An InnoDB Deadlock Example

An InnoDB Deadlock Example

下面的例子說(shuō)明了當(dāng)鎖請(qǐng)求導(dǎo)致死鎖時(shí),錯(cuò)誤是如何發(fā)生的。該示例涉及兩個(gè)客戶機(jī),A和B。

首先,客戶機(jī)A創(chuàng)建一個(gè)包含一行的表,然后開(kāi)始一個(gè)事務(wù)。在事務(wù)中,A通過(guò)在共享模式下選擇該行來(lái)獲得該行的S鎖

mysql> CREATE TABLE t (i INT) ENGINE = InnoDB;
Query OK, 0 rows affected (1.07 sec)

mysql> INSERT INTO t (i) VALUES(1);
Query OK, 1 row affected (0.09 sec)

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
+------+
| i    |
+------+
|    1 |
+------+

接下來(lái),客戶機(jī)B開(kāi)始一個(gè)事務(wù),并試圖從表中刪除該行

mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

mysql> DELETE FROM t WHERE i = 1;

delete操作需要一個(gè)X鎖。這個(gè)鎖不能被授予,因?yàn)樗c客戶端A持有的S鎖不兼容,所以請(qǐng)求進(jìn)入到行和客戶端B塊的鎖請(qǐng)求隊(duì)列中。

最后,客戶機(jī)A還試圖從表中刪除該行

mysql> DELETE FROM t WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction

這里發(fā)生死鎖是因?yàn)榭蛻舳薃需要一個(gè)X鎖來(lái)刪除WHERE i = 1的這行。但是,這個(gè)鎖請(qǐng)求不能被授予,因?yàn)榭蛻舳薆已經(jīng)有一個(gè)X鎖的請(qǐng)求,且正在等待客戶端A釋放它的S鎖。A持有的S鎖也不能升級(jí)為X鎖,因?yàn)锽之前請(qǐng)求了X鎖。因此,InnoDB會(huì)為其中一個(gè)客戶端生成一個(gè)錯(cuò)誤,并釋放其鎖??蛻舳朔祷剡@個(gè)錯(cuò)誤

ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction

此時(shí),可以授予對(duì)另一個(gè)客戶機(jī)的鎖請(qǐng)求,并從表中刪除行(因?yàn)榭蛻舳薆拋出異常后,客戶端A操作成功)。

mysql> DELETE FROM t WHERE i = 1;
Query OK, 1 row affected (0.00 sec)

排它鎖(X鎖)和共享鎖(S鎖):

所謂X鎖,是事務(wù)T對(duì)數(shù)據(jù)A加上X鎖時(shí),只允許事務(wù)T讀取和修改數(shù)據(jù)A

所謂S鎖,是事務(wù)T對(duì)數(shù)據(jù)A加上S鎖時(shí),其他事務(wù)只能再對(duì)數(shù)據(jù)A加S鎖,而不能加X(jué)鎖,直到T釋放A上的S鎖

若事務(wù)T對(duì)數(shù)據(jù)對(duì)象A加了S鎖,則T就可以對(duì)A進(jìn)行讀取,但不能進(jìn)行更新(S鎖因此又稱為讀鎖),在T釋放A上的S鎖以前,其他事務(wù)可以再對(duì)A加S鎖,但不能加X(jué)鎖,從而可以讀取A,但不能更新A.

我們可以通過(guò) show engine innodb status 命令來(lái)獲取最近一次的死鎖日志

我們來(lái)查看一下錯(cuò)誤日志

------------------------
LATEST DETECTED DEADLOCK
------------------------
2021-04-17 09:22:26 0x700006baf000
*** (1) TRANSACTION:
TRANSACTION 121889, ACTIVE 11 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 9, OS thread handle 123145424609280, query id 50 localhost root updating
DELETE FROM t WHERE i = 1

*** (1) HOLDS THE LOCK(S):
RECORD LOCKS space id 896 page no 4 n bits 72 index GEN_CLUST_INDEX of table `test`.`t` trx id 121889 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 6; hex 000000000600; asc       ;;
 1: len 6; hex 00000001dc1f; asc       ;;
 2: len 7; hex 82000001130110; asc        ;;
 3: len 4; hex 80000001; asc     ;;


*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 896 page no 4 n bits 72 index GEN_CLUST_INDEX of table `test`.`t` trx id 121889 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 6; hex 000000000600; asc       ;;
 1: len 6; hex 00000001dc1f; asc       ;;
 2: len 7; hex 82000001130110; asc        ;;
 3: len 4; hex 80000001; asc     ;;


*** (2) TRANSACTION:
TRANSACTION 121890, ACTIVE 25 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 4 lock struct(s), heap size 1136, 3 row lock(s)
MySQL thread id 8, OS thread handle 123145424306176, query id 51 localhost root updating
DELETE FROM t WHERE i = 1

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 896 page no 4 n bits 72 index GEN_CLUST_INDEX of table `test`.`t` trx id 121890 lock mode S
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 6; hex 000000000600; asc       ;;
 1: len 6; hex 00000001dc1f; asc       ;;
 2: len 7; hex 82000001130110; asc        ;;
 3: len 4; hex 80000001; asc     ;;


*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 896 page no 4 n bits 72 index GEN_CLUST_INDEX of table `test`.`t` trx id 121890 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0
 0: len 6; hex 000000000600; asc       ;;
 1: len 6; hex 00000001dc1f; asc       ;;
 2: len 7; hex 82000001130110; asc        ;;
 3: len 4; hex 80000001; asc     ;;

*** WE ROLL BACK TRANSACTION (1)
------------
TRANSACTIONS
------------
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容