设为首页 收藏本站
查看: 4861|回复: 0

[经验分享] db2死锁、锁超时的案例分析

[复制链接]

尚未签到

发表于 2016-11-15 00:08:46 | 显示全部楼层 |阅读模式
  问题描述:在一个运行于DB2上的OLTP系统中,应用程序每两个小时挂起一次。挂起持续的时间每次长达2~3分钟甚至更多。在挂起期间,所有的INSERT、UPDATE和DELETE操作都无响应,但是一些查询操作可以执行。
  运行环境:DB2 V9.1,操作系统 AIX 5.3。
  最初怀疑问题是由锁定等待引起的,但是当把LOCKTIMEOUT设置为10秒之后,此挂起现象依然继续发生。挂起发生后,应用程序也不会因为锁超 时而被回滚。同时,每次挂起发生的频率为非常准确的两小时。使用GET SNAPSHOT和db2pd观察挂起发生期间锁的状况,也没有发现异常。但是可以注意到很多应用在挂起期间都处于"Commit Active"状态:

  • Application status =  Commit  Active 
  在调整了缓冲池、日志缓冲池和SOFTMAX等日志相关参数之后,问题依然没有改善。同时注意到在挂起发生时,系统的CPU、I/O都不繁忙,相反都比较空闲。
  当经过2~3分钟之后,挂起状态会被自动解除,同时数据库上的操作都恢复继续执行。DB2的诊断日志文件db2diag.log中也没有记录任何错误信息。
  下面我们讲解针对这个问题的诊断步骤:
  为了判断问题发生时DB2的运行状况,在DB2数据库运行的系统上,使用如下命令捕捉DB2进程的堆栈信息和操作系统CPU、I/O信息:

  • 1. db2pd -stacks -repeat 8  
  • 2. vmstat 4 > vmstat. out  
  • 3. iostat 4 > iostat. out  
  • 4. db2pd -eve -repeat 12 > pdeve.` date  +%Y%m%d.%H%M%S`  
  • --循环捕捉db2进程信息:   
  • while :;  
  • do  
  • ps -elf|grep db2 > ps. out .` date  +%Y%m%d.%H%M%S`  
  • sleep 10  
  • done  
  • 6. db2  update  monitor switches using lock  on  bufferpool  on  statement  on  
  • while :;  
  • do  
  • db2  "get snapshot for all on sample"  > snap.` date  +%Y%m%d.%H%M%S`  
  • sleep 10  
  • done 
  数据收集完成后,在快照中发现如输出结果9.47中的信息:

  • Application handle = 1445  
  • Application status =  Commit  Active  
  • Status change  time  = 12/07/2008 11:10:12.433060  
  • Application code page = 1386  
  • Application country/region code = 1  
  • DUOW correlation token = B6F80323.BF0C.030574102402  
  • Application  name  = Ptran013  
  • ... ...  
  • Snapshot  timestamp  = 12/07/2008 11:11:36.980672  
  • Coordinator agent process  or  thread ID = 929880 
  可以看到应用1445发起COMMIT的时间("Status change time")是"12/07/2008 11:10:12.433060",而快照的捕捉时间("Snapshot timestamp")是"12/07/2008 11:11:36.980672"。在这超过80秒的时间中,它一直处于"Commit Active"状态。
  "Commit Active"表示当前应用已经通知DB2提交未完成的事务,但是DB2还没有完成全部的提交动作。一个提交动作持续这么长时间是比较少见的,这可能说明 DB2由于某些原因无法完成提交。继续观察快照发现,还有其他超过20个应用同样处于"Commit Active"状态。
  在执行"db2pd-stacks"命令收集的堆栈文件中,找到对应929880("db2agent"进程ID)或者其他处于"Commit Active"状态的应用程序的文件,可以看到类似如下的输出信息:

  • sqlpgWaitForLrecOnDisk__FP9SQLP_DBCBUl  
  • sqlpWriteLR__FP20sqle_agent_privatecbUlN42P14SQLP_LREC_PARTT2P9SQLP_LSN8 
  这表明它正在向日志文件写入记录。DB2LOGGW后台进程负责日志记录的写入,可以看到它的调用堆栈如下所示:

  • semop  
  • sqloNLCKLock  
  • sqluhLock__FP12SQLUH_HANDLE  
  • VerifyHistoryFilesAndOptToRecover__FPP12SQLUH_HANDLEPcCb  
  • sqluhOpen__FPP12SQLUH_HANDLEPcUl  
  • ... ... 
  它正在等待获取在HISTORY FILE上的一个文件锁。 继续分析其他的堆栈输出文件,发现当时正在操作HISTORY FILE的进程是另一个"db2agent"进程295218,具体信息如下所示:

  • lseek64  
  • sqloseek  
  • sqluhReadEntry__F12SQLO_FHANDLEP11SQLUH_ENTRYP14SQLUH_WORKAREAPcN34PUi  
  • sqluh_get_next_history_file_entry  
  • sqluhGetEntryDRDA__FP5sqldaT1P13sqle_agent_cbP5sqlca  
  • sqlerKnownProcedure__FiPcPiP5sqldaT4P13sqlerFmpTableP13sqle_agent_cbP5sqlca  
  • ... ... 
  它已经打开了HISTORY FILE,并且正在一条条地读取其中的记录。在"db2pd-eve"的输出中,找到对应这个"db2agent"进程的客户端进程,具体信息如下所示:

  • Address AppHandl [nod-index] AgentPid Priority Type State ClientPid Userid  
  • CientNm  
  • Rowsread Rowswrtn LkTmOt DBName  
  • 0x078000000027D4C0 1291 [000-01291] 295218 0 Coord Inst-Active 950376 db2icps  
  • db2hmon 0 0 NotSet n/a 
  终于,发现是DB2HMON进程发起的这个操作。从DB2 V8.2开始,DB2HMON进程成了一个独立的服务器端进程,它不再受到HEALTH_MON参数的控制。当DB2实例启动的时候,DB2HMON进程 和实例主进程一起被启动。即使AUTO_MAINT设置为OFF,DB2HMON进程仍然会每两个小时就被唤醒一次,执行自动维护的评估性操作。当它执行 某些评估的时候,会扫描HISTORY FILE。在扫描期间,会妨碍其他应用程序修改HISTORY FILE。这种唤醒操作是无法停止的,除非将如下DB2注册表变量关闭:

  • db2set DB2_FMP_COMM_HEAPSZ=0 
  回想前面问题发生时的情景:
  (1) 每两个小时,DB2HMON进程被唤醒,发起一个连接到数据库服务器上,然后开始扫描HISTORY FILE文件。
  (2) 这时如果数据库上的某个日志文件被写满,由于日志归档已经打开,所以DB2会归档这个已经满的日志文件。但是由于在这之前DB2需要读取HISTORY FILE中的信息,所以会申请获得文件锁。
  (3) 于是,发生了锁等待。这不是DB2内部的锁等待,而是操作系统的文件级别上的锁等待,所以从DB2观察不到锁等待的现象。 当HISTORY FILE的大小随着DB2的使用时间不断增长之后,DB2HMON进程扫描这个文件所花费的时间也会随之增长。DB CFG中有一个参数REC_HIS_RETENTN,用于控制HISTORY FILE中信息的保留时限。它的默认值是366天。
  使用下面的命令,可以修改这个默认设置:

  • db2  update  db cfg  for  <db_name> using REC_HIS_RETENTN <number_of_days> 
  也可以使用命令截断HISTORY FILE:

  • db2 prune history yyyymmddhhmmss 
  当HISTORY FILE的大小被缩小后,DB2HMON扫描它所花费的时间大大减少,这个挂起的问题就不再发生了。
  上面的这个案例也许在实际生产中意义不大,举这个案例更重要的是希望读者学会问题诊断和分析的思路流程。这对你以后实际生产中的面对各种各样的问题诊断非常重要

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-300233-1-1.html 上篇帖子: 单向Q复制实践:db2表复制到db2 下篇帖子: DB2常用SQL示例,DB2 with的使用,DB2十六进制数据的使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表