MySQL XA 介绍

引言

在MySQL 5.7.7版本中,Oracle 官方将MySQL XA 一直存在的一个“bug” 进行了修复,使得MySQL XA 的实现符合了分布式事务的标准。那是否可以使用MySQL XA 让MySQL 具有分布式扩展的能力呢?在回答这个问题前,我们先看下MySQL XA 涉及到的相关概念。

相关概念介绍

事务:由一个有限的数据库操作序列构成,这些操作需要满足四个特性,即原子性、一致性、隔离性、持久性,简称ACID。

分布式事务:根据 Open Group 关于分布式事务的处理规范,定义了三种组件,如下图:

其中

AP

是指应用程序。

RM是资源管理器,事务的参与者,通常是数据库,比如MySQL Server。一个分布式事务通常涉及多个资源管理器。

TM是事务管理器,创建分布式事务并协调分布式事务中的各个子事务的执行和状态。子事务是指分布式事务中在RM上执行的具体操作。

两阶段提交 (Two-Phase Commit, 简称2PC) ,是为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种算法。分布式事务通常采用2PC,二阶段提交的算法思路可以概括为: 参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作,这里的参与者可以理解为RM,协调者可以理解为TM。如下图所示:

在第一阶段,TM会发送 Prepare 到所有参与分布式事务的RM询问是否可以提交操作,参与分布式事务的所有RM接收到请求,实现自身事务提交前的准备工作并返回结果。在第二阶段,根据RM返回的结果,如果涉及分布式事务的所有RM都返回可以提交,则TM给RM发送commit的命令,每个RM实现自己的提交,同时释放锁和资源,然后RM反馈提交成功,TM完成整个分布式事务;如果任何一个RM返回不能提交,则涉及分布式事务的所有RM都被告知需要回滚。MySQL XA 也是基于这个规范实现的,接下来我们介绍下MySQL XA。

MySQL XA 是什么?

MySQL XA 是基于Open Group 的<<Distributed Transaction Processing:The XA Specification>> 标准实现的,支持分布式事务,允许多个数据库实例参与一个全局的事务。MySQl XA 从MySQL 5.0 开始引入,仅innodb存储引擎支持MySQL XA事务。

MySQL XA 的命令集合如下:

XA START xid: 开启一个事务,并将事务置于ACTIVE状态,此后执行的SQL语句都将置于该是事务中。

XA END xid: 将事务置于IDLE状态,表示事务内的SQL操作完成。

XA PREPARE xid: 实现事务提交的准备工作,事务状态置于PREPARED状态。事务如果无法完成提交前的准备操作,该语句会执行失败。

XA COMMIT xid:  事务最终提交,完成持久化。

XA ROLLBACK xid: 事务回滚终止。

XA RECOVER: 查看MySQL中存在的PREPARED状态的xa事务。

下图是XA事务状态变迁图:

从分布式事务的变迁中可以看出,有两条路径可以使事务达到提交状态,有两条路径是回滚并结束事务。我们将这四条路径进行横向对比,看看每个阶段是如何实现分布式事务的ACID特性的(相关分析是在RR隔离级别下进行的,暂不考虑RC隔离级别)。

如上图可以看出,

1. 当xa start开启事务后,DML也会在对应的RM上创建undo以及read view(该read view是instance级别的)。

2. 当xa prepare 时会将子事务置于PREPARED状态,此时子事务已经完成事务提交前的所有准备工作(获得锁,并将PREPARED状态记录到共享表空间中,会将xa start到xa end之间操作记录在binlog中)。

3. 当xa commit 时会在binlog中记录xa commit xid, 并将innodb中PREPARED状态转化为COMMITED状态。

4. 当xa commit one phase 时会同时进行prepare和commit 两种操作,是在TM发现全局的分布式事务只涉及一个RM时进行的(因为不需要等待其他RM的反馈结果)。

5. 当xa rollback在xa prepare前时,因为没有写binlog和redo,只会释放undo, read view以及lock。

6. 当xa rollback 在xa prepare之后时,除了需要释放undo, read view以及lock,还需要binlog中记录xa rollback xid(使得从库不会提交该事务)以及innodb中将PREPARED状态转化为ROLLBACK状态。

