sql类似于insert。。。当行不在表中时,重复键更新将在每个唯一键索引/主键(无序)上生成间隙锁?
我发现在使用多个事务对具有多个唯一键的表执行insert on duplicate key update sql时,可能会导致死锁。
我的table就像:
| 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)
直接插入就可以了。所以我在想,这是因为两个会话都发生在锁定的gap(a,b)上,在出现死锁时(c,d)在主键上,但顺序不同。有人知道真正的原因吗?
暂无答案!
目前还没有任何答案,快来回答吧!