2011-09-12 86 views
40

我相信大多數人都知道2PC(兩階段提交協議)是什麼,以及如何在Java或大多數現代語言中使用它。基本上,它用於確保當您擁有2個或更多數據庫時事務處於同步狀態。兩階段提交

假設我在兩個不同的位置使用2PC 2分的DB(A和B)。在A和B準備提交事務之前,兩個DB都會向事務管理器報告,說他們已準備好提交。所以,當事務管理器被確認時,它會發回一個信號給A和B,告訴他們繼續。

這是我的問題:比方說,A收到信號並提交交易。一旦完成一切,B即將做同樣的事情,但有人拔掉電源線,導致整個服務器關機。當B重新上線時,B會做什麼? B怎麼做?

記住,一個致力於但是B不,我們正在使用2PC(因此,2PC的設計停止工作,不是嗎?)

回答

43

在兩階段提交

兩個階段提交併不保證分佈式事務不會失敗,但它確實保證不會在TM沒有意識到的情況下自動失敗。

爲了讓B到報告這項交易爲準備提交,B必須在永久存儲的交易(即B必須是能夠保證交易能夠在所有情況下提交)。在這種情況下,B一直堅持交易,但交易經理尚未收到B的消息,確認B已完成提交。

事務管理器將再次輪詢B時的B來到重新聯機,並要求它提交事務。如果B已經提交了交易,它將報告交易已完成。如果B還沒有提交交易,它就會提交,因爲它已經堅持了它,因此仍然可以提交交易。

爲了讓B到在這種情況下失敗了,那就要經歷一個災難性的失敗是數據丟失或日誌條目。交易管理者仍然會意識到B沒有報告成功的提交。

在實踐中,如果B可不再提交事務,這將意味着,這花了B發出災害已造成數據丟失,而當TM要求它提交TxID添加B將報告的錯誤它並沒有意識到或沒有認爲處於可交換狀態。

因此,兩個階段提交不會阻止發生的歷史災難性故障,但它確實防止故障的忽視。在這種情況下,如果B不能提交,事務管理器會嚮應用程序報告錯誤。

應用程序仍然必須能夠從錯誤中恢復,但成交離不開應用程序靜默失敗被意識到矛盾的狀態中。

語義

  • 如果資源管理器或網絡出現故障在階段1, 事務管理器將檢測到致命錯誤(無法連接到 資源管理器)和標記子交易失敗。當 網絡恢復時,它將中止所有參與資源管理器上的事務處理。

  • 如果資源管理器或網絡中的第2階段出現故障, 事務管理器將繼續輪詢直到 它回來了資源管理器。當它重新連接回資源管理器 它會告訴RM提交事務。如果RM沿'未知TxID'返回 錯誤,則TM將會知道 RM中存在數據丟失問題。

  • 如果TM在階段1中出現故障,則客戶端將阻塞,直到 TM恢復運行,除非它由於網絡連接斷開而超時或收到錯誤。在這種情況下,客戶意識到 錯誤,並且可以重新嘗試或啓動中止本身。

  • 如果TM進入第2階段下來,然後它會阻止,直到 以舊換新回來了客戶端。它已經將交易報告爲 可提交,並且不應向客戶提交致命錯誤 ,但它可能會阻止,直到TM恢復。 TM仍然會以 的交易處於未提交狀態,並將輪詢RM 以在其恢復時提交。

資源管理器中的提交後數據丟失事件不由事務管理器處理,它是RM彈性的函數。

兩階段提交併不保證容錯能力 - 請參閱Paxos瞭解確實解決容錯的協議示例 - 但它確實保證分佈式事務的部分故障不會不被注意。

  1. 注意,這種故障也可能會失去從先前提交的交易數據。兩階段提交併不能保證資源管理器不會丟失或損壞數據,或者DR過程不會搞砸。
+0

