概念:

XA(分布式事务)规范主要定义了(全局)事务管理器(TM: Transaction Manager)和(局部)资源管理器(RM: Resource Manager)之间的接口。XA为了实现分布式事务,将事务的提交分成了两个阶段:也就是2PC (tow phase commit),XA协议就是通过将事务的提交分为两个阶段来实现分布式事务。

两阶段:

1)prepare 阶段

事务管理器向所有涉及到的数据库服务器发出prepare"准备提交"请求,数据库收到请求后执行数据修改和日志记录等处理,处理完成后只是把事务的状态改成"可以提交",然后把结果返回给事务管理器。即:为prepare阶段,TM向RM发出prepare指令,RM进行操作,然后返回成功与否的信息给TM。

2)commit 阶段

事务管理器收到回应后进入第二阶段,如果在第一阶段内有任何一个数据库的操作发生了错误,或者事务管理器收不到某个数据库的回应,则认为事务失败,回撤所有数据库的事务。数据库服务器收不到第二阶段的确认提交请求,也会把"可以提交"的事务回撤。如果第一阶段中所有数据库都提交成功,那么事务管理器向数据库服务器发出"确认提交"请求,数据库服务器把事务的"可以提交"状态改为"提交完成"状态,然后返回应答。即:为事务提交或者回滚阶段,如果TM收到所有RM的成功消息,则TM向RM发出提交指令;不然则发出回滚指令。

实现:

MySQL中的XA实现分为:外部XA和内部XA。前者是指我们通常意义上的分布式事务实现;后者是指单台MySQL服务器中,Server层作为TM(事务协调者),而服务器中的多个数据库实例作为RM,而进行的一种分布式事务,也就是MySQL跨库事务;也就是一个事务涉及到同一条MySQL服务器中的两个innodb数据库(因为其它引擎不支持XA)。

1)内部XA的额外功能:XA 将事务的提交分为两个阶段,而这种实现,解决了 binlog 和 redo log的一致性问题。

MySQL为了兼容其它非事物引擎的复制,在server层面引入了 binlog, 它可以记录所有引擎中的修改操作,因而可以对所有的引擎使用复制功能。MySQL在4.x 的时候放弃redo的复制策略而引入binlog。但是引入了binlog,会导致一个问题——binlog和redo log的一致性问题:一个事务的提交必须写redo log和binlog,那么二者如何协调一致呢?事务的提交以哪一个log为标准?如何判断事务提交?事务崩溃恢复如何进行?

MySQL通过两阶段提交(内部XA的两阶段提交)很好地解决了这一问题:
第一阶段:InnoDB prepare,持有prepare_commit_mutex,并且write/sync redo log; 将回滚段设置为Prepared状态,binlog不作任何操作;
第二阶段:包含两步,> write/sync Binlog; > InnoDB commit (写入COMMIT标记后释放prepare_commit_mutex);
以binlog 的写入与否作为事务提交成功与否的标志,innodb commit标志并不是事务成功与否的标志。
此时的事务崩溃恢复过程如下:
> 崩溃恢复时,扫描最后一个Binlog文件,提取其中的xid
> InnoDB维持了状态为Prepare的事务链表,将这些事务的xid和Binlog中记录的xid做比较,如果在Binlog中存在,则提交,否则回滚事务。
通过这种方式,可以让InnoDB和Binlog中的事务状态保持一致。如果在写入innodb commit标志时崩溃,则恢复时,会重新对commit标志进行写入;在prepare阶段崩溃,则会回滚,在write/sync binlog阶段崩溃,也会回滚

简而言之就是:先写redo log,再写binlog,并以binlog写成功为事务提交成功的标志。崩溃恢复是以binlog中的xid和redo log中的xid进行比较,xid在binlog里存在则提交,不存在则回滚。

MySQL XA分为两类,内部XA与外部XA;

内部XA用于同一实例下跨多个引擎的事务,由Binlog作为协调者;

外部XA用于跨多个MySQL实例的分布式事务,需要应用层介入作为协调者(崩溃时的悬挂事务,全局提交还是回滚,需要由应用层决定,对应用层的实现要求较高);

