为何出现了trx_mysql_thread_id为0 的事务是什么
今天巡检时突然发现有很多锁等待超时的情况,原以为是一个简单的小事,一查,结果令人深思。
1. 问题现象
发现日志中出现了大量的 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction 错误

2. 排查过程
发现此类情况后,挑了其中一个SQL脚本手动运行了一下,发现同样报此错误
mysql> 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
出现此情况,第一反应是查看是否有未提交的事务或有其他的SQL运行时也需要对该条记录进行写操作。
# 查看正在运行的sql select * from information_schema.processlist where info is not null;
结果集中并无对该表的任何操作,因此,很大可能是有未提交的事务了。
# 查看事务 SELECT *FROM information_schema.INNODB_TRX;
结果中确实存在大量事务,此时原本以为已经查到问题,直接将对应为提交的事务杀掉即可(已与相关人员确认可以杀)
于是把脚本准备好,准备大开杀戒
# 杀sql会话
SELECT concat('kill ',trx_mysql_thread_id,";")t_sql FROM information_schema.INNODB_TRX;
但是仔细一看,trx_mysql_thread_id全部都是0

经确认,trx_mysql_thread_id=0 的事务全部为XA事务。
3. 处理过程
因为trx_mysql_thread_id=0 的事务无法通过kill trx_mysql_thread_id 的方式处理,所以,需要回滚这些XA事务。
查看XA事务信息
mysql> xa recover;
+------------+--------------+--------------+-------------------------------+
| formatID | gtrid_length | bqual_length | data |
+------------+--------------+--------------+-------------------------------+
| 1096044365 | 20 | 9 | tm156393736565426841tm1333009 |
| 1096044365 | 20 | 9 | tm156393708714926372tm1332251 |
| 1096044365 | 20 | 9 | tm156393726166726646tm1332693 |
...
+------------+--------------+--------------+-------------------------------+
43 rows in set (0.00 sec)
拼接生成XA事务回滚脚本
# XA事务回滚命令的格式:
xa rollback 'left(data,gtrid_length)','substr(data,gtrid_length+1,bqual_length)', formatID; # 以上查出来的信息拼接结果为(以下举其中一个为例)
xa rollback 'tm156393736565426841','tm1333009',1096044365;
执行回滚脚本
mysql> xa rollback 'tm156393736565426841','tm1333009', 1096044365;
Query OK, 0 rows affected (0.00 sec)

检查是否还存在未提交的XA事务
发现已经无正在执行事务

XA信息

测试能否正常更新记录
# 发现也已正常

再检查各日志,此类锁等待问题也未出现。
4. XA事务(分布式事务)浅析
mysql> XA START 'xatest';
Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO mytable (i) VALUES(10);
Query OK, 1 row affected (0.04 sec) mysql> XA END 'xatest';
Query OK, 0 rows affected (0.00 sec) mysql> XA PREPARE 'xatest';
Query OK, 0 rows affected (0.00 sec) mysql> XA COMMIT 'xatest';
Query OK, 0 rows affected (0.00 sec)
阶段二为提交阶段(commit)。当transaction manager确认所有参与者都ready后,向所有参与者发送commit命令。
如下图所示:
因为XA 事务是基于两阶段提交协议的,所以需要有一个事务协调者(transaction manager)来保证所有的事务参与者都完成了准备工作(第一阶段)。如果事务协调者(transaction manager)收到所有参与者都准备好的消息,就会通知所有的事务都可以提交了(第二阶段)。MySQL 在这个XA事务中扮演的是参与者的角色,而不是事务协调者(transaction manager)。
XA事务的性能问题
XA的性能很低。一个数据库的事务和多个数据库间的XA事务性能对比可发现,性能差10倍左右。因此要尽量避免XA事务,例如可以将数据写入本地,用高性能的消息系统分发数据。或使用数据库复制等技术。只有在这些都无法实现,且性能不是瓶颈时才应该使用XA。并发高的情况下不建议使用,可以借助redis或其他方法来改造。
关于XA事务的问题及优化的方案有什么建议可以留言沟通。
耿小厨已开通个人微信公众号,想进一步沟通或想了解其他文章的同学可以关注我

