Db2性能:系统CPU高问题分析的一些思路

db2性能:系统CPU高问题分析的一些思路

1. 如何判断CPU高?

有很多操作系统的命令可以看出来,比如ps -elf,iostat, vmstat, top/topas,

2. 收集数据

CPU高分为usr高和sys高,前者表示系统在执行应用代码,一般需要应用(比如Db2)来查原因。后者表示系统在执行kernal code,一般需要OS工程师协助分析。

A. sys CPU高

如果是%sys CPU高,这意味着系统在执行kernel code,这种情况下需要操作系统工程师一块支持,来从操作系统层面收集数据,例如:

AIX:
1) OS trace -- perfpmr.sh
Solaris:
1) dtrace script
Linux:
1) systemTap 工具
2) 如果能确定是Db2进程导致的,则收集db2sysc进程的strace -c 数据。
Db2:

Db2层面也可以收集一些数据,Db2导致的sys CPU高时,往往伴随着很多的latch,所以建议收集db2pd -latch和db2pd -stack的数据。

B. usr CPU高

如果是%usr CPU高,一般意味着系统正在执行应用的代码,很大可能是Db2执行的SQL语句导致的。需要找到占用CPU较多的SQL语句,看看在执行什么操作:

B1. 可以通过mon_get_pkg_cache_stmt找到占用CPU较多的动态SQL语句
db2 "select TOTAL_CPU_TIME/NUM_EXEC_WITH_METRICS as AVG_CPU_TIME, NUM_EXEC_WITH_METRICS, substr(STMT_TEXT,1,100) as STMT_TEXT from table( mon_get_pkg_cache_stmt (null, null,null,null)) as T where T.NUM_EXEC_WITH_METRICS <> 0 order by AVG_CPU_TIME DESC"
如果是routine占用了较多的CPU,比如存储过程,可以参考下面的链接:
调查routine的高 CPU 占用率
https://www.ibm.com/support/knowledgecenter/zh/SSEPGG_10.5.0/com.ibm.db2.luw.admin.mon.doc/doc/t0060667.html
B2. 可以通过db2pd -edus interval=120 来收集120秒之内每个edu占用的CPU时间,结合其他的信息,比如db2pd -eve、application snapshot的输出,来看一下edu对应的应用,以及应用执行的SQL语句是什么,针对这些SQL语句来优化。
SQL语句使用CPU较多的原因,简单说几个
--频繁地扫描环境池中的表、join操作、排序操作都会使用较多的CPU。
--获取锁和释放锁的过程,也要用较多的CPU。
对于如何解决,一般就是调优SQL了,比如通过建立适当的索引来避免表扫描、当需要锁较多时而对并发性要求不高时,直接在整个表上加锁、不需要那么多数据的时候使用fetch first xxx rows only等。这里不做阐述(因为我也不擅长),有兴趣的可以看参考资料。

3. 一个示例

环境: db2 10.5.0.5, suse linux 11
问题:%usr CPU高,大约95%,db2sysc进程使用的最多
数据收集:
在问题出现期间,收集了以下数据:

vmstat   > vmstat.
ps -elf > pself.
ps aux > psaux.
iostat > iostat.
db2pd -eve > db2pd_eve.out
db2pd -edus interval= > db2pd_edu_120.out
db2pd -stack all
db2 GET SNAPSHOT FOR APPLICATIONS ON <db_name> GLOBAL > applications.log
db2 GET SNAPSHOT FOR DATABASE ON <db_name> GLOBAL > DB.log
db2 get snapshot for all on <db_name> > dbsnap

数据分析:

3.1

iostat 输出显示 user CPU 很高.

avg-cpu: %user %nice %system %iowait %steal %idle

89.42 0.01 4.55 1.89 0.00 4.12

avg-cpu: %user %nice %system %iowait %steal %idle

94.41 0.00 5.59 0.00 0.00 0.00

avg-cpu: %user %nice %system %iowait %steal %idle

95.42 0.00 4.58 0.00 0.00 0.00

avg-cpu: %user %nice %system %iowait %steal %idle

94.67 0.00 5.33 0.00 0.00 0.00
3.2

ps aux的输出显示db2sysc进程使用了最多的CPU

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root  0.0 0.0   ? Ss Oct15 : init []

root  0.0 0.0   ? S Oct15 : [kthreadd]

...

root  0.0 0.2   ? Sl Oct15 : db2wdog  [db2inst1]

db2inst1   69.2   ? Sl Oct15 : db2sysc 

root  0.0 0.1   ? S Oct15 : db2ckpwd 

root  0.0 0.1   ? S Oct15 : db2ckpwd 

root  0.0 0.1   ? S Oct15 : db2ckpwd 

db2inst1  0.0 0.1   ? S Oct15 : db2vend (PD Vendor Process - ) 

