這個是很是經典的一個場景,在網上搜索插入意向鎖形成的死鎖,絕大部分都會指向這個例子mysql
表結構sql
CREATE TABLE `t1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` varchar(5),
`b` varchar(5),
PRIMARY KEY (`id`),
UNIQUE KEY `uk_name` (`a`,`b`)
);
複製代碼
三個事務的 insert 語句都是insert ignore into t1(a, b)values("1", "1");
bash
復現步驟以下:ui
t1 | t2 | t3 | 備註 |
---|---|---|---|
begin | begin | begin | |
insert | 成功 | ||
insert | 把 t1 的隱式鎖提高爲 X 鎖,t2 進入進入 S 鎖等待 | ||
insert | t3 進入進入 S 鎖等待 | ||
rollback; | t1 回滾之後,釋放 X 鎖,t2 和 t3 同時拿到了 S 鎖 | ||
ok | deadlock | t2 和 t3 都想拿插入意向鎖 X 鎖,形成死鎖條件 |
死鎖日誌以下spa
------------------------
LATEST DETECTED DEADLOCK
------------------------
181101 23:22:59
*** (1) TRANSACTION:
TRANSACTION 5032, ACTIVE 11 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 5, OS thread handle 0x70000d736000, query id 125 localhost root update
insert ignore into t1(a, b)values("1", "1")
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 56 page no 4 n bits 584 index `uk_name` of table `d1`.`t1` trx id 5032 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 139 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 3; hex 313031; asc 101;;
1: len 3; hex 313031; asc 101;;
2: len 4; hex 800007b1; asc ;;
*** (2) TRANSACTION:
TRANSACTION 5033, ACTIVE 6 sec inserting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 6, OS thread handle 0x70000d779000, query id 126 localhost root update
insert ignore into t1(a, b)values("1", "1")
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 56 page no 4 n bits 584 index `uk_name` of table `d1`.`t1` trx id 5033 lock mode S locks gap before rec
Record lock, heap no 139 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 3; hex 313031; asc 101;;
1: len 3; hex 313031; asc 101;;
2: len 4; hex 800007b1; asc ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 56 page no 4 n bits 584 index `uk_name` of table `d1`.`t1` trx id 5033 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 139 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 3; hex 313031; asc 101;;
1: len 3; hex 313031; asc 101;;
2: len 4; hex 800007b1; asc ;;
*** WE ROLL BACK TRANSACTION (2)
複製代碼
這裏咱們第一次提到了插入意向鎖(insert intention lock)日誌
插入意向鎖(insert intention lock) 對已有數據行的修改與刪除,必須增強互斥鎖 X 鎖,那對於數據的插入,是否還須要加這麼強的鎖,來實施互斥呢?插入意向鎖,孕育而生。 插入意向鎖是間隙鎖(Gap Locks)的一種,它是專門針對 insert 操做的,也是爲數很少的在 RC 級別下產生 Gap 鎖狀況code