二、初始化數據畫圖 本死鎖的堵塞主要集中在二級索引中,我們將二級索KEY idxa ( a )和主鍵的數據按照Innodb引擎存儲的方式大概排列一下則如圖:
三、T2 步驟1 T2 步驟1:delete from ty where a=5;
-----TRX NO:334719 LOCK STRUCT(1)(Add by gaopeng) RECORD LOCKS space id 653 page no 4 n bits 72 index idxa of table `test`.`ty` trx id 334719 lock_mode X(LOCK_X) locks gap and rec(LOCK_ORDINARY[next_key_lock]) Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 0: len 4; hex 80000005; asc ;; 1: len 4; hex 80000009; asc ;; -----TRX NO:334719 LOCK STRUCT(1)(Add by gaopeng) RECORD LOCKS space id 653 page no 3 n bits 72 index PRIMARY of table `test`.`ty` trx id 334719 lock_mode X(LOCK_X) locks rec but not gap(LOCK_REC_NOT_GAP)
四、T1 步驟2 T2 步驟1:delete from ty where a=5; 堵塞
-----TRX NO:334724 LOCK STRUCT(1)(Add by gaopeng) RECORD LOCKS space id 653 page no 4 n bits 72 index idxa of table `test`.`ty` trx id 334724 lock_mode X(LOCK_X) locks gap and rec(LOCK_ORDINARY[next_key_lock]) waiting(LOCK_WAIT) Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 0: len 4; hex 80000005; asc ;; 1: len 4; hex 80000009; asc ;; 根據這個記錄我們可以畫圖如下,黃色部分為事務T1準備上鎖但是被堵塞的部分,包含黃色部分和紅色部分的記錄說明它既被T2鎖定了并且T1拿不到這條記錄的鎖,它實際上就是一個next key lock的堵塞:
五、T2步驟3 這一步如果是: insert into ty(a,b) values(2,10); 則發生死鎖,實際上這一條記錄記錄在二級索引的值為(2,11),11是主鍵的值,則畫圖如下:
MySQL:Innodb 一個死鎖案例 image.png
這種情況下則T2也被堵塞,因為這個區域T1也處于堵塞下,則發生死鎖。死鎖記錄如下:
*** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 653 page no 4 n bits 72 index idxa of table `test`.`ty` trx id 334712 lock_mode X(LOCK_X) locks gap before rec(LOCK_GAP) insert intention(LOCK_INSERT_INTENTION) waiting(LOCK_WAIT) Record lock, heap no 3 PHYSICAL RECORD: n_fields 2; compact format; info bits 32 0: len 4; hex 80000005; asc ;; 1: len 4; hex 80000009; asc ;; 及插入印象鎖堵塞