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

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. SpringMVC与uploadify结合进行上传

    uploadify是一个第三方js插件,支持多文件上传,拥有较为强大的上传功能 1.uploadify实现 下载其flash版本 http://www.uploadify.com/  解压后将其内容区 ...

  2. 线程天敌TerminateThread与SuspendThread

    线程天敌TerminateThread与SuspendThread 作者:童磊(magictong) 目的:不是演示TerminateThread和SuspendThread的原理而是希望能在自己的程 ...

  3. jmeter报告分析工具

    一直以来做性能测试都是用jmeter和LR,当然还有一些自己写测试脚本,LR不用说,分析结果那个组件杠杠的!但是jmeter毕竟是开源的,所以分析查看结果不像LR那样自带图形神马的,虽然可以自己写脚本 ...

  4. Spring单例模式多线程安全问题-有状态的Bean

    Spring单例与线程安全小结 一.Spring单例模式与线程安全 Spring框架里的bean,或者说组件,获取实例的时候都是默认的单例模式,这是在多线程开发的时候要尤其注意的地方. 单例模式的意思 ...

  5. Python 爬虫从入门到进阶之路(七)

    在之前的文章中我们一直用到的库是 urllib.request,该库已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “HTTP for Hum ...

  6. 学习过程中遇到的python内置函数,后续遇到会继续补充进去

    1.python内置函数isinstance(数字,数字类型),判断一个数字的数字类型(int,float,comple).是,返回True,否,返回False2.python内置函数id()可以查看 ...

  7. JCS学习记录 --Java Caching System

    Java Caching System--JCS 缓存工具 //jcs版本 jcs-1.3.jar //jcs--cache.ccf缓存配置文件 cache.ccf //所依赖的jar包concurr ...

  8. HBase 学习之路(三)—— HBase基本环境搭建

    一.安装前置条件说明 1.1 JDK版本说明 HBase 需要依赖JDK环境,同时HBase 2.0+ 以上版本不再支持JDK 1.7 ,需要安装JDK 1.8+ .JDK 安装方式见本仓库: Lin ...

  9. 【JVM】02垃圾回收机制

    垃圾回收 垃圾回收策略https://blog.csdn.net/u010425776/article/details/51189318 程序计数器.Java虚拟机栈.本地方法栈都是线程私有的,也就是 ...

  10. appcan中evaluateScript、evaluatePopoverScript的使用

    1. 如果要在某个主窗体中执行JS,使用 appcan.window.evaluateScript(name,scriptContent) eg: appcan.window.evaluateScri ...