pgxc架構下兩階段提交異常分析

在當前去IOE的大潮下,分佈式數據庫正如火如荼的發展起來,特別是國產數據庫呈現了井噴態勢。一個典型的分佈式數據庫應該具有如下組件:①協調節點,也叫sql轉發節點,用來進行sql協議支持,分佈式執行計劃生成與下發;②數據節點:用來存儲數據,同時進行運算;③全局事務管理器,用來保證事務一致性。爲了保證高可用,成熟的分佈式數據庫這些節點都具有主備切換功能。

 

Pgxc就是這樣cn+dn+gtm的經典架構,底層基於postgresql數據庫,pgxc架構如下:

應用連接到協調節點coordinator,數據hash到每個數據節點datanode,所有數據庫節點組成完整一份數據,協調節點具有多副本,多個cn節點是無狀態的(其實這裏並不是真正意義上的無狀態,首先ddl元信息需要在每個cn進行同步,否則連到不同的cn可能查到不一致的結果;還有一方面是兩階段殘留的問題,這個問題我們後面再細細討論)。Dn是主備架構,主備通過流複製進行同步。Gtm負責生成全局gxid+snapshot,這裏的snapshot是爲了保證全局的讀一致性,做讀可見性判斷。

 

pgxc兩階段提交流程

 

下圖只以一個DN爲例,主要分爲下面幾個階段:

①:CN prepare ->②:所有DN prepare ->③:CN commit->④:所有DN commit

 

現在我們假設在如上四個階段發生異常探討數據庫的處理機制。

 

①cn prepare階段發生cn/dn宕機:

這種情況下不需要處理,如果cn宕機能夠重新啓動,那事務繼續執行,如果cn無法啓動,那麼會引入超時機制將事務進行回滾。同理如果dn宕機,那事務也會等待一個超時時間,然後進行回滾。總之,這種情況不會造成事務不一致。

 

②dn prepare ok階段發生cn/dn宕機:

這種情況其實和上面類似,也是會阻塞一個超時時間進行回滾,不會造成不一致現象。

 

③cn commit階段發生cn/dn宕機:

如果在cn下發完cn commit命令後宕機,這時dn收到commit命令後會進行提交,但是返回commit ok時發生cn宕機,事務進入阻塞狀態。如果cn下發commit之後某個dn發生宕機,則會造成某些dn commit成功,某些dn commit失敗,造成不一致,但是如果dn重新啓動後會繼續去cn上拿事務提交信息,發現是commit狀態,則會繼續執行commit操作,提交之前的事務。在這個地方我們可以探討一個更極端的情況,如果此時cn也宕機了,那麼失敗的dn重啓後去cn拿狀態發現拿不到,這是這個失敗dn上的事務就處於一個未決態,不知道是應該提交還是回滾,這時候應該有一個進程能夠從其他dn上發現該狀態並報告給故障dn,通知它進行提交。這個角色就是pgxc_clean進程,其實之前幾種情況下的事務的回滾也是該進程的工作。那我們再深入一下,如果該dn是事務的唯一參與者,那麼此時pgxc_clean就無法從其他dn以及cn獲取狀態,這時該dn就是真正的未決態了。

 

④dn commit ok階段發生cn/dn宕機:

這種情況下其實每個dn都已經提交成功,只是返回ack失敗,此時事務已經是一致的了,如果cn宕機,會選舉新的cn,如果dn宕機也沒有影響,數據已經落盤,啓動後數據不會丟失。       

 

爲了測試兩階段事務我們還專門研發了跨節點轉賬程序,轉賬程序邏輯如下:

 

一個transfer_test表包含客戶號、餘額等信息,隨機選取兩個賬戶進行兩條update轉賬,兩條轉賬放在一個事務裏。轉賬跨節點的概率爲(n-1)/n,n爲DN個數。轉賬程序支持高併發,支持指導賬戶,支持記錄tps值。使用改程序我們也測試出某些分佈式數據庫不一致的問題,同時也測試出了兩階段協議的阻塞問題。

 

更多精彩內容關注我的公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章