MySQL 5.7中对XA支持的改进
介绍
XA的意思为“eXtended Architecture”,是The Open Group组织为分布式事务处理创建的标准。虽然MySQL 5.0是第一个支持XA的版本,但MySQL 5.7提升了XA支持的可靠性,修复了许多错误,并增加了整体测试用例覆盖率。
背景
XA解决了在分布式资源集中的单个事务中保留ACID属性的问题。资源本身可以是其他MySQL服务器,甚至是不同的数据库技术。XA的标准描述了全局事务管理器和本地资源管理器之间的交互。
正如在上面提到的,MySQL 5.0引入了XA支持,从而增加了参与全局事务的能力。XA需要一个资源管理器,它提供了对事务资源的访问,还需要一个事务管理器来协调全局事务中的事务。MySQL的XA实现使MySQL服务器能够充当资源管理器,而连接到MySQL服务器的客户端则执行事务管理器的任务。
XA使用两阶段提交协议,其中第一阶段是提交请求,然后是实际提交。一旦全局事务的各个分支完成执行,两阶段提交协议就会启动:
- 在第一阶段,事务管理器发布准备提交消息给全局事务中涉及的所有分支。在资源管理器确认它已准备好提交之前,它会将操作结果记录在日志中,以便在第二阶段执行实际提交。
- 在第二阶段,事务管理器如果收到来自所有相关分支的肯定响应,则通知他们提交。但是,如果任何分支机构以失败方式回复,则会通知所有分支回滚。
事务管理器与多个资源管理器交互以处理全局事务中的各个事务/分支。该图描绘了涉及一个资源管理器的XA事务。XA事务的语句以XA关键字,要执行的操作和唯一标识符开头。在下面的示例中,字符串’xatest’表示全局事务标识符。除了全局事务标识符之外,还可以为XA事务指定分支标识符和格式ID。分支标识符用于标识本地事务,格式ID指定前两个组件使用的格式。
- XA START / BEGIN 启动一个事务并定义其全局事务标识符。
- XA END 指定活动事务的结束。
- XA PREPARE 准备事务以进行提交。
- XA COMMIT [ONE PHASE] 提交并终止PREPARED的事务。
- 如果是ONE PHASE选项,则在单步结束事务中执行准备和提交。
- XA ROLLBACK 回滚并终止事务。
- XA RECOVER 显示有关所有PREPARED事务的信息。
让我们看一下上述XA事务的状态转换。
XA START将事务置于ACTIVE状态。一旦所有语句都由活动事务执行,就会发出XA_END语句,使事务处于IDLE状态。
对于IDLE事务,可以发出XA PREPARE或XA COMMIT ONE PHASE。
XA PREPARE将事务置于PREPARED状态。而XA COMMIT ONE PHASE准备并提交交易。
对于PREPARED XA事务,发出XA COMMIT以提交结束事务。
主要的改进地方
在5.7.7之前,如果客户端连接已终止或服务器正常退出,则回滚PREPARED事务。当客户端被Kill时,所有事务都被回滚。因此,即使XA事务处于PREPARED状态,它也无法在XA RECOVER期间恢复事务。理想情况下,当事务是PREPARED时,应该可以COMMIT或ROLLBACK事务。对于这种情况,可参看下列示例:
mysql> CREATE TABLE t1(fld1 INT);
Query OK, 0 rows affected (0.01 sec)mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)mysql> XA START 'test';
Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO t1 VALUES (1);
Query OK, 1 row affected (0.00 sec)mysql> XA END 'test';
Query OK, 0 rows affected (0.00 sec)mysql> XA PREPARE 'test';
Query OK, 0 rows affected (0.00 sec)mysql> KilledNow start another client session. mysql> XA COMMIT 'test';
ERROR 1397 (XAE04): XAER_NOTA: Unknown XIDmysql> XA RECOVER;
Empty set (0.00 sec)
同样在5.7.7之前,如果XA事务处于PREPARED状态并且服务器异常退出,则可以在重新启动服务器后恢复事务 - 但是它没有被复制。 服务器重启后,XA事务仍然存在于PREPARED状态,但内容无法记录在二进制日志中。因此,二进制日志不同步导致数据漂移。因此,XA无法安全地用于复制。
ql> CREATE TABLE t1(fld1 INT);
Query OK, 0 rows affected (0.01 sec)mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)mysql> XA START 'test';
Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO t1 VALUES (1);
Query OK, 1 row affected (0.00 sec)mysql> XA END 'test';
Query OK, 0 rows affected (0.00 sec)mysql> XA PREPARE 'test';
Query OK, 0 rows affected (0.00 sec)Now kill the server.mysql> XA RECOVER;ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 1
Current database: test+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
| 1 | 4 | 0 | test |
+----------+--------------+--------------+------+
1 row in set (0.02 sec)mysql> XA COMMIT 'test';
Query OK, 0 rows affected (0.02 sec)mysql> SHOW BINLOG EVENS\G;
*************************** 1. row ***************************Log_name: nisha-PORTEGE-Z30-A-bin.000001Pos: 4Event_type: Format_descServer_id: 1End_log_pos: 120Info: Server ver: 5.6.29-debug-log, Binlog ver: 4
1 row in set (0.00 sec)mysql> SELECT * FROM t1;
+------+
| fld1 |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
克服上述限制需要更改XA事务恢复机制和二进制日志记录机制。在5.7.7中进行了这种改进。
- XA恢复机制已经扩展,当连接终止时,PREPARED XA事务将保留在事务高速缓存中,并在InnoDB中进行特殊标记。这允许客户端恢复PREPARED XA事务,然后是COMMIT / ROLLBACK。
- XA事务现在使用两个不同的GTID分两个阶段进行二进制记录,这两个GTID允许事务交错。在第一阶段,当发布XA PREPARE时,直到该点的事务被记录在二进制日志中并且可以通过XA_prepare_log_event. 在第二阶段识别在发出XA COMMIT / ROLLBACK时,事务的第二部分被写入二进制日志。由于XA PREPARE是持久的,因此XA事务不会回滚,并且在服务器重新启动或客户端断开连接后仍然存在。客户端可以执行XA COMMIT / ROLLBACK,二进制日志保持最新。当GTID为ON且二进制日志关闭时,XA事务也可以正常工作。
让我们看看5.7.7之后的上述例子的输出:
客户端断开连接后:
l> CREATE TABLE t1(fld1 INT);
Query OK, 0 rows affected (0.01 sec)mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)mysql> XA START 'test';
Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO t1 VALUES (1);
Query OK, 1 row affected (0.00 sec)mysql> XA END 'test';
Query OK, 0 rows affected (0.00 sec)mysql> XA PREPARE 'test';
Query OK, 0 rows affected (0.00 sec)mysql> KilledNow start another client session. mysql> XA RECOVER;
+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
| 1 | 4 | 0 | test |
+----------+--------------+--------------+------+
1 row in set (0.00 sec)mysql> XA COMMIT 'test';
Query OK, 0 rows affected (0.02 sec)
服务器重启后:
ql> CREATE TABLE t1(fld1 INT);
Query OK, 0 rows affected (0.01 sec)mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)mysql> XA START 'test';
Query OK, 0 rows affected (0.00 sec)mysql> INSERT INTO t1 VALUES (1);
Query OK, 1 row affected (0.00 sec)mysql> XA END 'test';
Query OK, 0 rows affected (0.00 sec)mysql> XA PREPARE 'test';
Query OK, 0 rows affected (0.00 sec)Now kill the server.mysql> XA RECOVER;ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 1
Current database: test+----------+--------------+--------------+------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+------+
| 1 | 4 | 0 | test |
+----------+--------------+--------------+------+
1 row in set (0.02 sec)mysql> XA COMMIT 'test';
Query OK, 0 rows affected (0.02 sec)mysql> SHOW BINLOG events\G;
*************************** 3. row ***************************Log_name: nisha-PORTEGE-Z30-A-bin.000001Pos: 154Event_type: Anonymous_GtidServer_id: 0
End_log_pos: 219Info: SET @@SESSION.GTID_NEXT= 'ANONYMOUS'
*************************** 4. row ***************************Log_name: nisha-PORTEGE-Z30-A-bin.000001Pos: 219Event_type: QueryServer_id: 0
End_log_pos: 319Info: XA START X'74657374',X'',1
*************************** 5. row ***************************Log_name: nisha-PORTEGE-Z30-A-bin.000001Pos: 319Event_type: QueryServer_id: 0
End_log_pos: 418Info: use `test`; INSERT INTO t1 VALUES (1)
*************************** 6. row ***************************Log_name: nisha-PORTEGE-Z30-A-bin.000001Pos: 418Event_type: QueryServer_id: 0
End_log_pos: 509Info: XA END X'74657374',X'',1
*************************** 7. row ***************************Log_name: nisha-PORTEGE-Z30-A-bin.000001Pos: 509Event_type: XA_prepareServer_id: 0
End_log_pos: 549Info: XA PREPARE X'74657374',X'',1
*************************** 8. row ***************************Log_name: nisha-PORTEGE-Z30-A-bin.000002Pos: 219Event_type: QueryServer_id: 0
End_log_pos: 313Info: XA COMMIT X'74657374',X'',1
8 rows in set (0.00 sec)
结论
MySQL 5.7中极大地改进了对XA的支持,并使实现XA JOIN / XA RESUME操作成为可能。期待看到它在分布式系统中的使用。
MySQL 5.7中对XA支持的改进相关推荐
- mysql xa 和普通事务_一文看懂MySQL中基于XA实现的分布式事务
概述 前面已经介绍了2PC和3PC方面的内容,那么MySQL数据库在分布式事务这块又是怎么规划呢? XA事务简介 XA 事务的基础是两阶段提交协议.需要有一个事务协调者来保证所有的事务参与者都完成了准 ...
- MySQL中基于XA实现的分布式事务
文章目录 一.前言 二.XA基础 2.1 XA基础知识 2.1.1 DTP是什么? 2.1.2 DTP的结构:AP TM RM(重点001) 2.1.3 DTP的重要概念 2.2 XA事务:基于两阶段 ...
- MySQL 中基于 XA 实现的分布式事务
五.MySQL 中基于 XA 实现的分布式事务 5.1 XA协议 首先我们来简要看下分布式事务处理的XA规范 可知XA规范中分布式事务有AP,RM,TM组成: 其中应用程序(Application P ...
- mysql存储引擎中INNODB和MyISAM的区别
切记:存储引擎是基于表的,而不是数据库. 存储引擎概念: MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不 ...
- dbv mysql_MariaDB与MySQL对比 --- 对分布式事务的支持
本文最初于2016年底发表在我的个人微信公众号里面,现略有修订后发布在这里.本文的技术信息针对的是mysql-5.7.x和mariadb-10.1.9. MariaDB和MySQL两者对分布式事务的支 ...
- MySQL 5.7中的新功能
本节总结了MySQL 5.7中添加,弃用和删除的内容.随附部分列出了MySQL服务器选项以及在MySQL 5.7中添加,弃用或删除的变量.请参见第1.5节"在MySQL 5.7中添加,弃用或 ...
- mysql 执行cmd,mysql命令行中执行sql的几种方式总结
1.直接输入sql执行 MySQL> select now(); +---------------------+ | now() | +---------------------+ | 2013 ...
- MySQL 5.7中的更多改进,包括计算列
让我们继续上一周的内容,讨论MySQL 5.7中的新特性,我们将把注意力集中于新的安全方面的特性.首先,新版本中取消了mysql_old_password这个认证插件.其实这个插件从版本4.x开始就已 ...
- MySQL数据库have_openss_MySQL 关于OpenSSL证书支持检查方式
1.mysql编译参数: #cat /usr/local/mysql/bin/mysqlbug|grep configure # This is set by configure CONFIGURE_ ...
最新文章
- 【专家观点】张亚勤、张宏江:人工智能的未来是什么?
- Chrome插件-新浪微博阅读器
- 台式计算机更新不了,台式机更新造成电脑关不了机怎么办
- asp.net返回值当文件下载问题
- Bootstrap按钮组中按钮的尺寸
- 常用linux网络配置命令
- Thinkphp结合phpqrcode生成二维码海报代码
- 计算机二级数据模拟表,2020年计算机二级《Access数据库程序设计》模拟题(5)...
- wps文字表格制作拼音田字格模板_手把手教你用wps表格excel制作田字格书法练习字帖...
- Object Classification Using CNN-Based Fusion of Vision and LIDAR in Autonomous Vehicle Environment
- revel MySQL_Go-Revel:Gorp连接MySQL
- 计算机的了解以及组装
- golang_逃逸分析
- ElasticSearch--Field的使用
- NotePad++7.5 64 bit版本以后没有plugin manger的解决方法
- python使用selenium启动谷歌浏览器无痕模式代码
- E: 错误,pkgProblemResolver::Resolve 发生故障,这可能是有软件包被要求保持现状的缘故。
- Facebook个人账号相关问题?
- SAP-READ语句
- 大家好,我是区块链本人。今天,我要给你们介绍我的家族。