Mysql死鎖問題總結


參考連接:https://www.cnblogs.com/nicole-star/p/11114199.html

一、問題

### Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction;

 

現象:接口響應時間超長,耗時幾十秒才返回錯誤提示,后台日志中出現Lock wait timeout exceeded; try restarting transaction的錯誤

二、原因分析

使用InnoDB表類型的時候,鎖等待超過了innodb_lock_wait_timeout(默認是50s)設置的時間,所以報錯

三、可能出現場景

1、在同一事務內先后對同一條數據進行插入和更新操作

2、多台服務器操作同一數據庫

3、瞬時出現高並發現象,spring事務造成數據庫死鎖,后續操作超時拋出異常

4、事務A對記錄C進行更新/刪除操作的請求未commit時,事務B也對記錄C進行更新/刪除操作。此時,B會等A提交事務,釋放行鎖。當等待時間超過innodb_lock_wait_timeout設置值時,會產生“LOCK WAIT”事務。

四、解決方案

1、【治標方法】innodb_lock_wait_timeout 鎖定等待時間改大

my.ini文件:

#innodb_lock_wait_timeout = 50

修改為

innodb_lock_wait_timeout = 500

缺點:全局更改,影響也是全局的,等待時間加長,容易使等待事務增多導致堆積問題。

2、【治標方法】事務信息查詢

SELECT * FROM information_schema.innodb_trx

查到一個一直沒有提交的只讀事務(trx_state=”LOCK WAIT”),找到對應線程,執行:

kill 線程ID(trx_mysql_thread_id)

3、【治標方法】如果殺掉線程依然不能解決,可以查找執行線程耗時比較久的任務,kill掉

SELECT * from information_schema.`PROCESSLIST` WHERE Time > 1000 AND USER = 'xxx' ORDER BY TIME desc;

kill 線程ID

4、【根本解決方法!】找到鎖表的事務,分析鎖表原因,進行優化。

實例:司機APP進行運單簽收,需要對et_waybill_info表某些記錄進行更新操作。一直處於鎖等待狀態,直到超時報錯。

經排查,發現:系統定時器定時執行任務,將所有未標識亮的已裝車或簽收的運單,按批次處理,如果運單裝車了但長時間未上傳GPS、溫濕度等信息,會一直被定時器處理。數據量越積越大,隊列長時間等待,對et_waybill_info表鎖住沒有釋放,致使簽收要操作et_waybill_info表無法拿到鎖,進行數據操作。

臨時解決方案:停掉定時器任務

根本解決方案:優化定時器

五、預防措施

1、開始事務(@transtion)指定超時時 間

例:@Transactional( rollbackFor = Exception.class , isolation = Isolation.REPEATABLE_READ, timeout = 30)

2、事務中存在批量修改、刪除語句的時候,where條件盡量加索引

3、事務中存在批量修改、刪除語句的時候,盡可能減少事務的執行時間

4、減少並發線程數

六、相關信息

1、innodb_lock_wait_timeout和lock_wait_timeout

innodb_lock_wait_timeout:InnoDB事務等待一個行級鎖的時間最長時間(單位是秒),超過這個時間就會放棄。默認值是50秒

lock_wait_timeout:獲取元數據鎖的超時時間。這個適合用於除了系統表之外的所有表(mysql庫之外)。

區別於innodb_lock_wait_timeout是針對dml操作的行級鎖的等待時間 ,而lock_wait_timeout是數據結構ddl操作的鎖的等待時間

2、事務相關表

INNODB_TRX  當前運行的所有事務

 

INNODB_LOCKS  當前出現的鎖,查看正在鎖的事務

 

INNODB_LOCK_WAITS  鎖等待的對應關系,查看等待鎖的事務

 

3、information_schema和performance_schema

information_schema:對數據庫元數據的抽象分析,由此提供了SQL語句方式來查詢數據庫運行時狀態,每次對infomation_schema的查詢都產生對metadata的互斥訪問,影響其他數據庫的訪問性能。這張數據表保存了MySQL服務器所有數據庫的信息。如數據庫名,數據庫的表,表欄的數據類型與訪問權限等。

performance_schema:內存型數據庫,使用performance_schema存儲引擎,通過事件機制將mysql服務的運行時狀態采集並存儲在performance_schema數據庫。用於監控MySQL server在一個較低級別的運行過程中的資源消耗、資源等待等情況。

七、總結

1、當看到mysql報錯時,可以根據報錯的信息及錯誤號去分析報錯原因,然后冷靜分析,透過現象看本質,從根本上解決問題。少用治標不治本的方案,還可能會帶來其他問題。

2、了解了mysql里幾張事務相關表

3、初識information_schema和performance_schema


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM