暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

MySQL 中的 XA 事务故障排除

原创 黎青峰 2022-10-12
552

这是与 XA 事务相关的令人兴奋的故障排除之一,让我们深入探讨。首先我为大家提供一些背景知识。

对于我们的一个客户,当我们尝试删除一个表时,它正在等待元数据锁定。在调试时,其中一个 XA 事务持有共享写锁并导致所有其他本地事务上的元数据锁。

让我们从 Performance Schema 中查看元数据锁。

mysql> select OBJECT_TYPE,OBJECT_SCHEMA,OBJECT_NAME, LOCK_TYPE,LOCK_STATUS,SOURCE from performance_schema.metadata_locks\G
******************* 1. row *********************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: sbtest
OBJECT_NAME: sbtest_table1
LOCK_TYPE: SHARED_WRITE
LOCK_STATUS: GRANTED
SOURCE: xa.cc:284
******************* 2. row *********************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: sbtest
OBJECT_NAME: sbtest_table2
LOCK_TYPE: SHARED_WRITE
LOCK_STATUS: GRANTED
SOURCE: xa.cc:284
******************* 3. row *********************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: sbtest
OBJECT_NAME: sbtest_table3
LOCK_TYPE: SHARED_WRITE
LOCK_STATUS: GRANTED
SOURCE: xa.cc:284
******************* 4. row *********************
OBJECT_TYPE: TABLE
OBJECT_SCHEMA: sbtest
OBJECT_NAME: sbtest_table1
LOCK_TYPE: EXCLUSIVE
LOCK_STATUS: PENDING
SOURCE: xa.cc:284

到底发生了什么?

在 MySQL 8.0.28 及更早版本中,XA 事务和本地(非 XA)事务是互斥的。 (8.0.29 中的 XA 更改)例如,如果已发出 XA START 以开始 XA 事务,则在提交或回滚 XA 事务之前无法启动本地事务。在我们的例子中,XA 事务已经处于 PREPARED 状态(既没有提交也没有回滚),持有锁。因此,我们试图启动的本地事务无法获取锁,因为它们是互斥的。

当事务未提交 (XA COMMIT;) 或未回滚 (XA ROLLBACK) 时,XA 事务将进入 PREPARED 状态;

XA 交易流程

image.png

我们可以从Show Engine InnoDB 状态输出中看到,事务已达到 Prepared 状态,\。

---TRANSACTION 28992918, ACTIVE (PREPARED) 1072517 sec recovered trx5 lock struct(s), heap size 1128, 0 row lock(s), undo log entries 8---TRANSACTION 234688, ACTIVE (PREPARED) 1072517 sec recovered trx3 lock struct(s), heap size 1128, 0 row lock(s), undo log entries 6---TRANSACTION 25949, ACTIVE (PREPARED) 1072517 sec recovered trx1 lock struct(s), heap size 1128, 0 row lock(s), undo log entries 1

我们可以通过运行 XA RECOVER 来获取所有 XA Prepared 事务的列表;要提交或回滚这些 XA 事务,我们需要知道每个 XA 事务的 XID

mysql> XA 恢复;
+------------+--------------+--------------+-------- --------------------------------------------------+
| 格式ID | gtrid_length | bqual_length | 数据 |                                       
+------------+--------------+--------------+-------- --------------------------------------------------+
| 1 | 38 | 1 | 3d36dccd-61d0-4ae1-9b39-f9ccc2400d44:44 |
| 1 | 39 | 2 | 11740f2a-8a85-4b33-b924-982c1539d197:2222 |
| 1 | 41 | 4 |0d0afb17-c480-4a30-88c0-907b20794d13:10011001 |
+------------+--------------+--------------+-------- --------------------------------------------------+

我们是如何解决这个问题的

我们已经知道,每个 XA 事务都以 XA 关键字开头,后跟 XID。XID 是 XA 事务标识符。一个 XID 值包含一到三个部分:

  • Gtrid 是一个全局事务标识符。
  • Bqual是一个分支限定符。
  • FormatID是一个数字,用于标识 gtrid 和 bqual 值使用的格式。
  • 对于全局事务中的每个 XA 事务,XID 值的 bqual 部分必须不同。
mysql> xa 恢复转换 xid;
+------------+--------------+--------------+-------- ---------------------------------------------+
| 格式ID | gtrid_length | bqual_length | 数据 |                                                        
+------------+--------------+--------------+-------- ---------------------------------------------+
| 1 | 6 | 2 | 0x1A64306166623137 |
| 1 | 7 | 4 | 0x31313734306632612D3861 | +------------+--------------+--------------+-------- ---------------------------------------------+
3 行一组(0.00 秒)

上面的“ XA RECOVER CONVERT XID ”给出了十六进制值的XID值。gtrid_length 和 bqual_length 字段告诉我们开始和停止的位置。我们需要以字节为单位的 gtrid_length 和以字节为单位的 bqual_length 并分离出这些值。

让我们从上面的输出中获取数据列值。让我们根据 gtrid_length(给出为 6)和 bqual_length(显示为 2)值将值拆分为字节。

由于“1A”是单个字节,请记住这一点,我们需要拆分数据值。

    0x 1A6430616662 3137

Gtrid_length - 6     == > (1A 64 30 61 66 62)
Bqual_length - 2   == > (31 37)

让我们现在尝试提交事务

mysql>XA COMMIT X’1A6430616662’,X’3137’,1;
Query OK, 0 rows affected (0.03 sec)

其中 1 是格式标识符

现在让我们进行第二次交易。基于给定的gtrid_length和bqual_length值,我们正在拆分数据值。

      0x 31313734306632 612D3861 

Gtrid_length - 7    == > (31 31 37 34 30 66 32)
Bqual_length - 4  == > (61 2D 38 61)
mysql>XA COMMIT X’31313734306632’,X’612D3861’,1
Query OK, 0 rows affected (0.03 sec)

在这里,“1”是格式标识符

关键信息

这样,从 XA RECOVER CONVERT XID 输出中,我们将能够获得任何处于准备状态的 XA 事务的 XID,并且我们可以根据我们的要求提交/回滚它。

为这次故障排除感到开心!

原文标题:Troubleshooting XA transactions in MySQL
原文作者:paulinjeyapriya
原文地址:https://mydbops.wordpress.com/2022/09/12/troubleshooting-xa-transaction-in-mysql/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论