最常见的内部XA事务存在于binlog与InnoDB存储引擎之间,从而保证了主从环境的数据一致性。

2)binlog 组提交:

      上面介绍事务的两阶段提交过程是5.6之前版本中的实现,有严重的缺陷。当sync_binlog=1时,很明显上述的第二阶段中的 write/sync binlog会成为瓶颈,而且还是持有全局大锁(prepare_commit_mutex: prepare 和 commit共用一把锁),这会导致性能急剧下降。解决办法就是在MySQL5.6中引进的binlog组提交。

Binlog Group Commit的过程拆分成了三个阶段

> flush stage 将各个线程的binlog从cache写到文件中;
> sync stage 对binlog做fsync操作(如果需要的话;最重要的就是这一步,对多个线程的binlog合并写入磁盘);
> commit stage 为各个线程做引擎层的事务commit(这里不用写redo log,在prepare阶段已写)。
每个stage同时只有一个线程在操作。(分成三个阶段,每个阶段的任务分配给一个专门的线程,这是典型的并发优化)
这种实现的优势在于三个阶段可以并发执行,从而提升效率。注意:prepare阶段没有变,还是write/sync redo log。
(另外:5.7中引入了MTS:多线程slave复制,也是通过binlog组提交实现的,在binlog组提交时,给每一个组提交打上一个seqno,然后在slave中就可以按照master中一样按照seqno的大小顺序,进行事务组提交了。)
题外话:淘宝对binlog group commit进行了进一步的优化,从XA恢复的逻辑我们可以知道,只要保证InnoDB Prepare阶段的redo日志在写Binlog前完成write/sync即可。因此我们对Group Commit的第一个stage的逻辑做了些许修改,大概描述如下:
. InnoDB Prepare,记录当前的LSN到thd中;
. 进入Group Commit的flush stage;Leader搜集队列,同时算出队列中最大的LSN。
. 将InnoDB的redo log write/fsync到指定的LSN (注:这一步就是redo log的组写入。因为小于等于LSN的redo log被一次性写入到ib_logfile[|]) #放到flush binlog 之后
. 写Binlog并进行随后的工作(sync Binlog, InnoDB commit , etc)

也就是将 redo log的write/sync延迟到了 binlog group commit的 flush stage 之后,sync binlog之前。通过延迟写redo log的方式,显式的为redo log做了一次组写入(redo log group write),并减少了(redo log) log_sys->mutex的竞争。也就是将 binlog group commit 对应的redo log也进行了 group write. 这样binlog 和 redo log都进行了优化。

注意:当引入Group Commit后,sync_binlog的含义就变了,假定设为1000,表示的不是1000个事务后做一次fsync,而是1000个事务组。

3)相关参数:

innodb_support_xa:默认为true,表示启用XA,虽然它会导致一次额外的磁盘flush(prepare阶段flush redo log). 但是我们必须启用,而不能关闭它。因为关闭会导致binlog写入的顺序和实际的事务提交顺序不一致,会导致崩溃恢复和slave复制时发生数据错误。如果启用了log-bin参数,并且不止一个线程对数据库进行修改,那么就必须启用innodb_support_xa参数。

文档:

http://www.ywnds.com/?p=5798

http://www.ywnds.com/?p=7892

