Mysql中的死鎖

2021-10-08 14:19:28 字數 1373 閱讀 5377

死鎖

一旦構成死鎖,innodb會盡可能的幫助開發者解除死鎖。其做法是自動終止一些事務的執行從而釋放鎖定狀態。在上一小節我們示範的多個加鎖場景,它們雖然都構成鎖等待,但是都沒有構成死鎖。那麼本文就要首先說明一下,什麼樣的情況才構成死鎖。

什麼是死鎖

兩個或者多個事務相互等待對方已鎖定的資源,而彼此都不為協助對方達成操作目而主動釋放已鎖定的資源,這樣的情況就稱為死鎖。請區分正常的鎖等待和死鎖的區別,例如以下示意圖中的鎖等待並不構成死鎖:

上圖中的情況只能稱為鎖資源等待,這是因為當a事務完成處理後就會釋放所佔據的資源上的鎖,這樣b事務就可以繼續進行處理。並且在這個過程中沒有任何因素阻止a事務完成,也沒有任何因素阻止b事務在隨後的操作中獲取鎖。但是,以下示意圖中的兩個事務就在相互等待對方已鎖定的資源,這就稱為死鎖:

死鎖造成的根本原因和上層mysql服務和下層innodb引擎的協調方式有關:在上層mysql服務和下層innodb引擎配合進行update、delete和insert操作時, 對滿足條件的索引加x鎖的操作是逐步進行的

當innodb進行update、delete或者insert操作時,如果有多條記錄滿足操作要求,那麼innodb引擎會鎖定一條記錄(實際上是相應的索引)然後再對這條記錄進行處理,完成後再鎖定下一條記錄進行處理。這樣依次迴圈直到所有滿足條件的資料被處理完,最後再統一釋放事務中的所有鎖。如果這個過程中某個將要鎖定的記錄已經被其它事務搶先鎖定,則本事務就進入等待狀態,一直等待到鎖定的資源被釋放為止。

首先,表鎖本身並不會導致死鎖,它只是innodb中的一種機制。但是表鎖會一次鎖定資料表中的所有聚集索引項。這就增加了表鎖所在事務需要等待前序事務執行完畢才能繼續執行的機率。而且這種等待狀態還很可能在乙個事務**現多次——因為有多個事務在同時執行嘛。在這個過程中由於表鎖逐漸佔據了聚簇索引上絕大多數的索引項,所以這又增加了和其它正在執行的事務搶占鎖定資源的,最終增加了死鎖發生的機率。

由於需要進行表鎖定的事務,需要將資料表中的所有聚集索引全部鎖定後(如果在預設的事務級別下還要加gap鎖),才能完成事務的執行過程,所以這會導致後序事務全部進入等待狀態。而innodb引擎根本無法預知表鎖所在事務是否佔據了後續資源需要使用的索引項。這就與之前的提到的情況一樣,增加了死鎖發生的機率。

關於MySQL中的死鎖

死鎖分為兩種情況,一種是死鎖,一種是鎖等待,通常我們說的mysql 死鎖 指的是鎖等待 事務1鎖定記錄a 事務2鎖定記錄b 事務1嘗試更新記錄b 這裡是鎖等待,等待事務2提交,釋放b 事務2嘗試更新記錄a 這裡是死鎖,mysql會自動檢測,並報error 1213 40001 deadlock fo...

mysql 死鎖模擬 Mysql的死鎖

專案經常會出現mysql的死鎖問題,當年年少總是想通過select from information schema.innodb locks 檢視被鎖的事務,然後kill掉他,或者重啟mysql,唉,治標不治本啊,下次還會出現這些問題,其實造成死鎖大多數情況就是我們的sql寫的不大好。我們先來模擬一...

mysql中什麼是死鎖 mysql死鎖是什麼意思

mysql死鎖是指兩個或多個事務在同一資源上相互占用,並請求鎖定對方占用的資源,從而導致惡性迴圈。innodb儲存引擎能檢測到死鎖的迴圈依賴並立即返回乙個錯誤。只有部分或完全回滾其中乙個事務,才能打破死鎖。什麼是死鎖?它是如何產生的?死鎖是指兩個或多個事務在同一資源上相互占用,並請求鎖定對方占用的資...