我们看到在MySQL 5.7版本里大量遗留很多年的bug都被fix掉了,bug#12161就是其中一个,该bug在2005年第一次report到Bug list上,十年之后终于在MySQL 5.7.7 第一个RC版本被fix了。

最近整理的Java架构学习视频和大厂项目底层知识点,需要的同学欢迎私信我【资料】发给你~一起学习进步!

Bug描述

当我们显式开启一个XA事务,执行操作,并完成XA PREPARE后,如果Kill session或者主动断开再重连执行XA RECOVER,之前的这个XA事务就会直接丢失掉了。

例如:

mysql> XA BEGIN 'abc';Query OK, 0 rows affected (0.00 sec)   mysql> INSERT INTO t1 VALUES (1,2,3);Query OK, 1 row affected (0.00 sec)   mysql> XA END 'abc';Query OK, 0 rows affected (0.00 sec)   mysql> XA PREPARE 'abc';Query OK, 0 rows affected (0.00 sec)   mysql> Ctrl-C -- exit!Aborted   mysql> XA RECOVER;Empty set (0.00 sec)

有趣的是,如果在XA PREPARE后把实例KILL掉,是可以通过XA RECOVER恢复的:

mysql> XA RECOVER;+----------+--------------+--------------+------+| formatID | gtrid_length | bqual_length | data |+----------+--------------+--------------+------+| 1 | 3 | 0 | abc |+----------+--------------+--------------+------+1 row in set (0.00 sec)   mysql> XA COMMIT 'abc';Query OK, 0 rows affected (0.00 sec)

虽然实例异常重启可以恢复事务,但引入的另外一个问题是:事务变更的binlog丢失,导致主备数据不一致。

bug产生的原因也很简单:在退出session时,线程总是会去无条件的回滚掉自己尚未提交的事务。

官方修复

持久化

为了解决这个问题,将XA的两阶段记录到了Binlog中;

对于上文描述的序列,当执行到XA PREPARE时,记录第一阶段的binlog,如下:

Query event : XA START X'616263',X'’,1  // 这里的'616262'即是'abc'的十六进制编码Table_map eventWrite_rows eventQuery event:XA END X'616263',X'',1XA_prepare event: XA PREPARE X'616263',X'’,1

这时候该XA事务同时在InnoDB层(事务处于Prepare状态,Redo持久化到磁盘)和Server层都有持久化信息。

其中XA_PREPARE事件是新引入的事件类型(内部类为XA_prepare_event),以后版本升级需要注意到这个低版本不兼容事件。

然后再执行XA COMMIT ‘abc’,产生新的事件:

Query event:XA COMMIT X'616263',X'',1

如果执行XA ROLLBACK,则记录:

Query event:XA ROLLBACK X'616263',X'',1

由于XA PREPARE和XA COMMIT是分开执行的,因此在这两个事件中间可能存在别的事务,备库复制线程需要处理这种情况。

为了实现XA PREPARE写binlog,对binlog_prepare进行了扩展,这里会调用mysql_bin_log.commit, 将cache中的binlog刷到文件中。

Tips:XID可以包含三个部分:gtrid, [, bqual [, format ID]],其中gtrid是必选的,表示全局标识,bqual是分支标识,默认为空’‘,format ID是一个unsigned整型,默认值为1,在上例中,我们只指定了gtrid为’abc’,因此bqual段和format ID均为默认值。更具体的描述参考官方文档。

如何恢复

当会话断开时(例如kill session或者一次干净的shutdown/restart操作),我们必须要能恢复该事务,之前的逻辑是在cleanup时,直接回滚所有的活跃事务。在新版本中,对XA PREPARE的事务做了特殊处理(THD::cleanup),如果处于Prepare状态,就将事务的in_recovery设置为TRUE,并更新到hash表transaction_cache中(transaction_cache_detach),该hash表用于维护所有XA事务。

对于非XA的活跃事务,在会话断开时,依然采用回滚策略。

当重连客户端后,我们可以直接执行 XA COMMIT ‘abc’,这时候会通过XID关键字去搜索transaction_cache并将对应的事务提交掉。

同时BINLOG的状态要保持一致,如果会话断开前的XA PREPARE没有记录Binlog, 重连后执行XA COMMIT也不应该记录。

备库复制

由于XA PREPARE和XA COMMIT是分开记录的,当碰到XA COMMIT时,备库采用等待之前的事务全部完成,然后再执行的方式(相当于退化到串行)。

另外,我们知道在一个正常的会话过程中,总是为其cache一个事务对象,新的事务会重用这个事务对象,避免多次分配;而XA事务的COMMIT和PREPARE是分离的,需要为XA事务单独分配事务对象。因此复制线程执行XA START时,将其拥有的事务对象临时保存起来(detach_native_trx),当执行到XA_prepare_log_event事件时,再将其恢复给复制线程,同时XA事务对象关闭read view,将is_recovered设置为TRUE(函数innodb_replace_trx_in_thd)。

随后复制线程在执行到XA COMMIT时直接根据XID找到对应的XA事务进行提交。

参考:

WL#6860 Binlogging XA-prepared transaction Github:git show f4c37f7aea732763947980600c6882ec908a54a0 MySQL 5.7.7-RC

有任何问题欢迎留言交流~


