在数据库从V9.7升级到10.5后发现核心系统执行下档程序时,在串行下档时没有问题,但是在并发执行下档程序时所有的后来的并发下档程序都会产生锁等待现象,并导致所有后来的下档请求失败,由此导致了系统的批量处理异常缓慢且性能低下。
该问题涉及到生产系统的稳定性,事关重大需要及时定位并解决。通过与核心平台组同事沟通交流该问题的现象,研发人员怀疑是数据库版本升级导致的该问题,因为在9.7版本时数据库在并发下档时性能表现良好没有出现过该问题,而我认为具体什么原因导致还需要通过复现问题后抓出详细信息进行分析后再做定论。简单沟通后既定了一个策略,去测试环境下复现该问题。
说干就干,在测试环境下通过db2top发现,研发同事在执行下档操请求时发生了锁等待且出现了锁超时的问题,顿时眼前一亮,笔者高兴的快要跳起来了,觉得已经找到答案了,这个一看就是由于锁等待导致懒惰系统的典型表现。所以下面要做的就是打开锁相关的监控开关并抓取对应的SQL那么该解决该问题就迎刃而解了。由于我们公司使用的静态程序,所以使用快照的方法对于这个问题来说行不通,需要通过使用event monitor的方法来分析该问题。
以下为具体步骤:
1、在DB210.5.5下重新编译db2evmonfmt工具
cd /home/db2inst1/sqllib/samples/java/jdbc
cp DB2EvmonLocking.xsl /home/db2inst1/fengzhanhai/troubleshooting/lock
cp db2evmonfmt.java /home/db2inst1/fengzhanhai/troubleshooting/lock
cd /home/db2inst1/sqllib/java/jdk64
2、配置环境变量
vi ~/.profile
PATH=$PATH:/home/db2inst1/sqllib/java/jdk64/bin
. ~/.profile
3、编译db2evmonfmt工具
javac db2evmonfmt.java
4、打开锁监控开关
db2 update db cfg for cbusdb using MON_LOCKTIMEOUT HISTORY MON_DEADLOCK HISTORY MON_LOCKWAIT HISTORY
5、创建事件监控器并打开监控器收集信息
db2 "CREATE EVENT MONITOR lockevmon FOR LOCKING WRITE TO UNFORMATTED EVENT TABLE (TABLE lock_mon in CBOD_P1_800)"
db2 set event monitor lockevmon state 1
6、通知研发执行对应下档程序模块复现问题并执行以下命令抓取对应的SQL
java db2evmonfmt -d cbusdb -ue lock_mon -ftext
具体SQL如下所示:
#DECLARE CSAACNEVT0308 CURSOR FOR SELECT * FROM SAACNEVT WHERE SUBSTR(FK_SAACN_KEY,:H00233)>=SUBSTR(:H00228,:H00233) AND SUBSTR(FK_SAACN_KEY,:H00233)<= SUBSTR(:H00229,:H00233) ORDER BY FK_SAACN_KEY FOR READ ONLY WITH UR
到这里抓到了对应的SQL,本来是一件可喜的事情,但是抓到后却傻了眼,因为该SQL只是一个简单的查询操作,即使并发请求也不至于产生锁等待或者锁超时的问题啊~
到这里问题又陷入了另一个困局,如果不是这个SQL导致的系统懒惰,那又是什么问题导致的呢?带着这个问题,我让研发同事再次复现了这个问题,通过db2top工具进行下钻后发现,在执行该SQL时发现一个奇怪的问题呢:该SQL在执行时会隐式的产生内部锁且对SYSIBM.SYSSECTION表加X锁。
最后通过查询IBM konwlege center信息确认导致该问题的原因是由于程序包的状态不正常导致的,在程序包不正常时,每次执行该程序包时,数据库会隐式对该程序包的执行计划存储的表执行更新操作。官方的解决方案就是将对相应的程序包执行一下重绑定即可。
最后通过执行db2 rebind USACNEVT,再次让研发同事并发执行对应的程序,性能得到显著提升并不再产生锁超时的问题。
阅读(3301) | 评论(0) | 转发(0) |