共計(jì) 7597 個(gè)字符,預(yù)計(jì)需要花費(fèi) 19 分鐘才能閱讀完成。
這篇文章主要為大家展示了“MySQL 5.7 中對(duì) XA 支持的改進(jìn)有哪些”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓丸趣 TV 小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“MySQL 5.7 中對(duì) XA 支持的改進(jìn)有哪些”這篇文章吧。
背景
XA 解決了當(dāng)跨分布式資源情況下能在單個(gè)事務(wù)中保留 ACID 屬性的問(wèn)題。資源本身可以是其他 MySQL 服務(wù)器,甚至可以其他是不同的數(shù)據(jù)庫(kù)技術(shù)。XA 標(biāo)準(zhǔn)描述了全局事務(wù)管理器和本地資源管理器之間的交互。
如引言中所述,MySQL 5.0 引入了 XA 支持,從而增加了參與全局事務(wù)的能力。XA 支持可以提供可訪問(wèn)事務(wù)資源的資源管理器和能夠在全局事務(wù)中協(xié)調(diào)事務(wù)的事務(wù)管理器。MySQL 的 XA 實(shí)現(xiàn)了讓 MySQL 服務(wù)器來(lái)充當(dāng)資源管理器,而連接到 MySQL 服務(wù)器的客戶端執(zhí)行事務(wù)管理器的任務(wù)。
XA 使用兩階段提交協(xié)議,其中第一階段是發(fā)出 commit 請(qǐng)求,然后再進(jìn)行實(shí)際的 commit。全局事務(wù)的各個(gè)分支完成執(zhí)行后,將啟動(dòng)兩階段提交協(xié)議:
在第一階段,事務(wù)管理器向全局事務(wù)中涉及的所有分支發(fā)出準(zhǔn)備 commit 的消息。在資源管理器確認(rèn)已準(zhǔn)備好提交之前,它會(huì)將操作的記錄結(jié)果記錄并保存,為第二階段執(zhí)行實(shí)際的提交做準(zhǔn)備。
在第二階段,事務(wù)管理器如果從所有涉及的分支接收到確定的響應(yīng),則通知它們提交。但是,如果任何一個(gè)分支的答復(fù)為否,則會(huì)通知所有分支執(zhí)行回滾。
一個(gè)事務(wù)管理器與多個(gè)資源管理器進(jìn)行交互,以處理全局事務(wù)中的單個(gè)事務(wù) / 分支。以下圖描述了涉及一個(gè)資源管理器中的 XA 事務(wù)。XA 事務(wù)的語(yǔ)句以 XA 關(guān)鍵字,要執(zhí)行的操作和唯一標(biāo)識(shí)符開(kāi)頭。在下面的示例中,字符串“xatest”表示全局事務(wù)標(biāo)識(shí)符。除了全局事務(wù)標(biāo)識(shí)符之外,還可以為 XA 事務(wù)指定分支標(biāo)識(shí)符和格式 ID。分支標(biāo)識(shí)符用于標(biāo)識(shí)本地事務(wù),格式 ID 指定前兩個(gè)組件使用的格式。
XA START / BEGIN 啟動(dòng)事務(wù)并定義其全局事務(wù)標(biāo)識(shí)符。
XA END 指定活動(dòng)事務(wù)的結(jié)束。
XA PREPARE 為事務(wù)的 COMMIT 做準(zhǔn)備。
XA COMMIT [ONE PHASE] COMMIT 并結(jié)束一個(gè)已 PREPARE 的事務(wù)。
如果使用“單階段”選項(xiàng),則準(zhǔn)備和提交將在結(jié)束事務(wù)的單個(gè)步驟中執(zhí)行。
XA ROLLBACK 回滾并終止事務(wù)。
XA RECOVER 顯示有關(guān)所有 PREPARED 事務(wù)的信息。
讓我們看一下上述 XA 事務(wù)的狀態(tài)之間轉(zhuǎn)換。
XA START 將事務(wù)置于活動(dòng)狀態(tài)。一旦所有語(yǔ)句由活動(dòng)事務(wù)執(zhí)行后,就會(huì)發(fā)出 XA_END 語(yǔ)句,使該事務(wù)處于 IDLE 狀態(tài)。對(duì)于空閑事務(wù),可以發(fā)出 XA PREPARE 或 XA COMMIT ONE PHASE。XA PREPARE 將事務(wù)置于 PREPARED 狀態(tài)。但是,XA COMMIT ONE PHASE 會(huì)準(zhǔn)備并提交事務(wù)。對(duì)于 PREPARED XA 事務(wù),將發(fā)出 XA COMMIT 提交以結(jié)束事務(wù)。
已解決主要問(wèn)題。
在 5.7.7 之前,如果客戶端連接終止或服務(wù)器正常退出,則回滾 PREPARED 事務(wù)。當(dāng)客戶端被殺死時(shí),所有交易都會(huì)回滾。因此,即使 XA 事務(wù)處于 PREPARED 狀態(tài),它也無(wú)法在 XA RECOVER 期間恢復(fù)該事務(wù)。理想情況下,在準(zhǔn)備事務(wù)時(shí),應(yīng)該可以提交或回滾該事務(wù)。對(duì)于這種情況,讓我們看一下
錯(cuò)誤 12161 中報(bào)告的
示例。
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 事務(wù)處于 PREPARED 狀態(tài)且服務(wù)器異常退出,則可以在重新啟動(dòng)服務(wù)器后恢復(fù)該事務(wù) - 但不會(huì)復(fù)制該事務(wù)。 服務(wù)器重新啟動(dòng)后,XA 事務(wù)仍將以 PREPARED 狀態(tài)存在,但其內(nèi)容無(wú)法記錄在二進(jìn)制日志中。因此,二進(jìn)制日志不同步,導(dǎo)致數(shù)據(jù)漂移。因此,XA 不能安全地用于復(fù)制。
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:
為了克服上述限制,需要對(duì) XA 事務(wù)恢復(fù)機(jī)制和二進(jìn)制日志記錄機(jī)制進(jìn)行更改。通過(guò)執(zhí)行工作日志編號(hào)
7193 和
6860 /
bug 12161 在 5.7.7 中進(jìn)行了改進(jìn)。
XA 恢復(fù)機(jī)制已得到擴(kuò)展,以便在終止連接時(shí),將 PREPARED XA 事務(wù)保留在事務(wù)緩存中,并在 InnoDB 中進(jìn)行特殊標(biāo)記。這允許客戶端恢復(fù) PREPARED XA 事務(wù),然后執(zhí)行 COMMIT / ROLLBACK。
現(xiàn)在,使用兩個(gè)不同的 GTID 在兩個(gè)階段對(duì) XA 事務(wù)進(jìn)行二進(jìn)制記錄,從而可以使事務(wù)交織。在第一階段中,當(dāng)發(fā)出 XA PREPARE 時(shí),直到該點(diǎn)的事務(wù)都會(huì)記錄在二進(jìn)制日志中,并且可以通過(guò)以下方式進(jìn)行標(biāo)識(shí):XA_prepare_log_event. 在第二階段中,當(dāng)發(fā)出 XA COMMIT / ROLLBACK 時(shí),將事務(wù)的第二部分寫入二進(jìn)制日志。由于 XA PREPARE 是持久性的,因此 XA 事務(wù)不會(huì)回滾,并且可以在服務(wù)器重新啟動(dòng)或客戶端斷開(kāi)連接后繼續(xù)存在。客戶端可以執(zhí)行 XA COMMIT / ROLLBACK,并且二進(jìn)制日志保持最新。當(dāng) GTID 設(shè)置為 ON 并且二進(jìn)制日志設(shè)置為 OFF 時(shí),XA 事務(wù)也可以很好地工作。
讓我們看看 5.7.7 之后的上述示例的輸出:
客戶端斷開(kāi)連接后:
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)
服務(wù)器重啟后:
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 中對(duì) XA 支持的改進(jìn)有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道!