整理总结不易,如果觉得这篇文章有意思的话,欢迎转发、收藏,给我一些鼓励~

有想看的内容或者建议,敬请留言!

最近利用空余时间整理了一些精选Java架构学习视频和大厂项目底层知识点,需要的同学欢迎私信我发给你~一起学习进步!有任何问题也欢迎交流~

Java日记本,每日存档超实用的技术干货学习笔记,每天陪你前进一点点~

mysql如何查看事务日记_修复MySQL中人人头疼的Bug,看这篇就够相关推荐

  1. mysql如何查看事务日记_详解 Mysql 事务和Mysql 日志

    事务特性 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节. 2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破 ...

  2. win7查看tomcat端口_想研究Tomcat性能调优,看这篇就够了

    一.下载地址 https://tomcat.apache.org/download-80.cgi 二.安装步骤 将安装包 apache-tomcat-8.5.39.tar.gz 上传至服务器 /usr ...

  3. mysql如何查看事务日记_MySQL日志查看详解

    解决问题: 了解MySQL日志? 怎样查看错误日志? 怎样查看慢日志? 1. MySQL日志分类? MySQL日志主要包含:错误日志.查询日志.慢查询日志.事务日志.二进制日志. 1.1 错误日志: ...

  4. mysql如何查看事务日记_Mysql事务和Mysql 日志

    事务特性 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节. 2.一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破 ...

  5. mysql索引与事务笔记_《MySQL技术内幕:InnoDB存储引擎》读书笔记五-锁、索引及事务...

    1.锁mysql 1)锁是数据库系统区别于文件系统的一个关键特性,数据库使用锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性.算法 2)每一种数据库实现锁的方式都不一样.sql 共享锁:容 ...

  6. mysql如何查看事务日记_MySQL中的几种日志了解

    前言 MySQL中有以下日志文件,分别是: 1:重做日志(redo log) 2:回滚日志(undo log) 3:二进制日志(binlog) 4:错误日志(errorlog) 5:慢查询日志(slo ...

  7. mysql四种事务级别_【MySQL 知识】四种事务隔离级别

    摘要:本篇文章主要是为了对MySQL的四种事务隔离级别的介绍.为了保证数据库的正确性与一致性,数据库事务具有原子性(Atomicity).一致性(Consistency).隔离性(Isolation) ...

  8. python6小时完全入门_如果只有1小时学Python,看这篇就够了,摸摸头发你还好吗!...

    和很多同学接触过程中,我发现自学Python数据分析的一个难点是资料繁多,过于复杂.大部分网上的资料总是从Python语法教起,夹杂着大量Python开发的知识点,花了很多时间却始终云里雾里,不知道哪 ...

  9. core控制器属性注入的用处_了解ASP.NET Core 依赖注入,看这篇就够了

    DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关于依赖注入的概念,身边有工作六七年的同事还个东西搞不清楚.另外再介绍一下.NET  Core的DI实现以及对实例 ...

  10. 学python重点是什么_如果只有1小时学Python,看这篇就够了

    大家好,我是大鹏,城市数据团联合发起人,致力于Python数据分析.数据可视化的应用与教学. 和很多同学接触过程中,我发现自学Python数据分析的一个难点是资料繁多,过于复杂.大部分网上的资料总是从 ...

最新文章

  1. 计算机系统的安全需求的需求等级,计算机信息系统安全等级保护 通用技术要求.PDF...
  2. php yii没有数据库吗,php – YII活动记录未插入数据库但未给出错误
  3. 自动渗透测试工具集APT2
  4. win8下面卸载MYSQL数据库
  5. matlab中tenmat,tensor_toolbox_2.5 2014最新的张量的工具包, 中包含了各种 函数。 matlab 238万源代码下载- www.pudn.com...
  6. USACO翻译:USACO 2014 FEB SILVER 三题
  7. Android USB Host与HID通讯
  8. 【设计模式】各个击破单例模式的8种写法
  9. kotlin读取sd卡里的文件_如何在Kotlin中写入文件?
  10. CentOS 7安装Gnome GUI 图形界面
  11. VS2017控制台打印问题
  12. D-News|扎克伯格下月发布人工智能管家,美放宽无人机商用飞行标准
  13. 基于Java毕业设计新能源汽车租赁管理系统源码+系统+mysql+lw文档+部署软件
  14. 11计算机专业vb试题答案,11高三计算机专业VB试题(三)
  15. 70行代码让你远离颈椎病,致所有的程序猿们
  16. python求残差_在python中如何计算点过程的残差
  17. 记忆测试系统c语言,单词记忆测试器程序设计.doc
  18. OPM Demo Flow
  19. STM32-24位AD7799驱动之手册代码详解,支持模拟SPI和硬件SPI
  20. 计算机基础a试题,计算机基础试题A

热门文章

  1. 何如添加到将文章添加到首页
  2. 关于304缓存 (转沫鱼的前端世界)
  3. Spring中的Bean可以绕过生命周期管理吗?
  4. 前端手残党福利(BootstrapCV大法)
  5. 高并发架构系列:最全消息队列有哪些?详解消息队列的选型与应用
  6. 一份来自滴滴运维工程师的监控系统建设心得
  7. 【设计模式】03-抽象工厂模式
  8. ACM模板(Java)
  9. python 的for与while 的i改变
  10. javascript 字符串中单引号和双引号区别