LATEST DETECTED DEADLOCK
------------------------
2018-12-21 13:34:32 0x7fc92c3be700
*** (1) TRANSACTION:
TRANSACTION 1862, ACTIVE 6 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 172, OS thread handle 140502007543552, query id 184 localhost root statistics
select ac_no, usr_no, cap_typ, ccy, ac_typ, ac_org, cap_typ_sts, cre_dt, ord_seq, last_ac_bal, cur_ac_bal, last_uava_bal, uava_bal, od_lmt, max_bal_lmt, min_bal_lmt, bal_tag, upd_dt, upd_jrn, nod_id, req_id, tm_smp from t_acm_ecbl where ac_org = '100001' and ac_no = '1200020000000501107' and cap_typ = '1' and ccy = 'CNY' for update
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 745 n bits 128 index PRIMARY of table `t2`.`t_acm_ecbl` trx id 1862 lock_mode X locks rec but not gap waiting
Record lock, heap no 37 PHYSICAL RECORD: n_fields 24; compact format; info bits 0
0: len 19; hex 31323030303230303030303030353031313037; asc 1200020000000501107;;
1: len 1; hex 31; asc 1;;
2: len 3; hex 434e59; asc CNY;;
3: len 6; hex 313030303031; asc 100001;;
4: len 6; hex 00000000073b; asc ;;;
5: len 7; hex 36000001200110; asc 6 ;;
6: len 9; hex 800000000000000000; asc ;;
7: len 3; hex 313230; asc 120;;
8: len 1; hex 30; asc 0;;
9: len 8; hex 3230313830393131; asc 20180911;;
10: len 10; hex 80000000000000000014; asc ;;
11: len 9; hex 80000000000000cb00; asc ;;
12: len 9; hex 800000000000009905; asc ;;
13: len 9; hex 800000000000000000; asc ;;
14: len 9; hex 800000000000000000; asc ;;
15: len 9; hex 800000000000000000; asc ;;
16: len 9; hex 800000000000000000; asc ;;
17: len 9; hex 800000000000000000; asc ;;
18: len 30; hex 316437386665623265376630343434373735666235396638343937313935; asc 1d78feb2e7f0444775fb59f8497195; (total 32 bytes);
19: len 8; hex 3230313831323134; asc 20181214;;
20: len 18; hex 323031383132313430303030353938393937; asc 201812140000598997;;
21: SQL NULL;
22: len 18; hex 323031383039313130303030333531363138; asc 201809110000351618;;
23: len 13; hex 31353434373137383833373035; asc 1544717883705;;
*** (2) TRANSACTION:
TRANSACTION 1861, ACTIVE 10 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 167, OS thread handle 140502007277312, query id 185 localhost root updating
UPDATE t_acm_ecbl
SET ORD_SEQ = 20
,LAST_AC_BAL = 203.00
,CUR_AC_BAL=153.05
,BAL_TAG='1d78feb2e7f0444775fb59f8497195c5'
,UPD_DT='20181214'
,UPD_JRN='201812140000598997'
,TM_SMP='1544717883705'
WHERE AC_NO = '1200020000000501107'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 28 page no 745 n bits 128 index PRIMARY of table `t2`.`t_acm_ecbl` trx id 1861 lock_mode X locks rec but not gap
Record lock, heap no 37 PHYSICAL RECORD: n_fields 24; compact format; info bits 0
0: len 19; hex 31323030303230303030303030353031313037; asc 1200020000000501107;;
1: len 1; hex 31; asc 1;;
2: len 3; hex 434e59; asc CNY;;
3: len 6; hex 313030303031; asc 100001;;
4: len 6; hex 00000000073b; asc ;;;
5: len 7; hex 36000001200110; asc 6 ;;
6: len 9; hex 800000000000000000; asc ;;
7: len 3; hex 313230; asc 120;;
8: len 1; hex 30; asc 0;;
9: len 8; hex 3230313830393131; asc 20180911;;
10: len 10; hex 80000000000000000014; asc ;;
11: len 9; hex 80000000000000cb00; asc ;;
12: len 9; hex 800000000000009905; asc ;;
13: len 9; hex 800000000000000000; asc ;;
14: len 9; hex 800000000000000000; asc ;;
15: len 9; hex 800000000000000000; asc ;;
16: len 9; hex 800000000000000000; asc ;;
17: len 9; hex 800000000000000000; asc ;;
18: len 30; hex 316437386665623265376630343434373735666235396638343937313935; asc 1d78feb2e7f0444775fb59f8497195; (total 32 bytes);
19: len 8; hex 3230313831323134; asc 20181214;;
20: len 18; hex 323031383132313430303030353938393937; asc 201812140000598997;;
21: SQL NULL;
22: len 18; hex 323031383039313130303030333531363138; asc 201809110000351618;;
23: len 13; hex 31353434373137383833373035; asc 1544717883705;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 745 n bits 128 index PRIMARY of table `t2`.`t_acm_ecbl` trx id 1861 lock_mode X waiting
Record lock, heap no 37 PHYSICAL RECORD: n_fields 24; compact format; info bits 0
0: len 19; hex 31323030303230303030303030353031313037; asc 1200020000000501107;;
1: len 1; hex 31; asc 1;;
2: len 3; hex 434e59; asc CNY;;
3: len 6; hex 313030303031; asc 100001;;
4: len 6; hex 00000000073b; asc ;;;
5: len 7; hex 36000001200110; asc 6 ;;
6: len 9; hex 800000000000000000; asc ;;
7: len 3; hex 313230; asc 120;;
8: len 1; hex 30; asc 0;;
9: len 8; hex 3230313830393131; asc 20180911;;
10: len 10; hex 80000000000000000014; asc ;;
11: len 9; hex 80000000000000cb00; asc ;;
12: len 9; hex 800000000000009905; asc ;;
13: len 9; hex 800000000000000000; asc ;;
14: len 9; hex 800000000000000000; asc ;;
15: len 9; hex 800000000000000000; asc ;;
16: len 9; hex 800000000000000000; asc ;;
17: len 9; hex 800000000000000000; asc ;;
18: len 30; hex 316437386665623265376630343434373735666235396638343937313935; asc 1d78feb2e7f0444775fb59f8497195; (total 32 bytes);
19: len 8; hex 3230313831323134; asc 20181214;;
20: len 18; hex 323031383132313430303030353938393937; asc 201812140000598997;;
21: SQL NULL;
22: len 18; hex 323031383039313130303030333531363138; asc 201809110000351618;;
23: len 13; hex 31353434373137383833373035; asc 1544717883705;;
*** WE ROLL BACK TRANSACTION (1)
mysql> show create table t_acm_ecbl\G
*************************** 1. row ***************************
Table: t_acm_ecbl
Create Table: CREATE TABLE `t_acm_ecbl` (
`AC_NO` varchar(32) NOT NULLL,
`USR_NO` decimal(20,0) DEFAULT NULL,
`CAP_TYP` varchar(1) NOT NULL,
`CCY` varchar(3) NOT NULL,
`AC_TYP` varchar(3) NOT NULL ,
`AC_ORG` varchar(10) NOT NULL ,
`CAP_TYP_STS` varchar(1) NOT NULL DEFAULT ' ',
PRIMARY KEY (`AC_NO`,`CAP_TYP`,`CCY`,`AC_ORG`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
联合主键 PRIMARY KEY (AC_NO
,CAP_TYP
,CCY
,AC_ORG
)
事务1862等待space id 28 page no 745 heap no 37这行数据的行锁,锁类型(lock_mode X locks rec but not gap waiting)
事务1861持有space id 28 page no 745 heap no 37这行数据的行锁,锁类型(lock_mode X locks rec but not gap)
事务1861等待 space id 28 page no 745 heap no 37 这行数据的行锁+gap锁(lock_mode X waiting),触发死锁检测,回滚1862的select for update。
为什么会出现这种场景呢?需要对事务中(已经和RD确认事务中包含两条sql,一条select for update,一条update)的两条语句的加锁过程进行分析
如下
select * from t_acm_ecbl where ac_org = '100001' and ac_no = '1200020000000501107' and cap_typ = '1' and ccy = 'CNY' for update
事务1861执行如上sql的加锁过程为
2018-12-21T13:34:22.873954+08:00 167 [Note] InnoDB: trx_id: 1861 create a record lock and add it to lock hash table,
space_id: 28
page_no: 745
heap_no: 37
n_bits: 128
primary key: 1
is record lock: 1
is waiting: 0
is gap: 0
is record not gap: 1
is insert intention: 0
lock_mode: 3 (0:LOCK_IS, 1:LOCK_IX, 2:LOCK_S, 3:LOCK_X, 4:LOCK_AUTO_INC, 5:LOCK_NONE)
如果同时另外一个线程进行相同的select操作,加锁过程为
事务1862执行select for update
2018-12-21T13:34:26.379141+08:00 172 [Note] InnoDB: trx_id: 1862 create a record lock and add it to lock hash table,
space_id: 28 ibd no
page_no: 745 数据页no
heap_no: 37 在数据页中的heap no
n_bits: 128
primary key: 1 主键索引
is record lock: 1 行锁
is waiting: 1 处于加锁等待状态,因为事务1861持有此行数据的x锁,x兼容
is gap: 0
is record not gap: 1 只锁记录,不锁gap
is insert intention: 0
lock_mode: 3 (0:LOCK_IS, 1:LOCK_IX, 2:LOCK_S, 3:LOCK_X, 4:LOCK_AUTO_INC, 5:LOCK_NONE)
UPDATE t_acm_ecbl
SET ORD_SEQ = 20
WHERE AC_NO = '1200020000000501107'
由于此update语句的where条件中只包含了主键索引的第一个字段,所以呢,加锁范围被放大了。可以这样来想象这个范围。
对于联合主键的如下值
(3,3,3),(4,2,3),(5,3,2)
如果where 条件中只包含了col_1 = 4, 那么在主键索引中,可以插入(4,,)的间隙为(3,3,3)-(5,3,2)。可以看如下的加锁过程
事务1861 执行此update的加锁过程如下
第一:
2018-12-21T13:34:32.260018+08:00 167 [Note] InnoDB: trx_id: 1861 create a record lock and add it to lock hash table,
space_id: 28
page_no: 745
heap_no: 37
n_bits: 128
primary key: 1
is record lock: 1 //行锁
is waiting: 1 //等待状态,因为锁队列中存在1862在等待
is gap: 0 //非gap锁
is record not gap: 0 //非只锁记录,不锁间隙,则是next key(记录+间隙)
is insert intention: 0
lock_mode: 3 (0:LOCK_IS, 1:LOCK_IX, 2:LOCK_S, 3:LOCK_X, 4:LOCK_AUTO_INC, 5:LOCK_NONE)
此时已经引发了死锁检测机制,回滚掉了事务1862.
第二,1861需要再加锁,其实就是对于下一行记录的间隙锁,因为这个间隙可以插入符合where条件中的值。
2018-12-21T13:34:32.260171+08:00 167 [Note] InnoDB: trx_id: 1861 create a record lock and add it to lock hash table,
space_id: 28
page_no: 745
heap_no: 38
n_bits: 128
primary key: 1
is record lock: 1
is waiting: 0
is gap: 1
is record not gap: 0
is insert intention: 0
lock_mode: 3 (0:LOCK_IS, 1:LOCK_IX, 2:LOCK_S, 3:LOCK_X, 4:LOCK_AUTO_INC, 5:LOCK_NONE)
分析完毕。
非常简单,修改事务中的update语句,where条件中要包含所有的主键值。