MySQL 行锁超时排查方法优化
一、锁超时排大纲
#### 20191219 10:10:10,查方234 | com.alibaba.druid.filter.logging.Log4jFilter.statementLogError(Log4jFilter.java:152) | ERROR | {conn-10593, pstmt-38675} execute error. update xxx set xxx = ? , xxx = ? where RowGuid = ? com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction之前在 [如何有效排查解决 MySQL 行锁等待超时问题] 文章中介绍了如何监控解决行锁超时报错,当时介绍的法优监控方案主要是以 shell 脚本 + general_log 来捕获行锁等待信息,后来感觉比较麻烦,锁超时排因此优化后改成用 Event + Procedure 的查方方法定时在 MySQl 内执行,将行锁等待信息记录到日志表中,法优并且加入了 pfs 表中的锁超时排事务上下文信息,这样可以省去登陆服务器执行脚本与分析 general_log 的查方过程,更加便捷。法优
因为用到了 Event 和 performance_schema 下的锁超时排系统表,源码下载所以需要打开两者的查方配置,pfs 使用默认监控项就可以,法优这里主要使用到的锁超时排是 events_statements_history 表,默认会保留会话 10 条 SQL。查方
performance_schema = on event_scheduler = 1二、法优步骤
目前该方法仅在 MySQL 5.7 版本使用过,MySQL 8.0 未测试。
create database `innodb_monitor`;create database `innodb_monitor`;
2.2 创建存储过程
use innodb_monitor; delimiter ;; CREATE PROCEDURE pro_innodb_lock_wait_check() BEGIN declare wait_rows int; set group_concat_max_len = 1024000; CREATE TABLE IF NOT EXISTS `innodb_lock_wait_log` ( `report_time` datetime DEFAULT NULL, `waiting_id` int(11) DEFAULT NULL, `blocking_id` int(11) DEFAULT NULL, `duration` varchar(50) DEFAULT NULL, `state` varchar(50) DEFAULT NULL, `waiting_query` longtext DEFAULT NULL, `blocking_current_query` longtext DEFAULT NULL, `blocking_thd_last_query` longtext, `thread_id` int(11) DEFAULT NULL ); select count(*) into wait_rows from information_schema.innodb_lock_waits ; if wait_rows > 0 THEN insert into `innodb_lock_wait_log` SELECT now(),r.trx_mysql_thread_id waiting_id,b.trx_mysql_thread_id blocking_id,concat(timestampdiff(SECOND,r.trx_wait_started,CURRENT_TIMESTAMP()),s) AS duration, t.processlist_command state,r.trx_query waiting_query,b.trx_query blocking_current_query,group_concat(left(h.sql_text,10000) order by h.TIMER_START DESC SEPARATOR ;\n) As blocking_thd_query_history,thread_id FROM information_schema.innodb_lock_waits w JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id LEFT JOIN performance_schema.threads t on t.processlist_id = b.trx_mysql_thread_id LEFT JOIN performance_schema.events_statements_history h USING(thread_id) group by thread_id,r.trx_id order by r.trx_wait_started; end if; END ;;2.3 创建事件
事件 每隔 5 秒 (通常等于 innodb_lock_wait_timeout 的值)执行一次,持续监控 7 天,结束后会自动删除事件,也可以自定义保留时长。高防服务器
use innodb_monitor; delimiter ;; CREATE EVENT `event_innodb_lock_wait_check` ON SCHEDULE EVERY 5 SECOND STARTS CURRENT_TIMESTAMP ENDS CURRENT_TIMESTAMP + INTERVAL 7 DAY ON COMPLETION NOT PRESERVE ENABLE DO call pro_innodb_lock_wait_check(); ;;2.4 事件启停
--1为全局开启事件,0为全局关闭 mysql > SET GLOBAL event_scheduler = 1; --临时关闭事件 mysql > ALTER EVENT event_innodb_lock_wait_check DISABLE; --关闭开启事件 mysql > ALTER EVENT event_innodb_lock_wait_check ENABLE;三、日志表
再根据应用日志报错时间点及 SQL 分析 innodb_lock_wait_log 表。其中主要有 2 种场景:
blocking_current_query 不为空,说明阻塞事务处于运行状态,这时候需要分析当前运行 SQL 是否存在性能问题。 blocking_current_query 为空,state 为 Sleep,此时阻塞事务处于挂起状态,即不再运行 SQL,此时需要通过分析 blocking_thd_last_query 分析事务上下文,注意该列中的 SQL 为时间降序,即从下往上执行。
云南idc服务商相关文章
如何使用苹果设备分享WiFi密码给其他手机(简单实用的方法和步骤,让你轻松共享网络连接)
摘要:现在,我们离不开互联网的便利,而WiFi成为了我们生活中不可或缺的一部分。当我们身边有朋友或家人需要连接网络时,有时候告诉他们长长的密码实在是不太方便。幸运的是,苹果设备为我们提供...2025-11-05如何使用苹果电脑连接华硕电脑进行系统重装(以苹果AirDrop技术为基础,教你一步步完成华硕电脑系统重装)
摘要:随着科技的进步,越来越多的人开始使用多台设备来满足不同的需求。然而,在使用不同品牌的电脑时,可能会遇到一些问题,例如在华硕电脑上进行系统重装。本文将以苹果电脑和华硕电脑为例,介绍如...2025-11-05- 摘要:随着科技的不断发展,电子游戏已经成为现代人生活中不可或缺的一部分。而精灵雷神K8作为一款备受瞩目的游戏设备,给玩家带来了全新的游戏体验。本文将深入探索精灵雷神K8的魅力,从不同方面...2025-11-05
- 摘要:随着科技的不断进步,一体台式电脑以其独特的设计和便捷的使用方式成为了越来越多人工作和娱乐的首选。一体台式电脑将显示屏、主机和输入设备整合在一起,占用空间小、外观美观,给用户带来了全...2025-11-05
苹果电脑wps更新域名错误问题解决方法(如何正确处理苹果电脑wps软件在更新过程中出现的域名错误)
摘要:在使用苹果电脑的过程中,很多用户会遇到wps软件在更新时出现域名错误的问题,导致更新失败或使用受限。本文将为大家提供一些解决方法,帮助解决这个困扰苹果电脑用户的问题。1.检...2025-11-05原装系统安装教程(详细教程带你了解原装系统安装步骤及注意事项)
摘要:随着电脑技术的不断发展,更多人选择在自己的电脑上安装原装系统以获得更好的性能和稳定性。但对于一些没有经验的用户来说,安装原装系统可能会有一些困惑和不知所措。本文将为大家提供一份详细...2025-11-05


最新评论