今天巡检时突然发现有很多锁等待超时的情况,原以为是一个简单的小事,一查,结果令人深思。

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事务(分布式事务)浅析

在本应用中,为了降低单点压力,根据业务情况进行了分表分库,将表分布在不同的库中(库分布在不同的机器上)。在这种场景下,事务的提交会变得相对复杂,因为多个节点(库)的存在,可能存在部分节点提交失败的情况,即事务的ACID特性需要在各个不同的数据库实例中保证。比如更新db1库的A表时,必须同步更新db2库的B表,两个更新形成一个事务,要么都成功,要么都失败,起初,为了简化应用程序在事务处理的难度,因此直接使用MySQL数据库的分布式事务。
 
 两阶段提交
分布式事务通常采用2PC协议,全称Two Phase Commitment Protocol。该协议主要为了解决在分布式数据库场景下,所有节点间数据一致性的问题。分布式事务通过2PC协议将提交分成两个阶段:
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)
阶段一为准备(prepare)阶段。即所有的参与者准备执行事务并锁住需要的资源。参与者ready时,向transaction manager报告已准备就绪。
阶段二为提交阶段(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 的事务是什么的更多相关文章

  1. PetaPoco4.0的事务为什么不会回滚

    using (var srop=DbHelper.CurrentDb.GetTransaction()) { ID = bp.AddModel(model).ToStr(); #region 参与楼盘 ...

  2. MySQL 8.0 —— CATS事务调度算法的性能提升

    原文地址:https://mysqlserverteam.com/contention-aware-transaction-scheduling-arriving-in-innodb-to-boost ...

  3. MongoDB4.0支持事务管理

    ​ 背景 最后我们看一下MongoDB的事务管理,本来是没这一篇的,因为网上大部分资料太老,都为MongoDB之前的版本,的确在MongoDB 4.0版本之前是没有事务管理,但是今天年初MongoDB ...

  4. mongodb4.0支持事务

    事务特性: 原子性:所有的改变都完成一致性:最终执行结果一致就行隔离性:一个事务的执行不能其它事务干扰.持久性:指一个事务一旦提交,数据不会改变,存在数据库中 exports.getSession = ...

  5. EJB3.0之事务

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/aboy123/article/details/24586803 一 事务是什么 1 事务的概念 1. ...

  6. SpringBoot2.0 基础案例(12):基于转账案例,演示事务管理操作

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.事务管理简介 1.事务基本概念 一组业务操作ABCD,要么全部 ...

  7. MongoDB 4.0 事务实现解析

    MongoDB 4.0 引入的事务功能,支持多文档ACID特性,例如使用 mongo shell 进行事务操作 > s = db.getMongo().startSession() sessio ...

  8. 【Redis3.0.x】事务

    Redis3.0.x 事务 基本概念 multi,exec,discard,watch 是 Redis 事务的基础,它们允许一步执行一组命令,有两个重要保证: 事务中的所有命令都被序列化并顺序执行.在 ...

  9. MySQL事务锁等待超时 Lock wait timeout exceeded; try restarting transaction

    工作中处理定时任务分发消息时出现的问题,在查找并解决问题的时候,将相关的问题博客收集整理,在此记录下,以便之后再遇到相同的问题,方便查阅. 问题场景 问题出现的场景: 在消息队列处理消息时,同一事务内 ...

随机推荐

  1. Windows完成端口编程

    Windows完成端口编程目录一 基本概念二 OVERLAPPED数据结构三 完成端口的内部机制创建完成端口完成端口线程的工作原理线程间数据传递线程的安全退出 一 基本概念       设备---wi ...

  2. 发布Qt Widgets桌面应用程序的方法(自定义进程步骤,用QT Creator直接生成)

    发布Qt Widgets桌面应用程序的方法 Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序 ...

  3. Qt 设置背景图片3种方法(三种方法:QPalette调色板,paintEvent,QSS)

    方法1. setStylSheet{"QDialog{background-image:url()"}}  //使用styleSheet 这种方法的好处是继承它的dialog都会自 ...

  4. Java代码消除switch/case,if/else语句的几种实现方式

    转自:https://my.oschina.net/stefanzhlg/blog/372413 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else ...

  5. 《C++ Primer》读书笔记 第三章

    1.注意:头文件不应包含using声明.因为头文件的内容会拷贝到所有引用他的文件中去,对于某些程序来说,由于不经意间包含了一些名字,可能会产生名字冲突.2.string类型的读入:用cin读入stri ...

  6. Hexo+NexT(一):在Windows下安装Hexo+NexT及搭建博客

    阅读本篇之前,假定读者已经有了Node.js的基础,如需要补充Node.js知识的,请自行百度. Hexo是在Node.js框架下的一个项目,利用Node.js提供的强大功能,完成从Markdown到 ...

  7. Python 爬虫从入门到进阶之路(九)

    之前的文章我们介绍了一下 Python 中的正则表达式和与爬虫正则相关的 re 模块,本章我们就利用正则表达式和 re 模块来做一个案例,爬取<糗事百科>的糗事并存储到本地. 我们要爬取的 ...

  8. Scala 学习之路(七)—— 常用集合类型之 Map & Tuple

    一.映射(Map) 1.1 构造Map // 初始化一个空map val scores01 = new HashMap[String, Int] // 从指定的值初始化Map(方式一) val sco ...

  9. Docker配置容器位置和小技巧

    Docker使用小技巧 清理全部停止的docker容器 有时候我们会有很多已经停止的容器或者由于错误强制退出不能用的容器,那我们就需要删除了,但是我们一个一个的rm删除很麻烦,有多少容器就要rm多少次 ...

  10. H5离线缓存基础系列

    1.什么是离线缓存 离线缓存:离线缓存可以将站点的一些文件缓存到本地,它是浏览器自己的一种机制,将需要的文件缓存下来,以便后期即使没有连接网络,被缓存的页面也可以展示. 2.离线缓存的优势 在没有网络 ...