共计 7597 个字符,预计需要花费 19 分钟才能阅读完成。
这篇文章主要为大家展示了“MySQL 5.7 中对 XA 支持的改进有哪些”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让丸趣 TV 小编带领大家一起研究并学习一下“MySQL 5.7 中对 XA 支持的改进有哪些”这篇文章吧。
背景
XA 解决了当跨分布式资源情况下能在单个事务中保留 ACID 属性的问题。资源本身可以是其他 MySQL 服务器,甚至可以其他是不同的数据库技术。XA 标准描述了全局事务管理器和本地资源管理器之间的交互。
如引言中所述,MySQL 5.0 引入了 XA 支持,从而增加了参与全局事务的能力。XA 支持可以提供可访问事务资源的资源管理器和能够在全局事务中协调事务的事务管理器。MySQL 的 XA 实现了让 MySQL 服务器来充当资源管理器,而连接到 MySQL 服务器的客户端执行事务管理器的任务。
XA 使用两阶段提交协议,其中第一阶段是发出 commit 请求,然后再进行实际的 commit。全局事务的各个分支完成执行后,将启动两阶段提交协议:
在第一阶段,事务管理器向全局事务中涉及的所有分支发出准备 commit 的消息。在资源管理器确认已准备好提交之前,它会将操作的记录结果记录并保存,为第二阶段执行实际的提交做准备。
在第二阶段,事务管理器如果从所有涉及的分支接收到确定的响应,则通知它们提交。但是,如果任何一个分支的答复为否,则会通知所有分支执行回滚。
一个事务管理器与多个资源管理器进行交互,以处理全局事务中的单个事务 / 分支。以下图描述了涉及一个资源管理器中的 XA 事务。XA 事务的语句以 XA 关键字,要执行的操作和唯一标识符开头。在下面的示例中,字符串“xatest”表示全局事务标识符。除了全局事务标识符之外,还可以为 XA 事务指定分支标识符和格式 ID。分支标识符用于标识本地事务,格式 ID 指定前两个组件使用的格式。
XA START / BEGIN 启动事务并定义其全局事务标识符。
XA END 指定活动事务的结束。
XA PREPARE 为事务的 COMMIT 做准备。
XA COMMIT [ONE PHASE] COMMIT 并结束一个已 PREPARE 的事务。
如果使用“单阶段”选项,则准备和提交将在结束事务的单个步骤中执行。
XA ROLLBACK 回滚并终止事务。
XA RECOVER 显示有关所有 PREPARED 事务的信息。
让我们看一下上述 XA 事务的状态之间转换。
XA START 将事务置于活动状态。一旦所有语句由活动事务执行后,就会发出 XA_END 语句,使该事务处于 IDLE 状态。对于空闲事务,可以发出 XA PREPARE 或 XA COMMIT ONE PHASE。XA PREPARE 将事务置于 PREPARED 状态。但是,XA COMMIT ONE PHASE 会准备并提交事务。对于 PREPARED XA 事务,将发出 XA COMMIT 提交以结束事务。
已解决主要问题。
在 5.7.7 之前,如果客户端连接终止或服务器正常退出,则回滚 PREPARED 事务。当客户端被杀死时,所有交易都会回滚。因此,即使 XA 事务处于 PREPARED 状态,它也无法在 XA RECOVER 期间恢复该事务。理想情况下,在准备事务时,应该可以提交或回滚该事务。对于这种情况,让我们看一下
错误 12161 中报告的
示例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
mysql CREATETABLEt1(fld1INT);
QueryOK, 0 rowsaffected (0.01 sec)
mysql COMMIT;
QueryOK, 0 rowsaffected (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.00 sec)
mysql INSERTINTOt1VALUES (1);
QueryOK, 1 rowaffected (0.00 sec)
mysql XAEND test
QueryOK, 0 rowsaffected (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.00 sec)
mysql Killed
Nowstartanotherclientsession.
mysql XA test
1397 (XAE04): XAER_NOTA: UnknownXID
mysql XARECOVER;
Emptyset (0.00 sec)
同样在 5.7.7 之前,如果 XA 事务处于 PREPARED 状态且服务器异常退出,则可以在重新启动服务器后恢复该事务 - 但不会复制该事务。 服务器重新启动后,XA 事务仍将以 PREPARED 状态存在,但其内容无法记录在二进制日志中。因此,二进制日志不同步,导致数据漂移。因此,XA 不能安全地用于复制。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
mysql CREATETABLEt1(fld1INT);
QueryOK, 0 rowsaffected (0.01 sec)
mysql COMMIT;
QueryOK, 0 rowsaffected (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.00 sec)
mysql INSERTINTOt1VALUES (1);
QueryOK, 1 rowaffected (0.00 sec)
mysql XAEND test
QueryOK, 0 rowsaffected (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.00 sec)
Nowkilltheserver.
mysql XARECOVER;
2006 (HY000): MySQLserverhasgoneaway
Noconnection. Tryingto reconnect…
Connectionid: 1
Currentdatabase: test
+———-+————–+————–+——+
| formatID | gtrid_length | bqual_length | data |
+———-+————–+————–+——+
| 1 | 4 | 0 | test |
+———-+————–+————–+——+
1 rowin set (0.02 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.02 sec)
mysql SHOWBINLOGEVENS\G;
*************************** 1. row ***************************
Log_name: nisha-PORTEGE-Z30-A-bin.000001
Pos: 4
Event_type: Format_desc
Server_id: 1
End_log_pos: 120
Info: Serverver: 5.6.29-debug-log, Binlogver: 4
1 rowin set (0.00 sec)
mysql SELECT * FROMt1;
+——+
| fld1 |
+——+
| 1 |
+——+
1 rowin set (0.00 sec)
overcoming the above mentioned restrictions required changes in the XA transaction recovery mechanism and binary logging mechanism. This improvement was made in 5.7.7 through the implementation of work log number
7193 and
6860/
bug 12161.
The XA recovery mechansim has been extended such that when a connection is terminated, the PREPARED XA transactions are left in the transaction cache and marked specially in InnoDB. This allows the client to RECOVER the PREPARED XA transactions and then COMMIT/ ROLLBACK.
The XA transactions are now binlogged in two phases using two different GTIDs which allows the transactions to be interleaved. During the first phase, when XA PREPARE is issued, the transaction up until that point is logged in the binary log and can be identified by XA_prepare_log_event. During the second phase, when XA COMMIT/ROLLBACK is issued, the second part of the transaction is written into the binary log. Since XA PREPARE is persistent, the XA transaction is not rolled back and survives the server restart or client disconnect. The client can perform XA COMMIT/ROLLBACK and the binary log remains up to date. XA transactions also works well when GTID is ON and binary log is turned OFF.
Let us look at the output of the above examples after 5.7.7:
为了克服上述限制,需要对 XA 事务恢复机制和二进制日志记录机制进行更改。通过执行工作日志编号
7193 和
6860 /
bug 12161 在 5.7.7 中进行了改进。
XA 恢复机制已得到扩展,以便在终止连接时,将 PREPARED XA 事务保留在事务缓存中,并在 InnoDB 中进行特殊标记。这允许客户端恢复 PREPARED XA 事务,然后执行 COMMIT / ROLLBACK。
现在,使用两个不同的 GTID 在两个阶段对 XA 事务进行二进制记录,从而可以使事务交织。在第一阶段中,当发出 XA PREPARE 时,直到该点的事务都会记录在二进制日志中,并且可以通过以下方式进行标识:XA_prepare_log_event. 在第二阶段中,当发出 XA COMMIT / ROLLBACK 时,将事务的第二部分写入二进制日志。由于 XA PREPARE 是持久性的,因此 XA 事务不会回滚,并且可以在服务器重新启动或客户端断开连接后继续存在。客户端可以执行 XA COMMIT / ROLLBACK,并且二进制日志保持最新。当 GTID 设置为 ON 并且二进制日志设置为 OFF 时,XA 事务也可以很好地工作。
让我们看看 5.7.7 之后的上述示例的输出:
客户端断开连接后:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
mysql CREATETABLEt1(fld1INT);
QueryOK, 0 rowsaffected (0.01 sec)
mysql COMMIT;
QueryOK, 0 rowsaffected (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.00 sec)
mysql INSERTINTOt1VALUES (1);
QueryOK, 1 rowaffected (0.00 sec)
mysql XAEND test
QueryOK, 0 rowsaffected (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.00 sec)
mysql Killed
Nowstartanotherclientsession.
mysql XARECOVER;
+———-+————–+————–+——+
| formatID | gtrid_length | bqual_length | data |
+———-+————–+————–+——+
| 1 | 4 | 0 | test |
+———-+————–+————–+——+
1 rowin set (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.02 sec)
服务器重启后:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
mysql CREATETABLEt1(fld1INT);
QueryOK, 0 rowsaffected (0.01 sec)
mysql COMMIT;
QueryOK, 0 rowsaffected (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.00 sec)
mysql INSERTINTOt1VALUES (1);
QueryOK, 1 rowaffected (0.00 sec)
mysql XAEND test
QueryOK, 0 rowsaffected (0.00 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.00 sec)
Nowkilltheserver.
mysql XARECOVER;
2006 (HY000): MySQLserverhasgoneaway
Noconnection. Tryingto reconnect…
Connectionid: 1
Currentdatabase: test
+———-+————–+————–+——+
| formatID | gtrid_length | bqual_length | data |
+———-+————–+————–+——+
| 1 | 4 | 0 | test |
+———-+————–+————–+——+
1 rowin set (0.02 sec)
mysql XA test
QueryOK, 0 rowsaffected (0.02 sec)
mysql SHOWBINLOGevents\G;
*************************** 3. row ***************************
Log_name: nisha-PORTEGE-Z30-A-bin.000001
Pos: 154
Event_type: Anonymous_Gtid
Server_id: 0
End_log_pos: 219
Info: @@SESSION.GTID_NEXT= ANONYMOUS
*************************** 4. row ***************************
Log_name: nisha-PORTEGE-Z30-A-bin.000001
Pos: 219
Event_type: Query
Server_id: 0
End_log_pos: 319
Info: XA 74657374 , ,1
*************************** 5. row ***************************
Log_name: nisha-PORTEGE-Z30-A-bin.000001
Pos: 319
Event_type: Query
Server_id: 0
End_log_pos: 418
Info: use `test`; INSERTINTOt1VALUES (1)
*************************** 6. row ***************************
Log_name: nisha-PORTEGE-Z30-A-bin.000001
Pos: 418
Event_type: Query
Server_id: 0
End_log_pos: 509
Info: XAEND 74657374 , ,1
*************************** 7. row ***************************
Log_name: nisha-PORTEGE-Z30-A-bin.000001
Pos: 509
Event_type: XA_prepare
Server_id: 0
End_log_pos: 549
Info: XA 74657374 , ,1
*************************** 8. row ***************************
Log_name: nisha-PORTEGE-Z30-A-bin.000002
Pos: 219
Event_type: Server_id: 0
End_log_pos: 313
Info: XA 74657374 , ,1
8 rowsin set (0.00 sec)
以上是“MySQL 5.7 中对 XA 支持的改进有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!