本文最初于2016年底发表在我的个人微信公众号里面,现略有修订后发布在这里。本文的技术信息针对的是mysql-5.7.x和mariadb-10.1.9。

MariaDB和MySQL两者对分布式事务的支持有所不同,总的来说MySQL的支持更好,是完备的和可靠的(尽管后来也陆续发现了不少bug),而MariaDB的支持还有诸多问题,先举例说明。

本文测试用例使用MySQL-5.7.16和MariaDB-10.1.9 进行测试。

MySQL/MariaDB对分布式事务的支持是根据 X/Open CAE document Distributed Transaction Processing: The XA Specification (http://www.opengroup.org/public/pubs/catalog/c193.htm) ,主要包括下面这几个语句:

xa start 'gtid';

xa end 'gtid';

xa prepare 'gtid';

xa commit 'gtid';

xa rollback 'gtid';

xa recover;

外部的分布式事务管理器(transaction manager, TM) 可以使用这套XA命令来操作mysql 数据库,按照XA标准的两阶段提交算法(2PC) 完成分布式事务提交。各个语句的意义见官方文档。

其中mariadb的问题在于 xa prepare 'gtid' 之后,这个事务分支(transaction branch) 可能会丢失。详见下文。

事先创建1个简单的表并且插入4行数据:

create table t1(a int primary key);

insert into t1 values(1),(2),(3),(4);

一。两者的公共行为(相同点)

本节的查询是要说明,xa prepare之前(无论是xa end 之前还是之后),xa事务的改动对外部不可见,也不持久化,退出连接就会丢失修改。xa事务信息本身也会在退出连接后消失,重新连接后xa recover不会显示它。

这些行为mysql与mariadb相同,都是正确的。

mysql> use test;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

mysql> xa start '124';

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(5);

Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values(6);

Query OK, 1 row affected (0.00 sec)

mysql> quit;

Bye

david@david-VirtualBox:~/mysql_installs/mysql-5.7.16$ ./bin/mysql -S ../../mysql-instances/a/mysql.sock

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 5

Server version: 5.7.16-debug-log Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> xa recover;

Empty set (0.00 sec)

mysql> use test;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

mysql> xa start '124';

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(5);

Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values(6);

Query OK, 1 row affected (0.00 sec)

mysql> xa end '124';

Query OK, 0 rows affected (0.00 sec)

mysql> quit;

Bye

david@david-VirtualBox:~/mysql_installs/mysql-5.7.16$ ./bin/mysql -S ../../mysql-instances/a/mysql.sock

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 6

Server version: 5.7.16-debug-log Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> xa recover;

Empty set (0.00 sec)

mysql> select*from t1;

ERROR 1046 (3D000): No database selected

mysql> use test;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

mysql> select*from t1;

+------+

| a |

+------+

| 1 |

| 2 |

| 3 |

| 4 |

+------+

4 rows in set (0.00 sec)

二。MySQL的XA PREPARE 的行为

1. 对MySQL来说,在一个事务中执行xa prepare之后退出连接,xa事务不丢失,它的更新也不会丢失。

mysql> create table t1(a int);

Query OK, 0 rows affected (0.05 sec)

mysql> xa start '123';

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(1),(2);

Query OK, 2 rows affected (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 0

mysql> insert into t1 values(3),(4);

Query OK, 2 rows affected (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 0

mysql> xa end '123';

Query OK, 0 rows affected (0.00 sec)

mysql> xa prepare '123';

Query OK, 0 rows affected (0.07 sec)

mysql> quit;

Bye

david@david-VirtualBox:~/mysql_installs/mysql-5.7.16$ ./bin/mysql -S ../../mysql-instances/a/mysql.sock

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 4

Server version: 5.7.16-debug-log Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> xa recover;

+----------+--------------+--------------+------+

| formatID | gtrid_length | bqual_length | data |

+----------+--------------+--------------+------+

| 1 | 3 | 0 | 123 |

+----------+--------------+--------------+------+

1 row in set (0.00 sec)

mysql> xa commit '123';

Query OK, 0 rows affected (0.01 sec)

mysql> select*From test.t1;

+------+

| a |

+------+

| 1 |

| 2 |

| 3 |

| 4 |

+------+

4 rows in set (0.00 sec)

2. 对mysql来说,在一个事务中执行xa prepare后,kill掉 mysqld ,xa 事务的改动及其元数据不丢失,mysql binlog系统与innodb做了协调一致的事务恢复,非常完美。重启mysqld后,客户端连接上去,执行xa recover可以看到这个prepared事务,执行 xa commit 可以完成该事务的提交。

mysql> xa start '124';

Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values(5);

Query OK, 1 row affected (0.00 sec)

mysql> insert into t1 values(6);

Query OK, 1 row affected (0.00 sec)

mysql> xa end '124';

Query OK, 0 rows affected (0.00 sec)

mysql> xa prepare '124';

Query OK, 0 rows affected (0.00 sec)

mysql> quit;

Bye

david@david-VirtualBox:~/mysql_installs/mysql-5.7.16$ ./bin/mysql -S ../../mysql-instances/a/mysql.sock

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 7

Server version: 5.7.16-debug-log Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> xa recover;

+----------+--------------+--------------+------+

| formatID | gtrid_length | bqual_length | data |

+----------+--------------+--------------+------+

| 1 | 3 | 0 | 124 |

+----------+--------------+--------------+------+

1 row in set (0.00 sec)

mysql> quit

Bye

[1]+ Killed ./bin/mysqld_safe --defaults-file=../../mysql-instances/a/my.cnf

david@david-VirtualBox:~/mysql_installs/mysql-5.7.16$ ./bin/mysqld_safe --defaults-file=../../mysql-instances/a/my.cnf &

[1] 22109

david@david-VirtualBox:~/mysql_installs/mysql-5.7.16$ 2016-12-02T06:53:49.336023Z mysqld_safe Logging to '/home/david/mysql-instances/a/datadir/david-VirtualBox.err'.

2016-12-02T06:53:49.350561Z mysqld_safe Starting mysqld daemon with databases from /home/david/mysql-instances/a/datadir

david@david-VirtualBox:~/mysql_installs/mysql-5.7.16$ ./bin/mysql -S ../../mysql-instances/a/mysql.sock

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 2

Server version: 5.7.16-debug-log Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> xa recover;

+----------+--------------+--------------+------+

| formatID | gtrid_length | bqual_length | data |

+----------+--------------+--------------+------+

| 1 | 3 | 0 | 124 |

+----------+--------------+--------------+------+

1 row in set (0.00 sec)

mysql> select*from t1;

ERROR 1046 (3D000): No database selected

mysql> use test;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

Database changed

mysql> select*from t1;

+------+

| a |

+------+

| 1 |

| 2 |

| 3 |

| 4 |

+------+

4 rows in set (0.00 sec)

mysql> xa commit '124';

Query OK, 0 rows affected (0.00 sec)

mysql> select*from t1;

+------+

| a |

+------+

| 1 |

| 2 |

| 3 |

| 4 |

| 5 |

| 6 |

+------+

6 rows in set (0.00 sec)

mysql>

3. mysql之所以能做到上述行为,是因为mysql在xa prepare 做了binlog刷盘,并且允许其后的xa commit被其他事务的binlog隔开。

本例中,新启动一个xa事务 T1,在xa prepare 之后,另启动一个连接在其中执行2个普通本地事务,然后再做xa commit T1,可以看到这个xa commit 的binlog与xa prepare被那两个新事务的binlog隔开了。对MySQL来说这不是问题。

三。MariaDB的XA支持

mariadb没有把xa start到xa prepare这一块操作作为一个单独的binlog事务并且在xa prepare时刻做binlog刷盘,因此xa prepare之后一旦数据库连接断开或者mysqld重启,那么binlog子系统中prepared状态的事务的binlog就消失了,但是innodb当中这个prepared事务是存在的也就是说binlog与innodb数据不一致了。

1. xa prepare 后连接断开,那么这个prepared事务就消失了,包括事务修改数据和元数据。binlog上面没有它的binlog,xa recover也不能列出这个事务。这就错的更加离谱了,可能是连接断开后mariadb把innodb中prepared的事务也回滚了。

MariaDB [(none)]> xa start '124';

Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> insert into t1 values(5);

ERROR 1046 (3D000): No database selected

MariaDB [(none)]> use test;

Database changed

MariaDB [test]> insert into t1 values(5);

Query OK, 1 row affected (0.00 sec)

MariaDB [test]> insert into t1 values(6);

Query OK, 1 row affected (0.00 sec)

MariaDB [test]> xa end '124';

Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> xa prepare '124';

Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> xa recover;

+----------+--------------+--------------+------+

| formatID | gtrid_length | bqual_length | data |

+----------+--------------+--------------+------+

| 1 | 3 | 0 | 124 |

+----------+--------------+--------------+------+

1 row in set (0.00 sec)

MariaDB [test]> quit;

Bye

[tdengine@TENCENT64 ~/davie/mysql_installs/tdsql-mariadb-10.1.9-bin-release3/install]$./jmysql.sh 6678

cmd: e

/data/6678/prod/mysql.sock

/data/home/tdengine/davie/mysql_installs/tdsql-mariadb-10.1.9-bin-release3

Welcome to the MariaDB monitor. Commands end with ; or \g.

Your MariaDB connection id is 9

Server version: 10.1.9-MariaDBV1.0R030D002-20161123-1511 Source distribution

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> xa recover;

Empty set (0.00 sec)

MariaDB [(none)]> use test;

Database changed

MariaDB [test]> select*from t1;

Empty set (0.00 sec)

MariaDB [test]>

2. xa prepare 后kill掉mysqld,那么这个prepared事务在binlog上面不存在,不过xa recover能列出这个事务,并且它的改动也存在。

在innodb当中,执行了XA PREPARE之后,这个事务已经prepare了,但是它的binlog没有写到binlog文件中。mysqld被kill掉重新拉起后,innodb做了事务恢复,所以可以看到它之前的改动;但是binlog上面却没有这个事务。不过做xa commit 却又可以提交这个事务。之后,这个事务的改动就可见了。但是,innodb中的数据与binlog已经不一致了。备机上面没有事务内容

MariaDB [test]> xa start '125';

Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> insert into t1 values(9);

Query OK, 1 row affected (0.00 sec)

MariaDB [test]> insert into t1 values(10);

Query OK, 1 row affected (0.00 sec)

MariaDB [test]> xa end '125';

Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> xa prepare '125';

Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> quit

Bye

[tdengine@TENCENT64 ~/davie/mysql_installs/tdsql-mariadb-10.1.9-bin-release3/install]$./jmysql.sh 6678

cmd: e

/data/6678/prod/mysql.sock

/data/home/tdengine/davie/mysql_installs/tdsql-mariadb-10.1.9-bin-release3

Welcome to the MariaDB monitor. Commands end with ; or \g.

Your MariaDB connection id is 3

Server version: 10.1.9-MariaDBV1.0R030D002-20161123-1511 Source distribution

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> xa recover;

+----------+--------------+--------------+------+

| formatID | gtrid_length | bqual_length | data |

+----------+--------------+--------------+------+

| 1 | 3 | 0 | 125 |

+----------+--------------+--------------+------+

1 row in set (0.00 sec)

MariaDB [(none)]> select*from t1;

ERROR 1046 (3D000): No database selected

MariaDB [(none)]> use test;

Database changed

MariaDB [test]> select*from t1;

+---+

| a |

+---+

| 5 |

| 6 |

| 7 |

| 8 |

+---+

4 rows in set (0.01 sec)

MariaDB [test]> xa commit '125';

Query OK, 0 rows affected (0.00 sec)

MariaDB [test]> select*from t1;

+----+

| a |

+----+

| 5 |

| 6 |

| 7 |

| 8 |

| 9 |

| 10 |

+----+

6 rows in set (0.00 sec)

MariaDB [test]>

从最初的测例开始,一直没有任何插入数据行的binlog(write_row)写入。

dbv mysql_MariaDB与MySQL对比 --- 对分布式事务的支持相关推荐

  1. mysql平台workb_MySQL分布式事务

    一.分布式事务 在说分布式事务(XA)之前,可以先看一下"以交易系统为例,看分布式事务架构的五大演进",阐述了分布式事务解决了什么问题? InnoDB存储引擎提供了对XA事务的支持 ...

  2. 深度剖析Apache Shardingsphere对分布式事务的支持

    Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由 JDBC.Proxy 和 Sidecar(规划中)这 3 款相互独立,却又能够混合部署配合使用的产 ...

  3. php mysql xa_分布式事务之——MySQL对XA事务的支持

    MySQL 从5.0.3开始支持XA分布式事务,且只有InnoDB存储引擎支持.MySQL Connector/J 从5.0.0版本之后开始直接提供对XA的支持. 需要注意的是, 在DTP模型中,my ...

  4. mysql xa 和普通事务_一文看懂MySQL中基于XA实现的分布式事务

    概述 前面已经介绍了2PC和3PC方面的内容,那么MySQL数据库在分布式事务这块又是怎么规划呢? XA事务简介 XA 事务的基础是两阶段提交协议.需要有一个事务协调者来保证所有的事务参与者都完成了准 ...

  5. 《深入理解分布式事务》第七章 XA 强一致性分布式事务原理

    <深入理解分布式事务>第七章 XA 强一致性分布式事务原理 文章目录 <深入理解分布式事务>第七章 XA 强一致性分布式事务原理 一.X/Open DTP 模型与 XA 规范 ...

  6. mysql xid原理_MySQL数据库分布式事务XA实现原理分析

    [IT168 技术]MySQL XA原理 MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨多个引擎的事务,由大家熟悉的Binlog作为协调者;外部XA用于跨多MySQL实例的分布 ...

  7. MySQL分布式事务(XA事务)

    MySQL分布式事务(XA事务) 官网:https://dev.mysql.com/doc/refman/5.7/en/xa.html 1.什么是分布式事务 分布式事务就是指事务的参与者.支持事务的服 ...

  8. mysql xa 实现_MySQL数据库分布式事务XA的实现原理分析

    1 原理 关于MySQL数据库的分布式事务XA,分布式事务实现的原理,可见[3];关于MySQL XA的说明,可见[1][2]. MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨 ...

  9. MySQL数据库分布式事务XA实现原理分析

    MySQL XA分为两类,内部XA与外部XA;内部XA用于同一实例下跨多个引擎的事务,由大家熟悉的Binlog作为协调者;外部XA用于跨多MySQL实例的分布式事务,需要应用层介入作为协调者(崩溃时的 ...

最新文章

  1. git 查看公共commit_git使用点滴:如何查看commit的内容
  2. Python面试基础题-2018-12-26
  3. 应用视觉设计_Day01
  4. MySQL 下载与配置教程(免安装版)
  5. 高等数学上-赵立军-北京大学出版社-题解-练习5.4
  6. 一百种简单整人方法_一种非常简单的用户故事方法
  7. [jQuery] jQuery与jQuery UI有啥区别?
  8. android wear 处理器,联发科推Android Wear平台可穿戴处理器
  9. 若依集成 WebSocket
  10. 大话Neo系列:Merkle Tree
  11. kubectl源码分析之config get-contexts
  12. (ICPR-2021)使用胶囊的多尺度部分表示变换的步态识别
  13. 前端开发-HTML+CSS实现京东官网左侧导航条列表
  14. 骑士精神 (迭代加深)
  15. 一文详细介绍情绪识别常用的数据集
  16. 软交换总结之二-七号信令
  17. 生活中软件易用性的例子_多用“举出例子”“比如说”,来进行生活中的语言交流...
  18. hilink互联技术_华为负重前行,打出王炸HiLink技术,引爆国内生态链格局
  19. [Excel]VLOOKUP函数使用示例
  20. 深圳软件测试培训:DOM中元素节点、属性节点、文本节点的理解

热门文章

  1. SpringBoot集成Editor.md 流程详细
  2. 系统架构设计师 - 系统可靠性设计
  3. 小程序开发(2)-之app.js、app.wxss、project.config.json说明
  4. python使用PyMysql连接MySQL实现增删改查
  5. 测试私有方法_史上最轻量!阿里开源了新型单元测试Mock工具
  6. python 判断时间是否大于6点_python中判断时间间隔的问题
  7. jq之$(“[href]“)
  8. 设置maven 参数调休_IDEA 使用 Maven构建Spark项目
  9. 在linux环境下安装wiringpi库,wiringPi库的pwm配置及使用说明
  10. html5 输入框有值无效,HTML5基础 input required 输入框内必须有内容