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

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. 树莓派中安装QT

    树莓派中安装QT 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 硬件:树莓派 步骤: 参考链接:http://qt-proje ...

  2. 验证码生成器(在TImage.Canvas上写字,很好看)

    生成验证码的方式有很多种,如下则是比较简单的实现,且运用了正余弦曲线来扭曲验证码字符. unit AuthenticodeGenerate; interface uses SysUtils, Wind ...

  3. 【图文】[新手]C++ 动态库导出函数名“乱码”及解决

    刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...

  4. 【UVA - 11624】Fire!

    -->Fire! 直接上中文 Descriptions: 乔在迷宫中工作.不幸的是,迷宫的一部分着火了,迷宫的主人没有制定火灾的逃跑计划.请帮助乔逃离迷宫.根据乔在迷宫中的位置以及迷宫的哪个方块 ...

  5. 使用redis PSUBSCRIBE实现实时任务

    PSUBSCRIBE可以监听键的过期事件 1.进行数据库的配置 notify-keyspace-events Ex 2.使用命令监听事件 psubscribe  __keyevnet@0__:expi ...

  6. CRM 总结

    目录 一. CRM客户关系管理系统 1. CRM是什么? 里面都有哪些功能(业务)? 2. 什么是公户?什么是私户?为什么要做这个区分? 3. 请列举出CRM系统中的表 4. 通过ORM操作对数据库的 ...

  7. 在Ubuntu16.04 TLS 安装LAMP

    准备在虚拟机上搭建一个靶机系统(DoraBox),但是还不想使用一键搭建所以起了心思准备使用LAMP框架搭载这个靶机系统,于是有了以下文章,先从百度搜索一下,Ubuntu搭建LAMP. 然后点进去第一 ...

  8. Linux命令学习-tail命令

    Linux中,tail命令的全称就是tail,主要用于监控日志文件. 对于一个正在运行应用来说,其对应的log日志文件肯定是在不断的更新,此时,便可通过tail命令来动态显示日志文件的内容.假设当前目 ...

  9. c++学习书籍推荐《C标准库(英文版)》下载

    <C标准库(英文版)>是由世界级C语言专家编写的C标准库经典著作,影响了几代程序员. <C标准库(英文版)>集中讨论了C标准库,全面介绍了ANSI/ISO C语言标准的所有库函 ...

  10. 2. python Mac 安装 dlib

    在macOS上: 从Mac App Store安装 XCode(或安装XCode命令行工具)(最低版本是:xcode8 以上) 有 homebrew 安装 有 CMAKE 安装 基础包 :numpy ...