mysql innodb死鎖問題詳解

2021-08-14 13:56:38 字數 2887 閱讀 7987

1 最近旅遊電商平台對外提供的介面經常有終端使用者反映請求超時異常 。

2 進過排查伺服器日誌有報錯,錯誤資訊如下:

error 1205 (hy000): lockwait timeout exceeded; try restarting transaction

3 了解平台使用的是mysql 資料庫版本5.6.34 儲存引擎是innodb。

4 推斷是mysql innodb 死鎖問題。

5 檢視資料庫隔離級別如下圖:

資料庫隔離級別 read uncommitted(讀取未提交內容) read committed(讀取提交內容)repeatable read(可重讀) serializable(可序列化)

6去檢視先當前庫的執行緒情況

沒有看到正在執行的慢sql記錄執行緒,再去檢視innodb的事務表innodb_trx,看下裡面是否有正在鎖定的事務執行緒,看看id是否在show full processlist裡面的sleep執行緒中,如果是,就證明這個sleep的執行緒事務一直沒有commit或者rollback而是卡住了

看到有這條9930577的sql,kill掉,執行kill 9930577;

ok 問題就非完美解決了7

小結 表資料量也不大,按照普通的情況來說,簡單的update應該不會造成阻塞的,mysql都是autocommit,不會出現update卡住的情況,去檢視下autocommit的值。

mysql> select @@autocommit;

| @@autocommit |

+--------------+

|        0|

1 row in set (0.00 sec)

看到亮閃閃的0,這個設定導致原來的update語句如果沒有commit的話,你再重新執行update語句,就會等待鎖定,當等待時間過長的時候,就會報error 1205 (hy000): lock wait timeout exceeded; try restarting transaction的錯誤。

所以趕緊commit剛才執行的update語句,之後 set global autocommit=1;8

innodb

關於鎖的表有三個

在5.5中,information_schema 庫中增加了三個關於鎖的表(memory引擎):

innodb_trx        ##

當前執行的所有事務

innodb_locks      ##

當前出現的鎖

innodb_lock_waits ##

鎖等待的對應關係 9

直接使用show engine innodbstatus檢視

先使用innodb_lock_monitor來獲取阻塞鎖線程

create table `innodb_lock_monitor` (

`a` int(11) default null

) engine=innodb default charset=utf8; ## 

隨便在乙個資料庫中建立這個表,就會開啟lock monitor  

然後再使用show engineinnodb status檢視

從以上很容易就分析出了有兩個問題,乙個是由於使用了唯一外索引導致的`xixing`.`t_mp_message_config`表的fk_mf_user 索引shopid欄位是唯一的索引,然後插入已經存在的shopid 導致行鎖住,事務不能提交。

第二個是因為`mp_zshl`.`seller_consume_code` trx id 31375933 lockmode ix 表被鎖住,鎖是ix 互斥鎖。

從以上就很容易定位到**具體位置 ,然後從**處盡量遮蔽這種情況發生。

10.

結論在分析innodb中鎖阻塞時,幾種方法的對比情況:

(1)  

使用show processlist檢視不靠譜;

(2)  

直接使用show engineinnodbstatus檢視,無法判斷到問題的根因;

(3)  

使用mysqladmin debug檢視,能看到所有產生鎖的執行緒,但無法判斷哪個才是根因;

(4)  

開啟innodb_lock_monitor後,再使用showengine innodb status檢視,能夠找到鎖阻塞的根因。

四 參考

getting-lock-wait-timeout-exceeded-try-restarting-transaction-even-though-im 

mysql鎖阻塞分析

mysql innodb_lock_wait 鎖等待

mysql5.6官方文件

簡單理解mysql InnoDB的死鎖問題

mysql三種鎖的級別 行級鎖 開銷大,加鎖慢 會出現死鎖 鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高 表級鎖 開銷小,加鎖快 不會出現死鎖 鎖定粒度大,發生鎖衝突的概率最高,併發度最低 頁面鎖 開銷和加鎖時間界於表鎖和行鎖之間 會出現死鎖 鎖定粒度界於表鎖和行鎖之間,併發度一般 資料庫儲存引...

Mysql InnoDB儲存引擎中 死鎖

今天我們來看死鎖,死鎖的一般場景大家都能想到,只要你不是很菜,a獲取資源z之後再獲取資源x,b獲取資源x之後再獲取資源z,這樣就造成了死鎖。解釋 死鎖是指兩個或兩個以上的事務在執行過程中,因爭奪鎖資源而造成的一種互相等待的現象。解決辦法 1.超時。innodb中設定了超時時間,引數為innodb l...

MySQL InnoDB除錯死鎖的方法!

近期寫了不少innodb鎖相關的文章,不少小夥伴問,如何在mysql終端模擬併發事務,如何復現之前文章中的案例。今天,咱們一起動起手來,模擬併發事務的互斥與死鎖。事前準備 安裝mysql服務端 安裝mysql客戶端 安裝能夠模擬多個併發事務的終端 畫外音 樓主使用的是mysql5.6,官方客戶端my...