久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL 5.7的分布式事務支持舉例分析

139次閱讀
沒有評論

共計 3161 個字符,預計需要花費 8 分鐘才能閱讀完成。

本篇內容主要講解“MySQL 5.7 的分布式事務支持舉例分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“MySQL 5.7 的分布式事務支持舉例分析”吧!

分布式事務通常采用 2PC 協議,全稱 Two Phase Commitment Protocol。該協議主要為了解決在分布式數據庫場景下,所有節點間數據一致性的問題。在分布式事務環境下,事務的提交會變得相對比較復雜,因為多個節點的存在,可能存在部分節點提交失敗的情況,即事務的 ACID 特性需要在各個數據庫實例中保證。總而言之,在分布式提交時,只要發生一個節點提交失敗,則所有的節點都不能提交,只有當所有節點都能提交時,整個分布式事務才允許被提交。

分布式事務通過 2PC 協議將提交分成兩個階段

prepare;

commit/rollback

第一階段的 prepare 只是用來詢問每個節點事務是否能提交,只有當得到所有節點的“許可”的情況下,第二階段的 commit 才能進行,否則就 rollback。需要注意的是:prepare 成功的事務,則必須全部提交。

MySQL 分布式事務

一直以來,MySQL 數據庫是支持分布式事務的,但是只能說是有限的支持,具體表現在:

已經 prepare 的事務,在客戶端退出或者服務宕機的時候,2PC 的事務會被回滾

在服務器故障重啟提交后,相應的 Binlog 被丟失

上述問題存在于 MySQL 數據庫長達數十年的時間,直到 MySQL-5.7.7 版本,官方才修復了該問題。雖然 InnoSQL 早已在 5.5 版本修復,但是對比官方的修復方案,我們真的做的沒有那么的優雅。下面將會詳細介紹下該問題的具體表現和官方修復方法,這里分別采用官方 MySQL-5.6.27 版本 (未修復) 和 MySQL-5.7.9 版本 (已修復) 進行驗證。

先來看下存在的問題,我們先創建一個表如下:

create table t(
 id int auto_increment primary key, 
 a int
)engine=innodb;

對于上述表,通過如下操作進行數據插入:

mysql  XA START  mysql56 
mysql  INSERT INTO t VALUES(1,1);
mysql  XA END  mysql56 
mysql  XA PREPARE  mysql56

通過上面的操作,用戶創建了一個分布式事務,并且 prepare 沒有返回錯誤,說明該分布式事務可以被提交。通過命令 XA RECOVER 查看顯示如下結果:

mysql  XA RECOVER;
+----------+--------------+--------------+---------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+---------+
| 1 | 7 | 0 | mysql56 |
+----------+--------------+--------------+---------+

若這時候用戶退出客戶端后重連,通過命令 xa recover 會發現剛才創建的 2PC 事務不見了。即 prepare 成功的事務丟失了,不符合 2PC 協議規范!!!

產生上述問題的主要原因在于:MySQL-5.6 版本在客戶端退出的時候,自動把已經 prepare 的事務回滾了,那么 MySQL 為什么要這樣做?這主要取決于 MySQL 的內部實現,MySQL-5.7 以前的版本,對于 prepare 的事務,MySQL 是不會記錄 binlog 的(官方說是減少 fsync,起到了優化的作用)。只有當分布式事務提交的時候才會把前面的操作寫入 binlog 信息,所以對于 binlog 來說,分布式事務與普通的事務沒有區別,而 prepare 以前的操作信息都保存在連接的 IO_CACHE 中,如果這個時候客戶端退出了,以前的 binlog 信息都會被丟失,再次重連后允許提交的話,會造成 Binlog 丟失,從而造成主從數據的不一致,所以官方在客戶端退出的時候直接把已經 prepare 的事務都回滾了!

官方的做法,貌似干得很漂亮,犧牲了一點標準化的東西,至少保證了主從數據的一致性。但其實不然,若用戶已經 prepare 后在客戶端退出之前,MySQL 發生了宕機,這個時候又會怎樣?

MySQL 在某個分布式事務 prepare 成功后宕機,宕機前操作該事務的連接并沒有斷開,這個時候已經 prepare 的事務并不會被回滾,所以在 MySQL 重新啟動后,引擎層通過 recover 機制能恢復該事務。當然該事務的 Binlog 已經在宕機過程中被丟失,這個時候,如果去提交,則會造成主從數據的不一致,即提交沒有記錄 Binlog,從上丟失該條數據。所以對于這種情況,官方一般建議直接回滾已經 prepare 的事務。

以上是 MySQL-5.7 以前版本 MySQL 在分布式事務上的各種問題,那么 MySQL-5.7 版本官方做了哪些改進?這個可以從官方的 WL#6860 描述上得到一些信息,我們還是本著沒有實踐就沒有發言權的態度,從具體的操作上來分析下 MySQL-5.7 的改進方法:

還是以上面同樣的表結構進行同樣的操作如下:

mysql  XA START  mysql57 
mysql  INSERT INTO t VALUES(1,1);
mysql  XA END  mysql57 
mysql  XA PREPARE  mysql57 通過上面的操作,明顯發現在 prepare 以后,從 XA START 到 XA PREPARE 之間的操作都被記錄到了 Master 的 Binlog 中,然后通過復制關系傳到了 Slave 上。也就是說 MySQL-5.7 開始,MySQL 對于分布式事務,在 prepare 的時候就完成了寫 Binlog 的操作,通過新增一種叫

當然僅靠這一點是不夠的,因為我們知道 Slave 通過 SQL thread 來回放 Relay log 信息,由于 prepare 的事務能阻塞整個 session,而回放的 SQL thread 只有一個(不考慮并行回放),那么 SQL thread 會不會因為被分布式事務的 prepare 階段所阻塞,從而造成整個 SQL thread 回放出現問題?這也正是官方要解決的第二個問題:怎么樣能使 SQL thread 在回放到分布式事務的 prepare 階段時,不阻塞后面 event 的回放?其實這個實現也很簡單(在 xa.cc::applier_reset_xa_trans),只要在 SQL thread 回放到 prepare 的時候,進行類似于客戶端斷開連接的處理即可(把相關 cache 與 SQL thread 的連接句柄脫離)。最后在 Slave 服務器上,用戶通過命令 XA RECOVER 可以查到如下信息:

mysql  XA RECOVER;
+----------+--------------+--------------+---------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+---------+
| 1 | 7 | 0 | mysql57 |
+----------+--------------+--------------+---------+

至于上面的事務什么時候提交,一般等到 Master 上進行 XA COMMIT  ‘mysql57’后,slave 上也同時會被提交。

到此,相信大家對“MySQL 5.7 的分布式事務支持舉例分析”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-19發表,共計3161字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 武夷山市| 长岛县| 阳谷县| 浑源县| 连州市| 临沧市| 阿拉尔市| 邵东县| 乐业县| 巴青县| 资兴市| 太谷县| 绥江县| 缙云县| 广南县| 仙居县| 西昌市| 阿克陶县| 北流市| 涿鹿县| 东乡县| 习水县| 天柱县| 三亚市| 都江堰市| 米易县| 合水县| 怀来县| 富裕县| 盘锦市| 郯城县| 湖州市| 东乡县| 黑山县| 军事| 若尔盖县| 文安县| 玉林市| 珲春市| 高邑县| 宁远县|