博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL binlog 组提交与 XA(分布式事务、两阶段提交)【转】
阅读量:5991 次
发布时间:2019-06-20

本文共 3529 字,大约阅读时间需要 11 分钟。

概念:

      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不作任何操作;第二阶段:包含两步,1> write/sync Binlog; 2> InnoDB commit (写入COMMIT标记后释放prepare_commit_mutex);以binlog 的写入与否作为事务提交成功与否的标志,innodb commit标志并不是事务成功与否的标志。 此时的事务崩溃恢复过程如下:1> 崩溃恢复时,扫描最后一个Binlog文件,提取其中的xid; 2> 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事务存在于binlogInnoDB存储引擎之间,从而保证了主从环境的数据一致性。

2)binlog 组提交:

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

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

1> flush stage 将各个线程的binlog从cache写到文件中; 2> sync stage 对binlog做fsync操作(如果需要的话;最重要的就是这一步,对多个线程的binlog合并写入磁盘);3> 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的逻辑做了些许修改,大概描述如下:
1. InnoDB Prepare,记录当前的LSN到thd中; 2. 进入Group Commit的flush stage;Leader搜集队列,同时算出队列中最大的LSN。 3. 将InnoDB的redo log write/fsync到指定的LSN  (注:这一步就是redo log的组写入。因为小于等于LSN的redo log被一次性写入到ib_logfile[0|1]) #放到flush binlog 之后4. 写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)相关参数:

默认为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 

转载地址:http://eetlx.baihongyu.com/

你可能感兴趣的文章
CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins
查看>>
Codeforces Round #411 (Div. 2)(A,B,C,D 四水题)
查看>>
Android 程序申请权限小知识点
查看>>
惑不惑
查看>>
chrome,opera..通过file协议浏览html代码时,发送的ajax请求本地文件,会报跨域错误...
查看>>
python+soket实现UDP协议的客户/服务端中文聊天程序
查看>>
PHP 高效分布代码转的
查看>>
微信小程序开发视频教程新鲜出炉
查看>>
查找表中的重复行
查看>>
全球晶圆产能排名:台积电仅次三星
查看>>
如何进行需求矩阵管理
查看>>
炒作?迪士尼否认《加勒比海盗5》被黑客窃取
查看>>
提高信息安全意识 对网络勒索病毒说不
查看>>
这样的开源应用你相信它吗?
查看>>
《Web前端工程师修炼之道(原书第4版)》——网页结构
查看>>
《Cisco QoS认证考试指南(第2版)》——6.1节“我已经知道了吗?”测试
查看>>
《BackTrack 5 Cookbook中文版——渗透测试实用技巧荟萃》—第3章3.5节扫描开放端口...
查看>>
《金蝶ERP-K/3模拟实战——财务/供应链/生产制造(第2版)》——第1章 金蝶ERP-K/3介绍 1.1 金蝶ERP-K/3系统介绍...
查看>>
SVN中文版客户端下载安装
查看>>
Clojure:让我兴奋的编程语言
查看>>