mysql查询未提交事务的sql语句,找出未提交事务执行的SQL语句
mysql开启事务后没有提交就退出,事务长时间running状态,进程又处于Sleep状态,有可能后续导致其他事物超时失败
常见原因
- 事务过程中执行其他非数据库操作,导致事务长期未被处理。
- 事务处理异常或实现逻辑有误,导致事务未被正常处理。
- 网络,数据库负荷过大等
能找到事物执行的sql语句的话就很容易定位到程序中错误的代码
排查过程
查看所有事务
查看进程信息
查询进程状态,发现sleep中,并没有执行,由此可以确认该事务没有提交
show full processlist
查找未提交的事务执行的sql语句
最简单粗暴也最靠谱的方式就是开启通用日志,其他方式不容易查出来,缺点是得开启之后才能记录到
开启MySQL通用日志
# 查看general log配置
show variables like '%general_log%'
## 开启general log
SET GLOBAL general_log = 1;
通用日志会记录所有sql信息,数据量很大,建议只在排查错误时开启,线上关闭
查看通用日志
找到进程号跟时间对应的记录
通用日志信息
210315 15:04:55 238046 Prepare SELECT `t`.*,`r`.`role_name` FROM `teacher` `t` INNER JOIN `school_role` `r` ON `t`.`role_id`=`r`.`id` WHERE ( `t`.`id` = ? ) AND `t`.`delete_time` = ? LIMIT 1
238046 Close stmt
238046 Execute SELECT `t`.*,`r`.`role_name` FROM `teacher` `t` INNER JOIN `school_role` `r` ON `t`.`role_id`=`r`.`id` WHERE ( `t`.`id` = '1' ) AND `t`.`delete_time` = '0' LIMIT 1
238046 Query START TRANSACTION
238046 Prepare INSERT INTO `school_role` SET `role_name` = ? , `create_time` = ?
238046 Close stmt
238046 Execute INSERT INTO `school_role` SET `role_name` = 'justtest' , `create_time` = 1615791895
238046 Prepare SELECT `t`.*,`r`.`role_name` FROM `teacher` `t` INNER JOIN `school_role` `r` ON `t`.`role_id`=`r`.`id` WHERE ( `t`.`id` = ? ) AND `t`.`delete_time` = ? LIMIT 1
238046 Close stmt
238046 Execute SELECT `t`.*,`r`.`role_name` FROM `teacher` `t` INNER JOIN `school_role` `r` ON `t`.`role_id`=`r`.`id` WHERE ( `t`.`id` = '1' ) AND `t`.`delete_time` = '0' LIMIT 1
238046 Prepare SELECT COUNT(*) AS think_count FROM `school_role`
238046 Close stmt
238046 Execute SELECT COUNT(*) AS think_count FROM `school_role`
238046 Prepare SELECT * FROM `school_role` ORDER BY `id` DESC LIMIT 0,10
238046 Close stmt
238046 Execute SELECT * FROM `school_role` ORDER BY `id` DESC LIMIT 0,10
通过日志发现,这个进程开启了事务,插入了一条数据,而没有提交事务,导致事物一直处于运行状态
定位错误代码
发现代码中开启了事务,没有提交