MySQL XA 的例子

上面介绍了MySQL XA 的原理,我们现在举几个简单的例子。

例子1,两阶段XA事务提交:

mysql> xa start 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1(id) values(1);

Query OK, 1 row affected (0.00 sec)

mysql> xa end 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

mysql> xa prepare 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

mysql> xa recover\G

formatID: 1

gtrid_length: 7

bqual_length: 0

data: mysql57

1 row in set (0.00 sec)

mysql> xa commit 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

对应的Binlog 中的记录如下:

例子2,xa commit one phase ,不需要等待其他RM反馈prepare的结果。

mysql> xa start 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1(id) values(2);

Query OK, 1 row affected (0.00 sec)

mysql> xa end 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

mysql> xa commit 'mysql57xa' one phase;

Query OK, 0 rows affected (0.00 sec)

对应的Binlog 中的记录如下:

例子3,在xa prepare后,执行xa rollback 回滚事务。

mysql> xa start 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1(id) values(3);

Query OK, 1 row affected (0.00 sec)

mysql> xa end 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

mysql> xa prepare 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

mysql> xa rollback 'mysql57xa';

Query OK, 0 rows affected (0.00 sec)

对应的Binlog 中的记录如下:

MySQL XA 的限制

在MySQL 5.7.7 之前,MySQL一直存在一个"bug"。在事务达到PREPARED状态后,客户端断开与MySQL的连接,MySQL 会自动回滚该事务,这个行为不符合分布式事务的规范,MySQL将PREPARED的事务丢失了。之所以MySQL这么实现是因为MySQL 5.7.7 之前PREPARED的事务并不会记录到binlog中。客户端退出后会丢失该信息,如果允许再提交,那么binlog缺少事务信息,会造成主从不一致。

在MySQL 5.7.7 之后,MySQL 新增了一个XA_prepare_log_event的事件,会把xa start到xa prepare中间的操作记录到Binlog中。Slave读取Relay log 进行回放,当SQL Thread读取到PREPARED的事务后,在读取xa commit或者xa rollback前,会进行一个类似客户端断开的操作,继续读取后续的事务信息,不会阻塞SQL Thread的执行。从以上的结果看,Oracle在MySQL 5.7.7 上确实完美的解决了MySQL XA一直存在的一个"bug"。

MySQL XA 的实践

本人曾在某公司的分布式数据库项目组中实践过基于MySQL XA的分布式事务。MySQL XA 要满足线上高并发的访问要求,在使用时还需要解决两个问题:分布式死锁问题和分布式读一致性问题。分布式死锁问题是指MySQL Server 是可以检测和解决单个MySQL实例中的死锁问题,但涉及到跨越多个MySQL 实例的分布式事务时候,需要程序层面实现死锁的检测和解决。分布式读一致性问题是指MySQL的read view 也是实例级别的,对于全局分布式事务来说无法实现读一致,只能通过select ... lock in share mode在读请求上加锁的串行化隔离级别来实现,这必然会带来并发性能的下降。这就需要在程序层面构建全局的read view来实现全局的MVCC 。当然这两个问题,当时团队的大牛们都已经解决了,我也很有幸参与其中。

本人水平有限,描述有误或是不准确的地方,请大家多多指教。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 什么是数据库? 数据库是存储数据的集合的单独的应用程序。每个数据库具有一个或多个不同的API,用于创建,访问,管理...
    chen_000阅读 4,005评论 0 19
  • 线上一个5.7从库复制中断: 查询具体报错: 第一感觉很奇怪,为什么会rollback失败呢?于是根据gtid去对...
    小卢二阅读 4,690评论 5 1
  • Mysql 有4种类型的日志:Error Log、Genaral Query Log、 Binary Log 和 ...
    人在码途阅读 16,287评论 2 11
  • 最近在一群辣眼睛玄幻剧当道的晚暑期档中,我突然发现了一股清流——简单不做作的《小别离》。 第一次听朋友说在看《小别...
    念念云耳阅读 14,421评论 10 40
  • 今天是正月十五,元宵节,本来对这个节日没有什么感觉,可就在刚才,看见家庭群里公公发的在外面散步的视频,忽然有些伤感...
    我的春夏秋冬阅读 91评论 0 1