首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MySQL里trx_mysql_thread_id为0的事务是啥,为何kill不了?

MySQL里trx_mysql_thread_id为0的事务是啥,为何kill不了?

作者头像
俊才
发布2026-03-31 12:30:02
发布2026-03-31 12:30:02
850
举报
文章被收录于专栏:数据库干货铺数据库干货铺

今天给大家分享一次生产环境的真实巡检故障:大量锁等待超时,排查后发现竟是trx_mysql_thread_id=0的事务在搞鬼,kill命令完全失效,最后靠XA事务回滚才解决。

这种问题隐蔽性极强,常规排查思路完全失效,看完这篇,下次遇到直接照抄解决方案!

一、问题现象:批量锁等待超时,业务更新失败

日常巡检数据库时,日志里疯狂报错:

代码语言:javascript
复制
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
图片
图片

手动执行业务更新SQL,同样触发报错:

代码语言:javascript
复制
UPDATE tbname SET column_name = 2 
WHERE col_id= '25945fa285904ea59cd92a73a3850ceb' AND aYear = 2018 AND aMonth = 5;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

典型的锁等待超时,业务更新被阻塞,影响正常运行。

二、排查过程:常规思路全失效,发现诡异事务

遇到锁等待,第一反应是查活跃会话、查未提交事务,结果全程踩坑:

1. 排查活跃会话

先查正在运行的SQL,完全没有对该表的操作:

代码语言:javascript
复制
select * from information_schema.processlist where info is not null;

2. 排查InnoDB事务

接着查INNODB_TRX,果然有大量未提交事务,本以为找到元凶,准备kill会话:

代码语言:javascript
复制
SELECT * FROM information_schema.INNODB_TRX;
图片
图片

结果中确实存在大量事务,此时原本以为已经查到问题,直接将对应为提交的事务杀掉即可(已与相关人员确认可以杀),于是把脚本准备好,准备大开杀戒。

3. 核心卡点:trx_mysql_thread_id=0

拼接kill语句时直接傻眼:所有事务的trx_mysql_thread_id全部为0!

代码语言:javascript
复制
SELECT concat('kill ',trx_mysql_thread_id,";") t_sql FROM information_schema.INNODB_TRX;

kill 0完全无效,这根本不是普通的用户会话事务!

最终确认:trx_mysql_thread_id=0的事务,全部是MySQL XA分布式事务。

三、处理方案:XA事务专用回滚步骤

普通kill命令失效,必须用XA事务语法手动回滚,步骤直接复制可用:

1. 查看未处理的XA事务

执行xa recover,列出所有prepare状态的XA事务:

代码语言:javascript
复制
mysql> xa recover;
+------------+--------------+--------------+-------------------------------+
| formatID   | gtrid_length | bqual_length | data                          |
+------------+--------------+--------------+-------------------------------+
| 1096044365 | 20           | 9            | tm156393736565426841tm1333009  |
| 1096044365 | 20           | 9            | tm156393708714926372tm1332251  |
+------------+--------------+--------------+-------------------------------+

2. 拼接XA回滚语句

XA回滚固定格式:

代码语言:javascript
复制
xa rollback 'gtrid内容','bqual内容',formatID;

拆分规则:

  • gtrid:截取data前gtrid_length位字符
  • bqual:截取data中gtrid_length+1开始、长度bqual_length的字符

以上面数据为例,拼接结果:

代码语言:javascript
复制
xa rollback 'tm156393736565426841','tm1333009',1096044365;

3. 批量执行回滚

逐行执行回滚语句,清理所有僵死XA事务:

代码语言:javascript
复制
mysql> xa rollback 'tm156393736565426841','tm1333009', 1096044365;
Query OK, 0 rows affected (0.00 sec)
图片
图片

4. 验证结果

再次查询INNODB_TRX,无残留事务

图片
图片

重新执行业务更新SQL,执行成功,锁等待超时错误彻底消失,业务恢复正常。

图片
图片

四、XA分布式事务到底是什么?

本次问题出在分库分表场景,业务跨多个库操作,必须用分布式事务保证一致性,而MySQL的XA事务就是基于两阶段提交(2PC)实现的。

1. 两阶段提交流程

  • 阶段1(Prepare):所有库锁定资源,准备就绪,上报协调者
  • 阶段2(Commit/Rollback):协调者统一指令,全部提交/全部回滚
图片
图片

2. MySQL XA事务基础语法

代码语言:javascript
复制
-- 开启XA事务
XA START 'xatest';
-- 执行业务SQL
INSERT INTO mytable (i) VALUES(10);
-- 结束XA事务
XA END 'xatest';
-- 准备阶段(核心:会持有锁)
XA PREPARE 'xatest';
-- 提交/回滚
XA COMMIT 'xatest';
XA ROLLBACK 'xatest';

3. XA事务的致命问题

XA事务有如下几个主要问题:

  • 僵死风险:协调者宕机,事务卡在Prepare阶段,长期持有锁
  • 性能极差:相比普通事务,性能下降10倍左右
  • 排查困难:trx_mysql_thread_id=0,常规工具无法识别

4. 避坑建议

生产环境可以禁用XA事务,如果没禁用,建议经常进行巡检及监控,即从如下方面进行:

  • 高并发场景禁用MySQL原生XA:改用消息队列、最终一致性方案替代
  • 定期巡检XA事务:定时执行xa recover,清理僵死事务
  • 优化分库分表逻辑:减少跨库事务,降低分布式事务使用频率
  • 监控告警:对INNODB_TRX中trx_mysql_thread_id=0的事务做告警

五、总结

trx_mysql_thread_id=0是MySQL分布式事务的标志性特征,遇到锁等待超时先查这个字段,别盲目kill会话!解决方案是:xa recover查看→拆分gtrid/bqual→xa rollback回滚,这样才能解决僵死XA事务导致的锁阻塞。

你在生产中遇到过哪些诡异的MySQL锁问题?欢迎评论区留言交流~

觉得干货实用,记得点赞、在看、转发,关注我,持续分享MySQL实战排坑技巧!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据库干货铺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档