MySQL binlog 组提交与 XA(分布式事务、两阶段提交)【转】的更多相关文章

  1. 分布式事务 & 两阶段提交 & 三阶段提交

    可以参考这篇文章: http://blog.csdn.net/whycold/article/details/47702133 两阶段提交保证了分布式事务的原子性,这些子事务要么都做,要么都不做. 而 ...

  2. 聊一聊 MySQL 中的数据编辑过程中涉及的两阶段提交

    MySQL 数据库中的两阶段提交,不知道您知道不?这篇文章就简单的聊一聊 MySQL 数据库中的两阶段提交,两阶段提交发生在数据变更期间(更新.删除.新增等),两阶段提交过程中涉及到了 MySQL 数 ...

  3. 分布式事务 spring 两阶段提交 tcc

    请问分布式事务一致性与raft或paxos协议解决的一致性问题是同一回事吗? - 知乎 https://www.zhihu.com/question/275845393 分布式事务11_TCC 两阶段 ...

  4. 分布式事务、XA、两阶段提交、一阶段提交

    本文原文连接:http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处! 1.XA XA是由X/Open组织提出的分布式事务的规范 ...

  5. 分布式事务(一)两阶段提交及JTA

    原创文章,同步发自作者个人博客 http://www.jasongj.com/big_data/two_phase_commit/ 分布式事务 分布式事务简介 分布式事务是指会涉及到操作多个数据库(或 ...

  6. 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究 转载

    1.XA XA是由X/Open组织提出的分布式事务的规范.XA规范主要定义了(全局)事务管理器(Transaction Manager)和(局部)资源管理器(Resource Manager)之间的接 ...

  7. XA: 事务和两阶段提交

    本文原文连接:http://blog.csdn.net/bluishglc/article/details/7612811 ,转载请注明出处! 1.XA XA是由X/Open组织提出的两阶段提交协议, ...

  8. 全网最牛X的!!! MySQL两阶段提交串讲

    目录 一.吹个牛 二.事务及它的特性 三.简单看下两阶段提交的流程 四.两阶段写日志用意? 五.加餐:sync_binlog = 1 问题 六.如何判断binlog和redolog是否达成了一致 七. ...

  9. 两阶段提交及JTA

    两阶段提交及JTA 分布式事务 分布式事务简介 分布式事务是指会涉及到操作多个数据库(或者提供事务语义的系统,如JMS)的事务.其实就是将对同一数据库事务的概念扩大到了对多个数据库的事务.目的是为了保 ...

随机推荐

  1. firefox的plugin-container.exe进程如何关闭?

    为什么要关闭container进程? 查看firefox所消耗的资源: ff本身: cpu一般是0-10%, 内存一般是400MB左右 plugin-container: cpu所占的比例很高, 可达 ...

  2. linux网络:常用命令(二)

    1.ping命令:与Windows下基本功能一样但也有所区别 1.命令格式: ping [选项] ip地址或域名主机等 选项 -c 加次数 -d 使用Socket的SO_DEBUG功能. -f 极限检 ...

  3. JMS基本概念和模型

    ------------------------------------------------------------------------------------------- JMS是什么 J ...

  4. jQuery源码-dom操作之jQuery.fn.html

    写在前面 前面陆陆续续写了jQuery源码的一些分析,尽可能地想要cover里面的源码细节,结果导致进度有些缓慢.jQuery的源码本来就比较晦涩,里面还有很多为了解决兼容问题很引入的神代码,如果不g ...

  5. CSS浮动属性Float介绍

    #cnblogs_post_body h6 {font-size: 16px;font-weight: bold;} 什么是CSS Float? float 是 css 的定位属性.在传统的印刷布局中 ...

  6. PHP魔术方法以及关于独立实例与相连实例的讲解

    <?php //魔术方法 //当包含多个类 //1.自动装载类的魔术方法__autoload() function __autoload($classname){ if (isset($clas ...

  7. 我们为之奋斗过的C#之---简单的库存管理系统

    今天非常开心,因为今天终于要给大家分享一个库存管理项目了. 我个人感觉在做项目之前一定先要把逻辑思路理清,不要拿到项目就噼里啪啦的一直敲下去这样是一不好的习惯,等你做大项目的时候,你就不会去养成一种做 ...

  8. Java中String和Int的相互转换

    一.将字串 String 转换成整数 intA. 有2个方法:1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([Strin ...

  9. composer环境配置

    一 下载composer.phar http://pan.baidu.com/s/1nuDQBzz cmd命令行切换到composer.phar文件目录下 运行: echo @php "%~ ...

  10. weapp微信小程序初探demo

    https://github.com/donglegend/weapp-demo 参考文档开发工具安装微信weapp API git项目源码微信小程序 demo效果展示效果预览