`
marb
  • 浏览: 419894 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

db2死锁、锁超时的案例分析

 
阅读更多

问题描述:在一个运行于DB2上的OLTP系统中,应用程序每两个小时挂起一次。挂起持续的时间每次长达2~3分钟甚至更多。在挂起期间,所有的INSERT、UPDATE和DELETE操作都无响应,但是一些查询操作可以执行。

运行环境:DB2 V9.1,操作系统 AIX 5.3。

最初怀疑问题是由锁定等待引起的,但是当把LOCKTIMEOUT设置为10秒之后,此挂起现象依然继续发生。挂起发生后,应用程序也不会因为锁超 时而被回滚。同时,每次挂起发生的频率为非常准确的两小时。使用GET SNAPSHOT和db2pd观察挂起发生期间锁的状况,也没有发现异常。但是可以注意到很多应用在挂起期间都处于"Commit Active"状态:

  1. Application status =  Commit  Active 

在调整了缓冲池、日志缓冲池和SOFTMAX等日志相关参数之后,问题依然没有改善。同时注意到在挂起发生时,系统的CPU、I/O都不繁忙,相反都比较空闲。

当经过2~3分钟之后,挂起状态会被自动解除,同时数据库上的操作都恢复继续执行。DB2的诊断日志文件db2diag.log中也没有记录任何错误信息。

下面我们讲解针对这个问题的诊断步骤:

为了判断问题发生时DB2的运行状况,在DB2数据库运行的系统上,使用如下命令捕捉DB2进程的堆栈信息和操作系统CPU、I/O信息:

  1. 1. db2pd -stacks -repeat 8  
  2. 2. vmstat 4 > vmstat. out  
  3. 3. iostat 4 > iostat. out  
  4. 4. db2pd -eve -repeat 12 > pdeve.` date  +%Y%m%d.%H%M%S`  
  5. --循环捕捉db2进程信息:  
  6. while :;  
  7. do  
  8. ps -elf|grep db2 > ps. out .` date  +%Y%m%d.%H%M%S`  
  9. sleep 10  
  10. done  
  11. 6. db2  update  monitor switches using lock  on  bufferpool  on  statement  on  
  12. while :;  
  13. do  
  14. db2  "get snapshot for all on sample"  > snap.` date  +%Y%m%d.%H%M%S`  
  15. sleep 10  
  16. done 

数据收集完成后,在快照中发现如输出结果9.47中的信息:

  1. Application handle = 1445  
  2. Application status =  Commit  Active  
  3. Status change  time  = 12/07/2008 11:10:12.433060  
  4. Application code page = 1386  
  5. Application country/region code = 1  
  6. DUOW correlation token = B6F80323.BF0C.030574102402  
  7. Application  name  = Ptran013  
  8. ... ...  
  9. Snapshot  timestamp  = 12/07/2008 11:11:36.980672  
  10. 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"状态的应用程序的文件,可以看到类似如下的输出信息:

  1. sqlpgWaitForLrecOnDisk__FP9SQLP_DBCBUl  
  2. sqlpWriteLR__FP20sqle_agent_privatecbUlN42P14SQLP_LREC_PARTT2P9SQLP_LSN8 

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

  1. semop  
  2. sqloNLCKLock  
  3. sqluhLock__FP12SQLUH_HANDLE  
  4. VerifyHistoryFilesAndOptToRecover__FPP12SQLUH_HANDLEPcCb  
  5. sqluhOpen__FPP12SQLUH_HANDLEPcUl  
  6. ... ... 

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

  1. lseek64  
  2. sqloseek  
  3. sqluhReadEntry__F12SQLO_FHANDLEP11SQLUH_ENTRYP14SQLUH_WORKAREAPcN34PUi  
  4. sqluh_get_next_history_file_entry  
  5. sqluhGetEntryDRDA__FP5sqldaT1P13sqle_agent_cbP5sqlca  
  6. sqlerKnownProcedure__FiPcPiP5sqldaT4P13sqlerFmpTableP13sqle_agent_cbP5sqlca  
  7. ... ... 

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

  1. Address AppHandl [nod-index] AgentPid Priority Type State ClientPid Userid  
  2. CientNm  
  3. Rowsread Rowswrtn LkTmOt DBName  
  4. 0x078000000027D4C0 1291 [000-01291] 295218 0 Coord Inst-Active 950376 db2icps  
  5. db2hmon 0 0 NotSet n/a 

终于,发现是DB2HMON进程发起的这个操作。从DB2 V8.2开始,DB2HMON进程成了一个独立的服务器端进程,它不再受到HEALTH_MON参数的控制。当DB2实例启动的时候,DB2HMON进程 和实例主进程一起被启动。即使AUTO_MAINT设置为OFF,DB2HMON进程仍然会每两个小时就被唤醒一次,执行自动维护的评估性操作。当它执行 某些评估的时候,会扫描HISTORY FILE。在扫描期间,会妨碍其他应用程序修改HISTORY FILE。这种唤醒操作是无法停止的,除非将如下DB2注册表变量关闭:

  1. 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天。

使用下面的命令,可以修改这个默认设置:

  1. db2  update  db cfg  for  <db_name> using REC_HIS_RETENTN <number_of_days> 

也可以使用命令截断HISTORY FILE:

  1. db2 prune history yyyymmddhhmmss 

当HISTORY FILE的大小被缩小后,DB2HMON扫描它所花费的时间大大减少,这个挂起的问题就不再发生了。

上面的这个案例也许在实际生产中意义不大,举这个案例更重要的是希望读者学会问题诊断和分析的思路流程。这对你以后实际生产中的面对各种各样的问题诊断非常重要

分享到:
评论

相关推荐

    db2死锁问题分析及解决方案

    ### DB2死锁问题分析及解决方案 #### 一、引言 在数据库管理与维护过程中,死锁问题是一个常见的挑战,特别是在使用IBM DB2这样的大型关系型数据库管理系统时。本文将详细探讨DB2中死锁问题的分析方法及有效的解决...

    DB2解决表死锁

    当检测到死锁时,它会尝试选择一个受害者事务进行回滚,以打破死锁循环,这通常由DB2的死锁超时设置触发。你可以通过调整DB2的配置参数,如DEADLOCK_TIMEOUT,来定制死锁检测的灵敏度。 为了预防DB2中的死锁,有...

    解决DB2死锁的一些资料整理

    - 监控`db2diag.log`文件,分析死锁和锁超时事件,及时解决问题。 5. **死锁检测与解决**: - DB2提供了死锁检测机制,通过`DLCHKTIME`参数调整检测频率。 - 当死锁发生时,DB2会选择一个事务进行回滚以打破死锁...

    db2死锁问题.doc

    这条命令的作用是开启DB2的监控开关,使得系统能够记录下有关锁定的信息,包括但不限于锁定的类型、持续时间等,这对于后续分析死锁原因非常重要。 ##### 2. 查看死锁状态 一旦开启了监控开关,就可以通过以下命令...

    DB2数据库锁升级分析及处理步骤

    使用`$db2getsnapshotfordbonbhdb`命令可以捕获数据库的实时状态快照,这包括了锁升级的关键指标,如当前持有的锁数量、锁等待次数、死锁检测次数等。这些信息对于分析锁升级的原因和频率非常有帮助。 ``` Database...

    mysql死锁的一些案例

    在实际应用中,理解这些概念并结合具体的案例分析,能够有效地防止和处理MySQL中的死锁问题,提高系统的稳定性和效率。对于"load file异常",需要根据具体错误信息来定位问题并进行解决,确保数据导入的顺利进行。

    DB2锁问题处理最佳实践

    db2pdcfg和db2_capture_locktimeout则分别用于捕获锁超时事件,并且通过设置特定参数,让系统在发生锁超时或死锁时调用相应的脚本进行记录。 DB2 9.7锁机制深入分析: DB2 9.7版本对锁机制进行了优化和改进,引入了...

    db2_查询锁方法

    通过以上方法,我们可以有效地查询DB2数据库中的锁状态,从而帮助解决可能遇到的与锁相关的性能问题或死锁问题。这些信息对于理解数据库中并发控制的行为至关重要,并且对于数据库管理员来说是非常有价值的诊断工具...

    在MFC 子线程中使用UI(控件)退出时死锁或者超时处理参考

    在MFC(Microsoft Foundation Classes)框架中,子线程与主线程交互并操作用户界面(UI)时,可能会遇到一些特定的问题,特别是当涉及...Test1文件可能是示例代码或案例分析,具体细节需查看该文件以获取更深入的理解。

    DB2锁相关情况介绍

    DB2提供了多种工具和命令,用于监控和管理锁,包括查看锁的持有者、等待队列、以及死锁信息。这有助于DBA诊断性能问题和优化数据库配置。 #### 八、总结 DB2的锁机制是其并发控制的核心,通过合理配置锁模式和管理...

    查看数据库的锁以及事务锁表的超时的调查

    博客的代码,查看当前导致数据库锁的具体sql语句,调查代码逻辑死锁导致数据库超时的例子,对应的博客文章位置http://blog.csdn.net/pfe_nova/article/details/9055981 注意将代码配置文件的连接字符串改成自己实际...

    db2解除死锁

    总的来说,DB2中的死锁处理需要结合监控、分析和操作三方面来进行。通过开启锁监控,解析日志找出问题,然后根据具体情况选择合适的解决策略,可以有效地管理和防止死锁问题,保证数据库系统的稳定运行。

    DB2数据库处理表死锁

    #### 一、理解DB2中的死锁与锁机制 在DB2(Database 2)这种关系型数据库管理系统中,锁是一种用于确保数据一致性和完整性的关键机制。当两个或多个事务互相等待对方释放资源时,就会发生死锁现象。死锁会严重阻碍...

    DB2解数据库死锁.doc

    4. **分析与预防**:在解除死锁后,应分析发生死锁的原因,可能是由于事务隔离级别设置不当、资源请求顺序不一致或者长时间持有锁等。根据分析结果,调整应用程序的代码逻辑,优化事务处理,避免再次出现死锁。例如...

    DB2死锁的解决过程全记录

    DB2死锁问题通常在涉及更新操作的SQL语句中出现,但在本案例中,一个普通的SELECT语句引起了死锁,这在实践中较为罕见。死锁的产生是由于多个事务在资源请求上形成循环等待,导致系统无法继续执行。解决DB2死锁的...

    oracle解锁,死锁

    当多个事务请求对同一资源进行访问时,可能会出现等待的情况,即一个事务正在等待另一个事务释放锁,而后者也在等待前者释放锁,这种现象被称为“死锁”。为了保证数据的一致性和完整性,Oracle数据库提供了一系列...

Global site tag (gtag.js) - Google Analytics