記一次mysql死鎖問題

2021-09-02 01:45:20 字數 1307 閱讀 6303

場景:innodb下不同的事務進行更新和插入操作導致資料庫死鎖,**如下,在批量插入之前,進行了邏輯刪除操作,這段**在併發情況下出現死鎖

堆疊異常: deadlock found when trying to get lock; try restarting transaction;

更新操作sql

批量插入sql

**分析

activityid為外來鍵,有外來鍵索引,如果是行級鎖肯定不會出現死鎖,所以更新的時候肯定不止鎖了一條資料

**中更新操作的是非唯一索引列在innodb引擎下會觸發 next-key lock(間隙鎖)。

舉例: 表t中有非唯一索引列 test_id為 1, 10, 18, 22, 26的5條資料,此時模擬操作:

事務a 刪除一條不存在的資料,資料庫就會去找從左開始找最近的索引值

delete from t where test_id= 27;

事務b 刪除一條不存在的資料,資料庫就會去找從左開始找最近的索引值

delete from t where test_id= 28;

此時事務a和b就會分別產生乙個(26,正無窮)間隙鎖,然後繼續操作

事務ainsert into t values(27);

此時事務a阻塞,因為事務b在刪除操作時擁有了區間鎖

事務binsert into t values(28);

此時事務b就會死鎖,因為事務a在刪除操作時擁有了區間鎖

解決之道

1、刪除時先判斷資料是否存在

2、刪除和插入分兩個事務處理

3、將事務隔離級別設定為讀已提交

如果更新資料庫存在資料就不會出現死鎖,在delete from ... where ... 和 update ... where ... 在搜尋遇到的每條記錄上設定乙個獨佔的間隙鎖。 如果通過索引搜尋到唯一行就會產生乙個索引記錄鎖。insert 語句對插入的行設定排他(獨佔)鎖。這個鎖是乙個索引記錄鎖,而不是間隙鎖,並且不會阻止其他會話在插入的行之前區間中插入資料。死鎖,innodb檢測到會剔除乙個事務回滾,讓另外乙個事務完成。

記一次mysql死鎖問題排查

2019.10.05 15 20 16字數 543閱讀 7 隔壁同事大佬 專案用的mysql資料庫引擎是innodb,資料庫的行鎖 表鎖是通過innodb使用表的索引來實現的。那麼就先查詢一下innodb的狀態 show engine innodb status 只擷取有用資訊 latest det...

記一次專案的死鎖分析

公司專案使用多執行緒開發,因此使用gdb exec c corefile執行core檔案後,使用bt列印堆疊資訊 看不出問題,需要進入到執行緒內部分析。1.info threads 列印執行緒資訊 可以看到有多個 lll lock wait 看到這裡,我們推測可能是鎖出現問題了。那麼繼續往,進入到執...

記一次mysql鎖超時問題

排查過程 select from information schema.innodb lock waits select from information schema.innodb trx show engine innodb status show variables like autocomm...