RDS MySQL InnoDB 鎖等待和鎖等待超時的處理

https://help.aliyun.com/knowledge_detail/41705.htmlhtml

1. Innodb 引擎錶行鎖等待和等待超時發生的場景mysql

2.Innodb 引擎行鎖等待狀況的處理sql

2.1 Innodb 行鎖等待超時參數 innodb_lock_wait_timeout數據庫

2.2 大量行鎖等待和行鎖等待超時的處理spa


1. Innodb 引擎錶行鎖等待和等待超時發生的場景

當一個 RDS MySQL 鏈接會話等待另一個會話持有的互斥行鎖時,會發生 Innodb 引擎錶行鎖等待狀況。3d

一般狀況下,持有該互斥行鎖的會話(鏈接)會迅速的執行完相關操做並釋放掉持有的互斥鎖(事務提交或者回滾),進而等待的會話在行鎖等待超時時間到來前得到該互斥行鎖,進行下一步操做。rest

但在某些狀況下,好比一個實例未感知到的來自客戶端應用的數據庫會話中斷,持有該互斥行鎖的會話長時間不釋放該互斥行鎖,此時若是有其餘會話申請該互斥行鎖,則會致使大量的行鎖等待與行鎖等待超時。code

2. Innodb 引擎行鎖等待狀況的處理 

本文提供的檢查和處理方法,僅當正在發生 InnoDB 行鎖等待的狀況下才成立;由於 InnoDB 行鎖等待默認超時時間爲50秒,所以一般狀況下不容易觀察到行鎖等待現場,能夠經過將 innodb_lock_wait_timeout 參數設置爲較大值來複現問題(生產環境不推薦使用過大的 innodb_lock_wait_timeout 參數值)。orm

2.1. Innodb 行鎖等待超時參數 innodb_lock_wait_timeout

# 參數 默認值 最小值 最大值 說明
1 innodb_lock_wait_timeout 50 1 1073741824 獲取Innodb 行鎖的等待時間,單位秒。可在會話級別設置

該參數控制 Innodb 行鎖等待的超時時間,單位爲秒,RDS 實例該參數的默認值爲 50(秒)。htm

等待互斥鎖的會話在等待 50 秒後會退出鎖等待狀態並返回下面的錯誤,這個行爲稱之爲 Innodb 引擎錶行鎖等待超時。

  1. ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

 innodb_lock_wait_00.png

能夠經過下面的命令查看當前會話和全局的參數設置。

  1. show variables like innodb_lock_wait_timeout’; 查看當前會話show global variables like innodb_lock_w%’; 查看全局設置

該參數支持在會話級別修改,方便應用在會話級別單獨設置某些特殊操做的行鎖等待超時時間,以下:

  1. set innodb_lock_wait_timeout=1000; —設置當前會話 Innodb 行鎖等待超時時間,單位秒

innodb_lock_wait_01.png

 

2.2. 大量行鎖等待和行鎖等待超時的處理

若是行鎖等待和行鎖等待超時持續發生,而且致使當前應用運行異常,那麼須要獲取到一直持有行鎖的會話,而且終止該會話來釋放持有的鎖(會話對應的事務會回滾)。

2.2.1 檢查致使鎖等待和鎖超時的會話

注:下面的方法必須在行鎖等待正在發生的時候進行檢查。

方法 1: 經過 DMS  實例信息   Innodb 鎖等待查看。

 

方法 2:經過 DMS  實例信息  實例會話查看。

 

方法 3: 在 DMS 沒法登陸的狀況下,能夠經過執行下面的查詢,得到致使行鎖等待和行鎖等待超時的會話。

select l.* from ( select 'Blocker' role, p.id, p.user, left(p.host, locate(':', p.host) - 1) host, tx.trx_id, tx.trx_state, tx.trx_started, timestampdiff(second, tx.trx_started, now()) duration, lo.lock_mode, lo.lock_type, lo.lock_table, lo.lock_index, tx.trx_query, lw.requesting_thd_id Blockee_id, lw.requesting_trx_id Blockee_trx from information_schema.innodb_trx tx, information_schema.innodb_lock_waits lw, information_schema.innodb_locks lo, information_schema.processlist p where lw.blocking_trx_id = tx.trx_id and p.id = tx.trx_mysql_thread_id and lo.lock_id = lw.blocking_lock_id union select 'Blockee' role, p.id, p.user, left(p.host, locate(':', p.host) - 1) host, tx.trx_id, tx.trx_state, tx.trx_started, timestampdiff(second, tx.trx_started, now()) duration, lo.lock_mode, lo.lock_type, lo.lock_table, lo.lock_index, tx.trx_query, null, null from information_schema.innodb_trx tx, information_schema.innodb_lock_waits lw, information_schema.innodb_locks lo, information_schema.processlist p where lw.requesting_trx_id = tx.trx_id and p.id = tx.trx_mysql_thread_id and lo.lock_id = lw.requested_lock_id) l order by role desc, trx_state desc;

好比:

對於複雜的多個會話相互行鎖等待狀況,建議先終止 Role 爲 Blocker 且 trx_state 爲 RUNNING 的會話;終止後再次檢查,若是仍舊有行鎖等待,再終止新結果中的 Role 爲 Blocker 且 trx_state 爲 RUNNING 的會話。 

2.2.2 處理致使行鎖等待和行鎖等待超時的會話

對於標識爲 Blocker 的會話(持有鎖阻塞其餘會話的 DML 操做,致使行鎖等待和行鎖等待超時),確認業務能夠接受其對應的事務回滾的狀況下,能夠將其終止。

終止會話的方法請參考:RDS for MySQL如何終止會話

好比,能夠經過 Kill 命令來從此會話終止。

相關文章
相關標籤/搜索