近期在工做在遇到了幾個和之前本身理解的一些不同的死鎖問題,所以想作一個mysql的死鎖系列,梳理一下mysql引起死鎖的一些場景,因爲我的認知終歸有限,本文所列的死鎖場景不表明mysql所有的死鎖觸發緣由,但願給其餘同窗啓示,如能在工做中剛好起到幫助做用,那就更好了。mysql
若是有多個事務,這裏咱們暫定爲兩個,事務A須要請求鎖lock_1,可是因爲事務B佔據着相關資源,致使事務A不能得到lock_1;同時,事務B請求鎖lock_2,可是因爲事務A佔據着相關資源,致使事務B不能得到鎖lock_2。爲了避免讓兩個事務都這麼長期hang着,這個時候mysql將會根據本身的一套規則選出開銷最小的事務,將其回滾,這樣,另一個事務就可以獲取須要的鎖資源繼續執行了。sql
以前不少文章都將死鎖的概念闡述爲這樣,這裏簡單描述就是:若是事務A已經持有鎖lock_1,但願繼續獲取鎖lock_2;同時,事務B已經獲取鎖lock_2,想繼續獲取鎖lock_1,兩個事務都佔據着對方但願獲取的鎖,因而產生死鎖!spa
若是按照第二種概念理解死鎖的定義,核心思想就是死鎖產生是由於雙方事務想獲取的鎖都被對方事務佔據着。這種理解其實有些片面,其實,死鎖產生的緣由本質上是兩個事務已經持有的鎖資源之間的相互影響,即只要事務B持有的鎖影響了事務A對相關鎖的獲取,同時事務A持有的鎖影響了事務B對相關鎖的獲取,不管事務A想獲取的鎖此時是否被事務B佔據着,此時都造成死鎖!3d
若是沒有死鎖檢測機制,若是發生了上面的場景,mysql該怎麼解決,是的,可能你想到了,可使用鎖超時,涉及相關的參數是innodb_lock_wait_timeout,可是這種方式是被動的,效率很低,相比之下,死鎖檢測就是更主動了,只要上面的說到的多事務互相hang住的場景一旦被mysql檢測到,mysql就會主動回滾低開銷事務。blog
mysql採用wait-for graph 原理來檢測死鎖,簡單的說就是多事務之間在互相hang住的時候,若是等待資源的矢量,造成了閉合迴路,那麼此時就斷定爲死鎖,下圖就是這樣的例子:事務
事務1因爲事務2已經持有的部分鎖,致使不能獲取相關的鎖,矢量方向指向事務2。同理事務2,事務3,事務4,矢量方向最終在4個事物之間造成閉合環路,死鎖造成。資源
請你們理解上面的概念,接下來的文章中咱們將會用實際的例子來展示死鎖產生的各類場景,在掌握了底層原理後,相信你們能以不變應萬變it