這個答案提出了[網絡可靠]這個危險的假設(https://queue.acm.org/detail.cfm?id=2655736)。 –

+0

我不知道你在做什麼。如果在第一階段發生網絡中斷,TM將無法連接到其中一個RM並因致命錯誤而中止交易,最終告知所有RM在他們重新聯機時中止。在第二階段,它將繼續輪詢RM,直到網絡恢復正常,此時它將發出確認提交。同樣,2PC不保證提交,它只是保證事務不會失敗,沒有應用程序意識到它。 – ConcernedOfTunbridgeWells

+0

如果TM在收到所有投票提交後崩潰,但在發送最終提交/放棄之前會怎麼樣?然後每個人都拿着鎖,等待投票。而且你不能超時,有些節點可能會提交而其他節點會超時並中止。如果你有一個同步可靠的網絡,並且沒有節點崩潰,並且你有實時操作系統,這樣你就可以在有限的時間內保證進度,那麼2PC就可以工作。通常,我們沒有這些屬性。 –

2

我相信三階段提交是一個更好的方法。不幸的是,我還沒有發現任何人實施這樣的技術。

http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/

這裏有上述文章的主要部分:

與2PC的主要困難是,一旦提交已決定由統籌製作,並傳達給一些副本,複製品會直接前進並根據提交語句執行操作,而不檢查每個其他副本是否收到該消息。然後,如果提交的副本與協調者一起崩潰,那麼系統無法告訴交易的結果是什麼(因爲只有收到消息的協調員和副本肯定知道)。由於事務可能已經在崩潰的副本上提交,協議不能悲觀地中止 - 因爲事務可能具有無法撤消的副作用。同樣,該議定書也不能樂觀地強制交易承諾,因爲最初的投票可能是墮胎。

這個問題 - 大部分情況 - 通過增加一個額外的階段到2PC來繞過,毫不奇怪,給我們一個三階段提交協議。這個想法很簡單。我們打破2PC的第二階段 - '承諾' - 分成兩個子階段。首先是「準備提交」階段。當協調員在第一階段收到一致的「是」票時,協調員會將此消息發送給所有副本。在接收到這些消息後,副本進入可以提交事務的狀態 - 通過獲取必要的鎖等等,但最重要的是不做任何以後無法撤消的工作。然後他們回覆協調員,告訴它已收到「準備提交」的信息。

此階段的目的是將投票結果傳達給每個副本,以便無論哪個副本死亡都可以恢復協議的狀態。

該協議的最後階段與2PC中的原始「提交或放棄」階段幾乎完全相同。如果協調員收到所有副本提交的「準備提交」消息的確認,則繼續提交事務是安全的。然而,如果交付沒有得到確認,協調員不能保證協議狀態在它發生崩潰時能夠被恢復(如果你容忍固定數量的故障,則協調器可以在接收到f + 1後繼續確認)。在這種情況下,協調員將中止交易。

如果協調器在任何時候都應該崩潰,恢復節點可以接管事務並從任何剩餘的副本中查詢狀態。如果已提交事務的副本已經崩潰,則我們知道每個其他副本都收到了「準備提交」消息(否則協調器不會移動到提交階段),因此恢復節點將會能夠確定交易能夠被執行,並且安全地將協議安排在其結論之上。如果有任何副本向恢復節點報告尚未收到「準備提交」的副本,恢復節點將知道該事務沒有在任何副本上提交,因此能夠悲觀地中止或重新運行協議從一開始就。

那麼3PC是否解決了我們所有的問題?不完全,但接近。在網絡分區的情況下,車輪相當不錯 - 想象一下,所有收到「準備提交」的副本位於分區的一側,而那些不在另一側的副本。然後這兩個分區將繼續與分別提交或中止事務的恢復節點,並且當網絡合並時,系統將具有不一致的狀態。所以3PC和2PC一樣有可能不安全的運行,但總是會取得進展並因此滿足其活性特性。 3PC不會阻止單節點故障的事實使得它對於高可用性比低延遲更重要的服務更具吸引力。

+0

最好把鏈接文章的基本部分放在答案中,這樣,如果鏈接被改變,信息不會丟失。 –

+0

爲了實際的正確性,您應該在系統中真正使用Raft或Paxos而不是3PC。 –

3

儘管您付出了很多努力,但您的情況並非唯一可能最終出錯的地方。假設A和B都向TM報告了「準備提交」,然後有人拔掉TM與B之間的界限,B正在等待TM的前進(或不進行),但它肯定獲勝在TM重新連接之前不會永遠等待(由於顯而易見的原因,在整個等待時間內,涉及交易的資源必須保持鎖定/不可訪問)。所以當B爲了自己的口味而等待時間過長時,它會採取所謂的「啓發式決策」。也就是說,它會決定獨立於TM來提交或回滾,呃,我不知道是什麼,但這並不重要。顯而易見的是,任何這樣的啓發式決策都可能偏離TM所做出的實際承諾決定。