在多个唯一键上使用重复键更新sql插入时出现死锁

时间:2018-12-06 13:00:59

标签: mysql deadlock

当行不在表中时,是否像重复插入键更新上的sql一样,会在每个唯一键索引/主键上无序地生成间隙锁?

我发现,当使用多个事务对具有多个唯一键的表上的重复键更新sql执行插入操作时,可能会导致死锁。

我的桌子就像:

| Table | Create Table                                                                                                                                                                                                                
| test | CREATE TABLE `test1` (
  `c1` int(11) NOT NULL,
  `c2` int(11) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  PRIMARY KEY (`c1`),
  UNIQUE KEY `uk` (`c2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci 

死锁出现后,我获得了引擎的innodb状态:

------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-12-06 20:01:57 0x70000ee06000
*** (1) TRANSACTION:
TRANSACTION 2219555, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 1
MySQL thread id 6686, OS thread handle 123145569476608, query id 6114936 localhost 127.0.0.1 root update
INSERT INTO test1 (`c1`, `c2`, `c3`) VALUES (15538, 1213457428, 30) ON DUPLICATE KEY UPDATE `c3` = VALUES(`c3`)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 65 page no 29 n bits 848 index cc of table `compare_db`.`test1` trx id 2219555 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 749 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex c88c97bb; asc     ;;
 1: len 4; hex 80002c42; asc   ,B;;

*** (2) TRANSACTION:
TRANSACTION 2219538, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1 4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 1
MySQL thread id 6631, OS thread handle 123145551896576, query id 6114889 localhost 127.0.0.1 root update
INSERT INTO test1 (`c1`, `c2`, `c3`) VALUES (535, 1215380840, 30) ON DUPLICATE KEY UPDATE `c3` = VALUES(`c3`)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 65 page no 29 n bits 840 index cc of table `compare_db`.`test1` trx id 2219538 lock_mode X locks gap before rec
Record lock, heap no 749 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex c88c97bb; asc     ;;
 1: len 4; hex 80002c42; asc   ,B;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 65 page no 29 n bits 848 index cc of table `compare_db`.`test1` trx id 2219538 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 749 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex c88c97bb; asc     ;;
 1: len 4; hex 80002c42; asc   ,B;;

*** WE ROLL BACK TRANSACTION (1)

直接插入就可以了。 我当时在想,这是因为当死锁出现时,两个会话都碰巧在英国锁定了间隙(a,b),在主键上锁定了(c,d),但是顺序不同。 有谁知道真正的原因吗?

0 个答案:

没有答案