DB2 锁问题分析与解释

DB2 锁问题分析与解释

DB2 应用中经常会遇到锁超时与死锁现象,那么这种现象产生的原因是什么呢。本文以试验的形式模拟锁等待、锁超时、死锁现象,并给出这些现象的根本原因。

试验环境:

DB2 v9.7.0.6

AIX 6.1.0.0

采用默认的隔离级别CS

STUDENT表的DDL与初始内容

————————————————

— DDL Statements for table “E97Q6C  “.”STUDENT”

————————————————

 

CREATE TABLE “E97Q6C  “.”STUDENT”  (

“AGE” INTEGER ,

“NAME” CHAR(8) )

IN “USERSPACE1” ;

$ db2 “select * from student”

AGE         NAME

———– ——–

3 xu

5 gao

2 liu

1 gu

试验1:验证insert操作与其他操作的锁等待问题

session 1中发出insert操作,在session 2中观察insert,update,delete操作是否会锁超时。

session 1

———

$ db2 +c “insert into student values(4, ‘miao’)”

DB20000I  The SQL command completed successfully.

session 2

———

$ db2 “insert into student values(6, ‘mu’)”

DB20000I  The SQL command completed successfully.

$ db2 “update student set name=’gu’ where age=1”

DB20000I  The SQL command completed successfully.

$ db2 “delete from student where age=2”

DB20000I  The SQL command completed successfully.

—————————————————————————-

结论1:当session 1对表作insert操作时,session 2对该表的insert及其他行的update,delete操作都不会有问题

 

—————————————————————————-

试验2:验证update操作与其他操作的锁等待问题

session 1中发出update操作,在session 2中观察insert,update,delete操作是否会锁超时。

————–

session 1

———

$ db2 commit

$ db2 “select * from student”

AGE         NAME

———– ——–

3 xu

5 gao

6 mu

4 miao

1 gu

5 record(s) selected.

$ db2 +c “update student set name = ‘qing’ where age=4”

DB20000I  The SQL command completed successfully.

session 2

———

阅读更多

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

  1. 如何判断CPU高?

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

  1. 收集数据

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

  1. 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的数据。

  1. 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等。这里不做阐述(因为我也不擅长),有兴趣的可以看参考资料。

  1. 一个示例

环境db2 10.5.0.5, suse linux 11

问题:%usr CPU高,大约95%,db2sysc进程使用的最多

数据收集:
在问题出现期间,收集了以下数据:

vmstat 1 10 > vmstat.1
ps -elf > pself.1
ps aux > psaux.1
iostat 1 10 > iostat.1

db2pd -eve > db2pd_eve.out
db2pd -edus interval=120 > 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

阅读更多