为何出现了trx_mysql_thread_id为0 的事务是什么的更多相关文章
- PetaPoco4.0的事务为什么不会回滚
using (var srop=DbHelper.CurrentDb.GetTransaction()) { ID = bp.AddModel(model).ToStr(); #region 参与楼盘 ...
- MySQL 8.0 —— CATS事务调度算法的性能提升
原文地址:https://mysqlserverteam.com/contention-aware-transaction-scheduling-arriving-in-innodb-to-boost ...
- MongoDB4.0支持事务管理
背景 最后我们看一下MongoDB的事务管理,本来是没这一篇的,因为网上大部分资料太老,都为MongoDB之前的版本,的确在MongoDB 4.0版本之前是没有事务管理,但是今天年初MongoDB ...
- mongodb4.0支持事务
事务特性: 原子性:所有的改变都完成一致性:最终执行结果一致就行隔离性:一个事务的执行不能其它事务干扰.持久性:指一个事务一旦提交,数据不会改变,存在数据库中 exports.getSession = ...
- EJB3.0之事务
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/aboy123/article/details/24586803 一 事务是什么 1 事务的概念 1. ...
- SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作
本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.事务管理简介 1.事务基本概念 一组业务操作ABCD,要么全部 ...
- MongoDB 4.0 事务实现解析
MongoDB 4.0 引入的事务功能,支持多文档ACID特性,例如使用 mongo shell 进行事务操作 > s = db.getMongo().startSession() sessio ...
- 【Redis3.0.x】事务
Redis3.0.x 事务 基本概念 multi,exec,discard,watch 是 Redis 事务的基础,它们允许一步执行一组命令,有两个重要保证: 事务中的所有命令都被序列化并顺序执行.在 ...
- MySQL事务锁等待超时 Lock wait timeout exceeded; try restarting transaction
工作中处理定时任务分发消息时出现的问题,在查找并解决问题的时候,将相关的问题博客收集整理,在此记录下,以便之后再遇到相同的问题,方便查阅. 问题场景 问题出现的场景: 在消息队列处理消息时,同一事务内 ...
随机推荐
- Qt技术优势
1. Qt这个C++的图形库由Trolltech在1994年左右开发.它可以运行在Windows,Mac OS X, Unix,还有像Sharp Zaurus这类嵌入式系统中.Qt是完全面向对象的. ...
- tortoisegit密码找回之抓包法
因为一直用tortoisegit记住密码(此方法只适用于tortoisegit有记住密码),昨天需要登陆gitlab发现密码忘记了,用了N个常用默认密码都不对:和度娘交流一会儿也无果,gitlab里的 ...
- java多线程之生产者-消费者
public class Product { private String lock; public Product(String lock) { this.lock = lock; } public ...
- python的实用函数
>>> file=open('txt.txt','a') >>> print >> file,'hello,world' >>> fi ...
- JVM底层实现与总结
一.类加载器 1.BootstrapClassLoader(启动类加载器) 它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME% ...
- Tido c++线段树知识讲解(转载)
线段树知识讲解 定义.建树.单点修改.区间查询 特别声明:如上的讲解说的是区间最大值 如果想要查询区间和 只需要改变一下建树和查询的代码就行了,如下 其他根据自己的需要进行修改即可
- JIRA的安装部署问题
JIRA的安装部署问题: 因电脑上装了两人系统,导致我的JIRA服务不能和tomcat同时启动,让我弄了好久都不知道是啥原因,经过请教,总算得出原来是JIRA的Port和Tomcat的Port冲突.在 ...
- React Router 4.0 + webpack 实现组件按需加载
网上关于React Router 4.0的按需加载文章有很多,大致的思路都一样,但是其实具体实现起来却要根据自己的实际情况来定,这里主要介绍一下我的实现方式. 主要方式是通过Route组件的rende ...
- php中使用trait设计单例
trait Singleton { private static $instace = null; private function __construct() { } private functio ...
- JavaScript 之有趣的函数(函数声明、调用、预解析、作用域)
前言:“函数是对象,函数名是指针.”,函数名仅仅是指向函数的指针,与其他包含函数指针的变量没有什么区别,话句话说,一个函数可能有多个名字. -1.函数声明,function+函数名称.调用方法:函数名 ...