mysql-deadlocks icon indicating copy to clipboard operation
mysql-deadlocks copied to clipboard

关于案例15的疑问

Open luokay opened this issue 5 years ago • 5 comments

(1) TRANSACTION: TRANSACTION 7826110, ACTIVE 2 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 10 lock struct(s), heap size 1136, 15 row lock(s), undo log entries 10 MySQL thread id 17765371, OS thread handle 139825729169152, query id 199063024 172.16.10.166 gdcuser update /* insert TestDO */ insert into tbl_test (create_time, global_name, update_time, corp_id, count, editable, expire_date, order_id, resource_id, sp_id, status, type, type_id, id) values (1575826470134, 'global', 1575826470134, '9434', 10000, 1, 0, '39f838f61783474492311f009aaba483', 'c342774899bf4ddfbd5ab68f1aab322f', '2c908a266ee67a45016ee693b1744424', 0, 'B', '', '2c908a266ee67a45016ee693b50b44d0') *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 23657 page no 4 n bits 248 index uk_tbl_test_index of table table.tbl_test trx id 7826110 lock mode S waiting Record lock, heap no 81 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 30; hex 633564393537313638616430343666626163623662653538613865646435; asc c5d957168ad046fbacb6be58a8edd5; (total 32 bytes); 1: len 3; hex 564d52; asc C;; 2: len 5; hex 3233323838; asc 23288;; 3: len 30; hex 326339303861323636656536376134353031366565363933616234363432; asc 2c908a266ee67a45016ee693ab4642; (total 32 bytes);

*** (2) TRANSACTION: TRANSACTION 7825164, ACTIVE 5 sec inserting mysql tables in use 1, locked 1 13 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1024 MySQL thread id 17765414, OS thread handle 139827979204352, query id 199069471 172.16.10.166 gdcuser update /* insert TestDO */ insert into tbl_test (create_time, global_name, update_time, corp_id, count, editable, expire_date, order_id, resource_id, sp_id, status, type, type_id, id) values (1575826467635, 'global', 1575826467635, '23288', 500, 1, 20191020, '31ddb90006f141dab012e02b09763eff', '29afcf31f27a4735a8f38dcdb66cb3fa', '2c908a266ee67a45016ee6931a643059', 0, 'A', '', '2c908a266ee67a45016ee693bc81464a') *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 23657 page no 4 n bits 248 index uk_tbl_test_index of table table.tbl_test trx id 7825164 lock_mode X locks rec but not gap Record lock, heap no 81 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 30; hex 633564393537313638616430343666626163623662653538613865646435; asc c5d957168ad046fbacb6be58a8edd5; (total 32 bytes); 1: len 3; hex 564d52; asc C;; 2: len 5; hex 3233323838; asc 23288;; 3: len 30; hex 326339303861323636656536376134353031366565363933616234363432; asc 2c908a266ee67a45016ee693ab4642; (total 32 bytes);

*** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 23657 page no 4 n bits 248 index uk_tbl_test_index of table table.tbl_test trx id 7825164 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 157 PHYSICAL RECORD: n_fields 4; compact format; info bits 32 0: len 30; hex 326136343165353562626465346265626230623230313833323466633439; asc 2a641e55bbde4bebb0b2018324fc49; (total 32 bytes); 1: len 9; hex 434f4e465f43414c4c; asc D;; 2: len 4; hex 39343334; asc 9434;; 3: len 30; hex 326339303861323636656536376134353031366565363933623331383434; asc 2c908a266ee67a45016ee693b31844; (total 32 bytes);

*** WE ROLL BACK TRANSACTION (1)

唯一索引为 resource_id、type、corp_id的组合索引,事务1中和事务2中插入记录并无冲突,请教下为何还会死锁?

luokay avatar Dec 09 '19 02:12 luokay

死锁日志里只能看到死锁发生时两个事务当前正在执行的SQL,这两个SQL不一定冲突,看事务一 undo log entries 10 说明事务一在执行这个SQL之前还有其他的SQL,和事务二冲突了,所以要检查下业务代码逻辑,或者查查binlog看看日志。

aneasystone avatar Dec 10 '19 10:12 aneasystone

非常感谢您的解答,事物1正在执行的语句正在等待s锁,不能说明这个和事物2中持有的x锁记录冲突吗,从业务分析来看,两个事物的corp_id不会相同,所以组合索引不应该会冲突,这个我可以再排查下binlog,另外除了索引冲突,还有没有什么可能引起该死锁?事物1 事物2等待和持有的 RECORD LOCKS space id 23657 page no 4 n bits 248 这条信息有没有什么特殊?

luokay avatar Dec 10 '19 14:12 luokay

死锁日志里能看到事务二加锁的记录是:(id, resource_id, type, corp_id) = ('2c908a266ee67a45016ee693ab4642', 'c5d957168ad046fbacb6be58a8edd5', 'C', '23288'),加锁类型是记录锁(lock_mode X locks rec but not gap),而事务一也要对这条记录加锁,加锁类型是 NK 锁(lock mode S),所以阻塞,要分析下事务一为什么会对这条记录加 S 锁。

另外,事务二还要对另一个记录加锁,(id, resource_id, type, corp_id) = ('2c908a266ee67a45016ee693b31844', '2a641e55bbde4bebb0b2018324fc49', 'D', '9434'),这条记录的 info bit 为 32,说明已经被删除了,可以排查下事务一有没有删除这个记录的SQL语句。

你这个死锁还是要结合具体的业务代码来分析,只从死锁日志很难知道这些锁是哪个SQL加的。

aneasystone avatar Dec 11 '19 00:12 aneasystone

要分析下事务一为什么会对这条记录加 S 锁

就这两个事物而言,事物1和事物2操作的tbl_test表的corpId永远是不相同的,一个是9434,一个是23288,均仅有插入操作,也就是说他们操作的行永远不会冲突,这才是我最困惑的地方。我再通过binlog去排查下吧,非常感谢~

luokay avatar Dec 11 '19 03:12 luokay

可以看下哪里有删除 9434 的地方,如果你非常肯定事务一没有删这条记录,那也有可能是三个事务连锁导致的死锁。binlog里找下这个时间点前后的日志,应该可以看到DELETE语句。

另外,你说两个事务都仅有插入操作,那么事务一在等待的S锁就只可能有一种情况:出现了唯一键冲突。binlog里找下是不是有其他事务也执行了插入操作?

aneasystone avatar Dec 11 '19 05:12 aneasystone