CREATE TABLE `test` ( `id` bigint(11) NOT NULL , `name` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL , `type` tinyint(4) NULL DEFAULT NULL , `uid` int(11) NULL DEFAULT NULL , PRIMARY KEY (`id`), UNIQUE INDEX `uniq_type_name` (`type`, `name`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci ROW_FORMAT=COMPACT ;
insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); insert into test(id, name, type, uid) values(2, "DT589", 3, 1001); insert into test(id, name, type, uid) values(3, "DT588", 3, 1001);
------------------------ LATEST DETECTED DEADLOCK ------------------------ 2018-06-21 10:51:03 2b16deb03700 *** (1) TRANSACTION: TRANSACTION 1905650677, ACTIVE 0.001 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s), undo log entries 1 LOCK BLOCKING MySQL thread id: 16983306 block 34208692 MySQL thread id 34208692, OS thread handle 0x2b2203b0b700, query id 9093982364 172.24.18.106 app_redcliffc update INSERT INTO `test` (id, name, type, uid) VALUES (4, 'DT590', 3, 1001) *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 138 page no 16492 n bits 408 index `uniq_type_name` of table `db`.`test` trx id 1905650677 lock mode S waiting Record lock, heap no 341 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000048; asc H;; 1: len 10; hex 44543631393230363835; asc DT61920685;; 2: len 8; hex 0461116807c09a00; asc a h ;; *** (2) TRANSACTION: TRANSACTION 1905650675, ACTIVE 0.004 sec inserting mysql tables in use 1, locked 1 3 lock struct(s), heap size 1184, 2 row lock(s), undo log entries 2 MySQL thread id 16983306, OS thread handle 0x2b16deb03700, query id 9093982366 172.24.18.105 app_redcliffc update INSERT INTO `test` (id, name, type, uid) VALUES (2, 'DT589', 3, 1001) *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 138 page no 16492 n bits 408 index `uniq_type_name` of table `db`.`test` trx id 1905650675 lock_mode X locks rec but not gap Record lock, heap no 341 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000048; asc H;; 1: len 10; hex 44543631393230363835; asc DT61920685;; 2: len 8; hex 0461116807c09a00; asc a h ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 138 page no 16492 n bits 408 index `uniq_type_name` of table `db`.`test` trx id 1905650675 lock_mode X locks gap before rec insert intention waiting Record lock, heap no 341 PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000048; asc H;; 1: len 10; hex 44543631393230363835; asc DT61920685;; 2: len 8; hex 0461116807c09a00; asc a h ;; *** WE ROLL BACK TRANSACTION (1)
session1 | session2 | |
insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); | 事務一先到,先插入第一條記錄DT590,成功 | |
insert into test(id, name, type, uid) values(2, "DT589", 3, 1001); |
事務一繼續插入次日DT589記錄,這個時候事務二請求到了,開始
插入第一條記錄DT590,而後就報出死鎖,事務二回滾,事務一成功執行
|
insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); |
session1 | 持鎖 | session2 | 持鎖 |
insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); | 插入一條數據庫中沒有的記錄,對DT590這條記錄加了一個x鎖 | ||
insert into test(id, name, type, uid) values(2, "DT589", 3, 1001); |
這時事務一插入DT589時候,發現這條記錄已經有了一個gap lock(DT589這條記錄恰好被事務二插DT590時候申請的gap lock包含了),會先申請一個insert intention waiting插入意向鎖,這個鎖和事務二持有gap lock互斥,發生死鎖。
事務一在等事務二釋放這條記錄gap lock, 事務二在等事務一釋放DT590 X鎖
|
insert into test(id, name, type, uid) values(1, "DT590", 3, 1001); | 事務二插入有惟一索引DT590這條記錄,發現這條記錄上已經有了x鎖,因此會申請一個該條記錄的s鎖和gap lock |