當啟用死鎖偵測 (預設值) 時,InnoDB
會自動偵測交易死鎖,並回滾一個或多個交易來打破死鎖。InnoDB
會嘗試挑選小型交易進行回滾,而交易的大小則由插入、更新或刪除的列數決定。
如果 innodb_table_locks = 1
(預設值) 和 autocommit = 0
,且其上方的 MySQL 層知道列層級的鎖定,則 InnoDB
會感知資料表鎖定。否則,InnoDB
無法偵測到涉及由 MySQL LOCK TABLES
陳述式設定的資料表鎖定,或由 InnoDB
以外的儲存引擎設定的鎖定的死鎖。透過設定 innodb_lock_wait_timeout
系統變數的值來解決這些情況。
如果 InnoDB
監控器輸出的 LATEST DETECTED DEADLOCK
區段包含一則訊息,指出 TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH, WE WILL ROLL BACK FOLLOWING TRANSACTION (在鎖定資料表等待圖中的搜尋過深或過長,我們將回滾下列交易),則表示等待清單中的交易數目已達到 200 的限制。超過 200 個交易的等待清單會被視為死鎖,而嘗試檢查等待清單的交易則會回滾。如果鎖定執行緒必須查看等待清單中交易擁有的超過 1,000,000 個鎖定,也可能會發生相同的錯誤。
如需組織資料庫操作以避免死鎖的技術,請參閱第 17.7.5 節「InnoDB 中的死鎖」。
在高併發系統中,當大量執行緒等待同一個鎖時,死鎖偵測可能會導致效能下降。有時,禁用死鎖偵測並依賴 innodb_lock_wait_timeout
設定在發生死鎖時進行交易回滾可能更有效率。可以使用 innodb_deadlock_detect
變數來禁用死鎖偵測。