问题描述:在一个运行于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扫描它所花费的时间大大减少,这个挂起的问题就不再发生了。
上面的这个案例也许在实际生产中意义不大,举这个案例更重要的是希望读者学会问题诊断和分析的思路流程。这对你以后实际生产中的面对各种各样的问题诊断非常重要
相关推荐
### DB2死锁问题分析及解决方案 #### 一、引言 在数据库管理与维护过程中,死锁问题是一个常见的挑战,特别是在使用IBM DB2这样的大型关系型数据库管理系统时。本文将详细探讨DB2中死锁问题的分析方法及有效的解决...
当检测到死锁时,它会尝试选择一个受害者事务进行回滚,以打破死锁循环,这通常由DB2的死锁超时设置触发。你可以通过调整DB2的配置参数,如DEADLOCK_TIMEOUT,来定制死锁检测的灵敏度。 为了预防DB2中的死锁,有...
- 监控`db2diag.log`文件,分析死锁和锁超时事件,及时解决问题。 5. **死锁检测与解决**: - DB2提供了死锁检测机制,通过`DLCHKTIME`参数调整检测频率。 - 当死锁发生时,DB2会选择一个事务进行回滚以打破死锁...
这条命令的作用是开启DB2的监控开关,使得系统能够记录下有关锁定的信息,包括但不限于锁定的类型、持续时间等,这对于后续分析死锁原因非常重要。 ##### 2. 查看死锁状态 一旦开启了监控开关,就可以通过以下命令...
使用`$db2getsnapshotfordbonbhdb`命令可以捕获数据库的实时状态快照,这包括了锁升级的关键指标,如当前持有的锁数量、锁等待次数、死锁检测次数等。这些信息对于分析锁升级的原因和频率非常有帮助。 ``` Database...
在实际应用中,理解这些概念并结合具体的案例分析,能够有效地防止和处理MySQL中的死锁问题,提高系统的稳定性和效率。对于"load file异常",需要根据具体错误信息来定位问题并进行解决,确保数据导入的顺利进行。
db2pdcfg和db2_capture_locktimeout则分别用于捕获锁超时事件,并且通过设置特定参数,让系统在发生锁超时或死锁时调用相应的脚本进行记录。 DB2 9.7锁机制深入分析: DB2 9.7版本对锁机制进行了优化和改进,引入了...
通过以上方法,我们可以有效地查询DB2数据库中的锁状态,从而帮助解决可能遇到的与锁相关的性能问题或死锁问题。这些信息对于理解数据库中并发控制的行为至关重要,并且对于数据库管理员来说是非常有价值的诊断工具...
在MFC(Microsoft Foundation Classes)框架中,子线程与主线程交互并操作用户界面(UI)时,可能会遇到一些特定的问题,特别是当涉及...Test1文件可能是示例代码或案例分析,具体细节需查看该文件以获取更深入的理解。
DB2提供了多种工具和命令,用于监控和管理锁,包括查看锁的持有者、等待队列、以及死锁信息。这有助于DBA诊断性能问题和优化数据库配置。 #### 八、总结 DB2的锁机制是其并发控制的核心,通过合理配置锁模式和管理...
博客的代码,查看当前导致数据库锁的具体sql语句,调查代码逻辑死锁导致数据库超时的例子,对应的博客文章位置http://blog.csdn.net/pfe_nova/article/details/9055981 注意将代码配置文件的连接字符串改成自己实际...
总的来说,DB2中的死锁处理需要结合监控、分析和操作三方面来进行。通过开启锁监控,解析日志找出问题,然后根据具体情况选择合适的解决策略,可以有效地管理和防止死锁问题,保证数据库系统的稳定运行。
- **死锁和超时**:确定死锁和超时发生的原因,并采取相应措施预防。 #### 三十、锁的几种情况 - **情景一:提交频率的测试**:通过调整事务的提交频率来观察锁行为的变化。 - **行级锁的CPU花费**:分析行级锁对...
#### 一、理解DB2中的死锁与锁机制 在DB2(Database 2)这种关系型数据库管理系统中,锁是一种用于确保数据一致性和完整性的关键机制。当两个或多个事务互相等待对方释放资源时,就会发生死锁现象。死锁会严重阻碍...
4. **分析与预防**:在解除死锁后,应分析发生死锁的原因,可能是由于事务隔离级别设置不当、资源请求顺序不一致或者长时间持有锁等。根据分析结果,调整应用程序的代码逻辑,优化事务处理,避免再次出现死锁。例如...
DB2死锁问题通常在涉及更新操作的SQL语句中出现,但在本案例中,一个普通的SELECT语句引起了死锁,这在实践中较为罕见。死锁的产生是由于多个事务在资源请求上形成循环等待,导致系统无法继续执行。解决DB2死锁的...
当多个事务请求对同一资源进行访问时,可能会出现等待的情况,即一个事务正在等待另一个事务释放锁,而后者也在等待前者释放锁,这种现象被称为“死锁”。为了保证数据的一致性和完整性,Oracle数据库提供了一系列...