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

ev7lccsx  于 2021-06-18  发布在  Mysql
关注(0)|答案(0)|浏览(285)

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)在主键上,但顺序不同。有人知道真正的原因吗?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题