DB2一次死锁问题的分析过程
Posted shengqin105
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DB2一次死锁问题的分析过程相关的知识,希望对你有一定的参考价值。
业务反馈应用在提交表单报以下SQL错误:
错误信息:操作失败:提交失败[4]SQLExecute: 40001
[IBM][CLI Driver][DB2/LINUXX8664] SQL0911N The current transaction has been rolled back because of a deadlock or timeout. Reason code
"2". SQLSTATE=40001

错误时间:2022-04-24 18:42:01
根据错误代码,这是一个典型的死锁问题,之前问题发生时已经建立dllock event monitor进行数据收集,收集的死锁信息以表的形式进行保存。
以下是分析的过程。
1.定位死锁
在CONNHEADER_DEADLOCK_MON表中取得时间相近且与应用报错时间一致的应用连接信息。
AGENT_ID | APPL_ID | APPL_NAME | CLIENT_NNAME | CONN_TIME | SEQUENCE_NO |
438 | 192.168.1.1.59272.220424104202 | ** | ** | 2022-04-24 18:42:01.518595 | 00001 |
7273 | 192.168.1.2.59777.220424104200 | ** | ** | 2022-04-24 18:41:59.817282 | 00004 |
使用表的方式建立DB2死锁监视器及表定义参考以下官网链接:
https://www.ibm.com/docs/en/db2/11.1?topic=monitoring-data-generated-by-deadlock-event-monitors
2.查询死锁信息
根据DEADLOCK_DEADLOCK_MON上的信息。
DEADLOCK_ID | DL_CONNS | EVMON_ACTIVATES | ROLLED_BACK_AGENT_ID | ROLLED_BACK_APPL_ID | ROLLED_BACK_PARTICIPANT_NO | ROLLED_BACK_SEQUENCE_NO | START_TIME |
402 | 2 | 1 | 438 | 192.168.1.1.59272.220424104202 | 2 | 00001 | 2022-04-24 18:42:04.264236 |
显示:
- (1)死锁的ID=402;
- (2)死锁发生的时间是18:42:04.264236
- (3)发生死锁时,随机回滚的是agent_id=438的dsp的应用;
3.查询死锁关联的AGENT
根据DLCONN_DEADLOCK_MON,查询DEADLOCK_ID=402涉及的应用,信息如下:
AGENT_ID | APPL_ID | APPL_ID_HOLDING_LK | DEADLOCK_ID | LOCK_MODE | LOCK_MODE_REQUESTED | LOCK_OBJECT_NAME | LOCK_OBJECT_TYPE | START_TIME | TABLE_NAME | TABLE_SCHEMA | STMT_TEXT |
438 | 192.168.1.1.59272.220424104202 | 192.168.1.2.59777.220424104200 | 402 | 3 | 12 | 1 | 5 | 2022-04-24 18:42:04.290207 | PT_PO_DT | KERNEL | (SQL1) |
7273 | 192.168.1.2.59777.220424104200 | 192.168.1.1.59272.220424104202 | 402 | 5 | 3 | 13228376098 | 2 | 2022-04-24 18:42:04.290494 | PT_PO | KERNEL | (SQL2) |
上表数据是解析的重点,其意义分别是:
(1)应用(agent_id=438,DSP应用),需要对PT_PO_DT的对象(lock_object_name=1)申请NW锁(lock_mode_requested=12),但此对象已经被DCS应用(appl_id_holding_lk=192.168.1.2.59777.220424104200,即agent_id=7273)持有了S锁(lock_mode=3),锁的类型为表锁(lock_object_type=5);
(2)应用(agent_id=7273,DCS应用),需要对PT_PO的对象(lock_object_name=13228376098)申请S锁(lock_mode_requested=3),但此对象已经被DSP应用(appl_id_holding_lk=192.168.1.1.59272.220424104202,即agent_id=438)持有了X锁(lock_mode=5),锁的类型为行锁(lock_object_type=2);
agent_id = 438发生死锁时事务当时的SQL1,经查明作业的主要内容是对PT_PO、PT_PO_DT两个进行插入数据的作业;
agent_id = 7273发生死锁时事务当前的SQL2,经查明此事务的主要内容是对PT_PO、PT_PO_DT进行查询然后更新PT_PO的某几行的某字段。
4.定位锁的对象
依据LOCK_OBJECT_NAME查询DLLOCK_DEADLOCK_MON表的对象,如下(但没什么卵用):
DEADLOCK_ID | LOCK_MODE | LOCK_OBJECT_NAME | LOCK_OBJECT_TYPE | TABLE_FILE_ID | TABLE_NAME |
402 | 5 | 13228376098 | 2(*row lock,SQL2) | 534 | PT_PO |
402 | 3 | 1 | 5(*end of table lock, SQL1) | 768 | PT_PO_DT |
5.死锁过程还原
由SQL反查业务的逻辑,结合上述的分析,死锁的对象关系梳理如下:
(1)SQL1需要向两个表插入数据,先插入PT_PO,后插入PT_PO_DT,所以持有X锁申请NW锁,但都是行锁;
(2)SQL2先查后更新,由于SQL使用索引不当,查询进会对整表申请S锁,锁的对象与SQL1冲突,从而导致死锁的产生;
(3)S锁与X锁不兼容,S锁与NW锁也不兼容,故造成相互锁死,DB2随机踢掉了SQL1的事务,并报错;
(3)所以解决此问题的方向是,优化SQL2的语句,确保查询、更新时合理使用索引并精确定位至具体的row,可以避免发生此问题。
-------------------------
上述监控表中的元素均以数字表示相关锁的类型,比较费解,附上相关的数据字典用于辅助理解。(调整表格很麻烦,我直接贴图好了)
附表:LOCK_MODE元素
来自 <https://www.ibm.com/docs/en/db2/11.1?topic=reference-l#r0001286>
附表:锁的兼容关系(Lock Type Compatibility)
来自 <https://www.ibm.com/docs/en/db2/9.7?topic=management-lock-type-compatibility>
附表:LOCK_OBJECT_TYPE
(取直sqlmon.h文件)
/******************************************************************************/
/* lock object type (lock_object_type) */
/******************************************************************************/
/* table lock type */
/* table row lock type */
/* Internal lock type */
/* Tablespace lock type */
/* end of table lock */
/* key value lock */
/* Internal lock on the sysboot table*/
/* Internal Plan lock */
/* Internal Variation lock */
/* Internal Sequence lock */
/* Bufferpool lock */
/* Internal Long/Lob lock */
/* Internal Catalog Cache lock */
/* Internal Online Backup lock */
/* Internal Object Table lock */
/* Internal Table Alter lock */
/* Internal DMS Sequence lock */
/* Inplace reorg lock */
/* Block lock type */
/* Table partition lock type */
/* Autoresize lock type */
/* Automatic storage lock type */
/* XML Path lock type */
/* Internal Extent Movement lock */
/* Global DDL lock */
附表:锁的类型
(支持的表锁)
(支持的行锁)
以上是关于DB2一次死锁问题的分析过程的主要内容,如果未能解决你的问题,请参考以下文章