MySQL事務鎖問題-Lock wait timeout exceeded
轉載:https://cloud.tencent.com/developer/article/1356959
問題現象:
接口響應時間超長,耗時幾十秒才返回錯誤提示,後臺日誌中出現Lock wait timeout exceeded; try restarting transaction
的錯誤
問題場景:
1、在同一事務內先後對同一條數據進行插入和更新操作;
2、多臺服務器操作同一數據庫;
3、瞬時出現高並發現象;
問題原因:
1、在高並發的情況下,Spring事物造成數據庫死鎖,後續操作超時拋出異常。
2、Mysql數據庫采用InnoDB模式,默認參數:innodb_lock_wait_timeout設置鎖等待的時間是50s,一旦數據庫鎖超過這個時間就會報錯
解決方法:
1、查看數據庫當前的進程,看一下有無正在執行的慢SQL記錄線程。
mysql> show processlist;
2、查看當前的事務
當前運行的所有事務
mysql> SELECT * FROM information_schema.INNODB_TRX;
當前出現的鎖
mysql> SELECT * FROM information_schema.INNODB_LOCKs;
鎖等待的對應關系
mysql> SELECT * FROM information_schema.INNODB_LOCK_waits;
解釋:看事務表INNODB_TRX,裏面是否有正在鎖定的事務線程,看看ID是否在show processlist裏面的sleep線程中,如果是,就證明這個sleep的線程事務一直沒有commit或者rollback而是卡住了,我們需要手動kill掉。
搜索的結果是在事務表發現了很多任務,這時候最好都kill掉。
3、批量刪除事務表中的事務
我這裏用的方法是:通過information_schema.processlist表中的連接信息生成需要處理掉的MySQL連接的語句臨時文件,然後執行臨時文件中生成的指令。
mysql> select concat(‘KILL ‘,id,‘;‘) from information_schema.processlist where user=‘cms_bokong‘;
+------------------------+
| concat(‘KILL ‘,id,‘;‘) |
+------------------------+
| KILL 10508; |
| KILL 10521; |
| KILL 10297; |
+------------------------+
18 rows in set (0.00 sec)
當然結果不可能只有3個,這裏我只是舉例子。參考鏈接上是建議導出到一個文本,然後執行文本。而我是直接copy到記事本處理掉 ‘|’,粘貼到命令行執行了。都可以。
kill掉以後再執行SELECT * FROM information_schema.INNODB_TRX;
就是空了。
這時候系統就正常了
故障排查
- mysql都是autocommit配置mysql> select @@autocommit; +--------------+ | @@autocommit | +--------------+ | 0 | +--------------+ 1 row in set (0.00 sec)
如果是0 ,則改為1
mysql> set global autocommit=1;
- mysql的引擎檢查,可以檢查一下數據庫引擎是不是InnoDB(mysql5.5.5以前默認是MyISAM,mysql5.5.5以後默認是InnoDB)show ENGINES; #檢查命令 如果不是的話改為 InnoDB :
查看表使用的存儲引擎
show table status from db_name where name=‘table_name‘;
修改表的存儲引擎
alter table table_name engine=innodb;
MySQL事務鎖問題-Lock wait timeout exceeded