db2inst1  0.0 0.1   ? Sl Oct15 : db2acd  ,,,,,,,,,,,995bc4,,1e014,,,,41fc0,0x210000000,0x210000000,,c8010,,

...

root  50.0 0.0   pts/ R+ : : ps aux

root  0.0 0.0   ? S : : [kworker/:]

patrol  0.0 0.0   ? Ss Oct15 : /bin/bash

patrol  0.0 0.0   ? Ss Oct15 : /bin/bash

root  0.0 0.0   ? S Oct15 : [kworker/:]
3.3

db2pd_edu_120.out 输出按照对EDU按照占用的CPU时间排序

Database Member  -- Active -- Up  days :: -- Date ---14.48.37.897471

List of all EDUs for database member 

db2sysc PID: 

db2wdog PID: 

db2acd PID: 

EDU ID TID Kernel TID EDU Name USR (s) SYS (s) USR DELTA SYS DELTA

========================================================================================================================================

   db2agent (SAMPLE)  24280.590000 478.060000 42.250000 1.080000

   db2agent (SAMPLE)  23898.440000 454.140000 40.980000 0.900000

   db2agent (SAMPLE)  23530.870000 446.600000 40.830000 0.850000

   db2agent (SAMPLE)  22660.420000 430.300000 40.600000 1.000000

   db2agent (SAMPLE)  23262.550000 443.450000 40.640000 0.900000

   db2agent (SAMPLE)  22989.210000 438.320000 40.660000 0.880000

   db2agent (SAMPLE)  22994.820000 436.550000 40.540000 0.900000

   db2agent (SAMPLE)  23656.830000 450.830000 40.540000 0.840000

   db2agent (SAMPLE)  23687.730000 450.920000 40.430000 0.920000

   db2agent (SAMPLE)  23498.360000 445.650000 40.440000 0.900000

   db2agent (SAMPLE)  22711.160000 427.530000 40.450000 0.850000

   db2agent (SAMPLE)  23338.770000 443.420000 40.270000 1.020000

   db2agent (SAMPLE)  22876.610000 435.050000 40.340000 0.920000

   db2agent (SAMPLE)  23423.810000 446.610000 40.340000 0.900000

   db2agent (SAMPLE)  22886.840000 433.260000 40.330000 0.910000

   db2agent (SAMPLE)  23631.250000 450.080000 40.220000 1.010000

   db2agent (SAMPLE)  23291.960000 443.260000 40.250000 0.980000

   db2agent (SAMPLE)  23276.780000 445.550000 40.270000 0.920000

   db2agent (SAMPLE)  22218.640000 419.450000 39.990000 0.960000

   db2agent (SAMPLE)  23387.590000 442.670000 39.970000 0.930000

   db2agent (SAMPLE)  22597.700000 427.340000 39.910000 0.970000

   db2agent (SAMPLE)  22962.390000 437.080000 39.990000 0.870000

   db2agent (SAMPLE)  23466.230000 448.500000 39.830000 1.020000

   db2agent (SAMPLE)  23581.980000 450.790000 39.910000 0.920000

   db2agent (SAMPLE)  22448.450000 423.550000 39.840000 0.930000

   db2agent (SAMPLE)  22930.950000 437.310000 39.740000 0.870000

   db2agent (SAMPLE)  22260.260000 423.640000 39.640000 0.910000

...
3.4

这里以EDU ID 110为例子,可以通过db2pd_eve.out找到其执行的SQL语句(这里可能不准确,因为抓取的是当前正在执行的SQL, 推荐结合mon_get_pkg_cache_stmt的输出)

Dynamic SQL Statements:

Address AnchID StmtUID NumEnv NumVar NumRef

NumExe Text

...

0x00007FAC67B6C640      

select * from TEST1 where KPICODE like '2222|!|!|%' order

by DCTIME desc fetch first  rows only with ur

...
3.5

Application SNAPSHOT显示sort、rows read都非常高

Application Snapshot

Application handle = 

Application status = UOW Executing

..

Rows inserted = 

Rows updated = 

Rows selected = 

Rows read = 

Rows written = 

..

Total sorts = 

..

Total User CPU Time used by agent (s) = 24801.492324

Total System CPU Time used by agent (s) = 0.000000

Agent process/thread ID = 
3.6

剩下的工作是:可以按照相同的方法找到其他占用CPU的SQL,并进行调优。当然,实际上可能并没有这么简单,需要多分析应用的快照,可以看到SQL语句是什么时候开始执行的?执行了多长时间?执行SQL语句之前是什么状态?同一时刻有多少SQL语句在执行?平时有那么多吗?等等,这些都可以从应用的快照中获取。所以应用的快照也是必收数据,而且要多收几次。

上一篇:java 的SPI机制


下一篇:Java学习笔记:语言基础