什麼是死鎖?
死鎖是指由於每個事務都持有對方需要的鎖而無法進行其他事務的情況。因為這兩個事務都在等待資源變得可用,所以兩個都不會釋放它持有的鎖。
死鎖的例子:
1.打開一個mysql控制檯client A
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> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE;
+------+
| i |
+------+
| 1 |
+------+
2.打開一個mysql控制檯client B
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> DELETE FROM t WHERE i = 1;
3. 在client A中執行:
mysql> DELETE FROM t WHERE i = 1;
Query OK, 1 row affected (0.00 sec)
4.此時client B中會出現:
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
注意:不一定是client B中會出現死鎖,因為,當mysql檢測到死鎖發生的時候回隨機回滾一個事務。
執行一個sql時如果暫時無法獲取到鎖並且沒有發生死鎖,該事務會進入一個鎖請求等待隊列,在隊列中等待50秒(默認值,可以通過set gloabl innodb_lock_wait_timeout=XXX設置)如果還無法獲得鎖,就會提示:ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction。
MySQL死鎖的檢測和回滾?
InnoDB自動檢測事務死鎖並回滾一個或多個事務以打破死鎖,InnoDB嘗試選擇一些小的事務以進行回滾,其中事務的大小由插入,更新或刪除的行數決定。
以上僅為個人見解,如果有錯誤歡迎指出,喜歡的話可以點贊收藏評論轉發,後續會繼續推出MySQL系列文章。
閱讀更多 沃爾特 的文章