MySQL死鎖原理及如何定位和解決

2021-10-19 09:31:32 字數 1903 閱讀 5989

死鎖是指兩個或者多個事務在同一資源上相互占用,並請求鎖定對方占用的資源,從而導致惡性迴圈的現象。當多個事務試圖以不同的順序鎖定資源時,就可能會產生死鎖。多個事務同時鎖定同乙個資源時,也會產生死鎖。例如,設想下面兩個事務同時處理stockprice表:

事務1

start transaction;

update stockprice set close = 45.50 where stock_id = 4 and date = '2002-05-01';

update stockprice set close = 19.80 where stock_id = 3 and date = '2002-05-02';

commit;

事務2

start transaction;

update stockprice set high = 20.12 where stock_id = 3 and date = '2002-05-02';

update stockprice set high = 47.20 where stock_id = 4 and date = '2002-05-01';

commit;

如果湊巧,兩個事務都執行了第一條update語句,更新了一行資料,同時也鎖定了該行資料,接著每個事務都嘗試去執行第二條update語句,卻發現該行已經被對方鎖定,然後兩個事務都等待對方釋放鎖,同時又持有對方需要的鎖,則陷入死迴圈。除非有外部因素介入才可能解除死鎖。

為了解決這種問題,資料庫系統實現了各種死鎖檢測和死鎖超時機制。越複雜的系統,比如innodb儲存引擎,越能檢測到死鎖的迴圈依賴,並立即返回乙個錯誤。這種解決方式很有效,否則死鎖會導致出現非常慢的查詢。還有一種解決方式,就是當查詢的時間達到鎖等待超時的設定後放棄鎖請求,這種方式通常來說不太好。innodb目前處理死鎖的方法是,將持有最少行級排他鎖的事務進行回滾(這是相對比較簡單的死鎖回滾演算法)。

鎖的行為和順序是和儲存引擎相關的。以同樣的順序執行語句,有些儲存引擎會產生死鎖,有些則不會。死鎖的產生有雙重原因:有些是因為真正的資料衝突,這種情況通常很難避免,但有些則完全是由於儲存引擎的實現方式導致的。

死鎖發生以後,只有部分或者完全回滾其中乙個事務,才能打破死鎖。對於事務型的系統,這是無法避免的,所以應用程式在設計時必須考慮如何處理死鎖。大多數情況下只需要重新執行因死鎖回滾的事務即可。

類似的業務邏輯以固定的順序訪問表和行(基本上是可以解決大部分的問題,比如轉賬,所有的功能介面都是先減錢再加錢)

大事務拆小,大事務更傾向於死鎖,如果業務允許,將大事務拆小

在同乙個事務中,盡可能做到一次鎖定所需要的所有資源,減少死鎖概率

降低隔離級別,如果業務允許,將隔離級別調低也是較好的選擇(有點扯淡,但是也管用.)

5 為表新增合理的索引,可以看到如果不走索引將會為表的每一行記錄新增上鎖(或者說是表鎖)

不加索引的事務語句拿到的鎖都是表鎖,表鎖級別大,死鎖概率就高了.

死鎖場景:

事務a操作 select * from table where id =1 for update

事務b操作 select * from table where id =2 for update

事務a操作 select * from table where id =2 for update

事務b操作 select * from table where id =1 for update

此時就卡住了事務a等著事務b釋放鎖,事務b等著事務a釋放鎖.

解決辦法很簡單,就是找dba看一下死鎖日誌就可以了,然後根據對應的sql,找到對應的**去改一下就可以了.

show engine innodb status 命令是可以檢視死鎖的資訊的

如何閱讀mysql的死鎖日誌

《mysql如何閱讀死鎖日誌》

《記一次線上sql死鎖事故:如何避免死鎖?》

gdb如何定位死鎖的位置

include include include using namespace std 互斥鎖 mutex mtx 執行緒共享資源 int i 0 執行緒入口函式 void func intmain 找到對應程式的pid,此處為10854,然後執行gdb p 10854進入該程序的gdb除錯介面。執...

mysql處理死鎖 mysql如何處理死鎖問題

mysql有兩種死鎖處理方式 1 等待,直到超時 innodb lock wait timeout 50s 2 發起死鎖檢測,主動回滾一條事務,讓其他事務繼續執行 innodb deadlock detect on 由於效能原因,一般都是使用死鎖檢測來進行處理死鎖。死鎖檢測 死鎖檢測的原理是構建乙個...

mysql 死鎖 知乎 事務的本質和死鎖的原理

原文 僅以mysql和spring為例,本文不介紹事務和鎖的概念。本文使用偽 表示方法 僅僅表達方法的意義及事務註解。事務的形狀 在我心中,事務一直是這個樣子的 x軸是上鎖的資源,y軸是消耗的時間,事務方塊隨著時間的流逝向下移動,當碰觸x軸時資源加鎖,越過x軸時資源解鎖 上圖是對於方法a的事務形狀,...