如果你認為利用中間件將數據分發出去就不用管了,這樣的想法可是很危險的!
DBLE 分佈式中間數據庫的中間件,是利用MYSQL 通用的 XA 協議來做的,如果不知道DBLE,那請百度一下。XA 協議對於分庫分庫分表是很重要的一個協議。
那麼什麼是XA 協議? XA是一種兩階段提交協議,很多數據庫和事務監視器都支持,它通過協調訪問多個關係數據庫的單個事務來確保數據完整性。XA保證在所有參與的數據庫中提交事務更新,或者從所有數據庫中完全回滾,恢復到事務開始之前的狀態。
為了參與XA事務,XA資源必須讓事務管理器知道其自身。一旦登記了XA資源,事務管理器將確保XA資源參與事務,並在事務的生存期內對XA資源進行適當的方法調用。要完成XA事務,所有資源管理器都參與一個兩階段提交(2pc)。XA事務中的提交稱為兩階段提交,因為在提交過程中有兩次傳遞。
在第一輪中,事務管理器詢問每個資源管理器是否在提交事務時遇到任何問題。如果任何資源管理器反對提交事務,則任何一方對XA事務中涉及的任何資源所做的所有工作都必須全部回滾。
事務管理器對每個已徵募的XA資源調用rollback()方法。如果沒有資源管理器反對提交,那麼第二輪將涉及事務管理器對每個已徵募的XA資源實際調用commit()。這個過程保證了可以跨多個資源的事務的ACID(原子性、一致性、隔離性和持久性)屬性。
XA 協議的一些步驟:
1 XA START
2 Some SQL statement
3 XA END
4 XA Prepare
5 XA Commit or Rollback
舉例,如果三個物理數據中的一個數據庫,在中間件下發數據的時候,其中一個進行了重啟,回怎麼樣,如果是在 MYSQL 5.6 版本的時候,那很可能就丟數據的情況,上面的話如果不理解的話我們還是捋一捋
- 中間件已經向分庫1和分庫2,分庫3,上發送完了 xa prepare ‘xid1’語句,並得到了成功的回覆
- 中間件向分庫1,3上發送了 ‘xa commit ‘xid1’語句,並已經成功返回
- 當 中間件向分庫2上發送 ‘xa commit ‘xid1’時,網絡斷開了,或者分庫2的數據庫實例被kill了
- 當網絡恢復(這時相關的Session已經退出了)或數據庫實例再啟動後(或切換到備庫),XA prepare了的事務已經回滾了, 當中間件 XA commit ‘xid1’發過來後數據庫實例根本找不到xid1這個xa事務
上面的流程就導致了分佈式事務的不一致:分庫1,3提交了事務,分庫2回滾了事務,整個事務提交了一半,回滾了一半。
但由於MYSQL5.6中沒有 xa prepare 的嚴格的持久化,當Session斷開,數據庫CRASH等情況下這些事務會被回滾掉,並且一個主庫配了SemiSync的情況下xa prepare了的事務也不會被髮送的SLAVE庫,當主庫切換到備庫這些事務也就丟失。
所以安全的使用中間件的情況一定是你使用了MYSQL.5.7 的情況下,分佈式的MYSQL 才能有安全的保證。
我們來做一個實驗
<code>
然後,機器突然就崩潰了。如果是一般的事務,那一定就消失了。下圖是機器已經重啟了,同時數據也沒有插入。
然後我們在commit
數據就回來了。通過這樣的方式分佈式中間件是可以保證某個物理庫出現問題後,在變得正常後的數據是可以進行恢復的。
XA RECOVER;
xa recover; 是可以看到在prepare 狀態的事務,參見上圖
同時在BINLOG 中也是有相關的XA的記錄,所以就算是切換,也不會導致分佈式事務的丟失。
所以,如果你認為分佈式中間件就是一個通過數據分片鍵進行數據分發,誰都可以做的。那隻好祝上帝保佑你了。。。
以上內容由東方瑞通資深講師 Austin”供稿,13年專業DBA經驗,曾任互聯網金融公司Senior DBA、500強制藥企業Senior DBA,精通Mysql、PostgreSQL、Mongo DB、SQLServer。
閱讀更多 天津東方瑞通 的文章