
トランザクション処理、データベース、コンピュータネットワーキングにおいて、2フェーズコミットプロトコル(2PC、tupac )は、アトミックコミットメントプロトコル( ACP )の一種である。これは、分散アトミックトランザクションに参加するすべてのプロセスを、トランザクションをコミットするか中止(ロールバック)するかについて調整する分散アルゴリズムである。このプロトコル(特殊なタイプのコンセンサスプロトコル)は、一時的なシステム障害(プロセス、ネットワークノード、通信などの障害を含む)の多くの場合でも目的を達成できるため、広く使用されている。[ 1 ] [ 2 ] [ 3 ] ただし、すべての可能性のある障害構成に対して耐性があるわけではなく、まれに、結果を修正するために手動介入が必要になることもあります。障害からの回復(ほとんどの場合は自動)に対応するため、プロトコルの参加者はプロトコルの状態をログに記録します。ログレコードは通常、生成に時間がかかりますが、障害後も存続し、プロトコルの回復手順によって使用されます。ログ記録通常、頻繁に使用されることはありませんが、プロトコルでは多くの障害シナリオが考慮され、サポートされるため、回復手順はプロトコルのかなりの部分を占めます。
単一の分散トランザクションの「通常の実行」 (つまり、障害が発生しない場合。これが通常最も頻繁に発生する状況)では、プロトコルは次の 2 つのフェーズで構成されます。
2 フェーズ コミット (2PC) プロトコルを、同時実行制御プロトコルである2 フェーズ ロック(2PL) プロトコルと混同しないでください。
このプロトコルは次のように動作します。1つのノードがコーディネーター(マスターサイト)として指定され、ネットワーク内の残りのノードは参加者として指定されます。このプロトコルでは、以下のことを前提としています。
最後の仮定は、ネットワーク通信は通常ルート変更できるため、それほど制限的ではありません。最初の2つの仮定ははるかに強力で、ノードが完全に破壊された場合、データが失われる可能性があります。
プロトコルは、トランザクションの最終ステップに到達した後、コーディネーターによって開始されます。参加者は、トランザクションが参加者側で正常に処理されたかどうかに応じて、合意メッセージまたは中止メッセージで応答します。
コーディネータがコミット要求フェーズ中にすべての参加者から合意メッセージを受信した場合:
コミット要求フェーズ中にいずれかの参加者が「いいえ」と投票した場合(またはコーディネータのタイムアウトが期限切れになった場合):
コーディネーター参加者 クエリをコミットする --------------------------------> 準備*/中止*に賛成/反対に投票してください <--------------------------------- コミット*/中止* コミット/ロールバック --------------------------------> 確認コミット*/中止* <-------------------------------- 終わり
レコードタイプの横にある*は、レコードが強制的に安定したストレージに保存されることを意味します。[ 4 ]
多くの場合、2PCプロトコルはコンピュータネットワークに分散されています。これは、互いに類似した複数の専用2PCコンポーネント(通常はトランザクションマネージャ(TM、2PCエージェントまたはトランザクション処理モニタとも呼ばれます))を実装することで簡単に分散できます。これらのコンポーネントは、各トランザクション(例:The Open GroupのX/Open XA)のプロトコル実行を実行します。分散トランザクションに関係するデータベース(コーディネータと参加者の両方)は、2PCを使用してそのトランザクションを終了するために、クローズTM(通常は参加者と同じネットワークノード上に存在)に登録します。各分散トランザクションには、トランザクション参加者が登録するTMのアドホックセットが存在します。各トランザクションには、2PCを調整するリーダー(コーディネータTM)が存在し、通常はコーディネータデータベースのTMです。ただし、パフォーマンスや信頼性上の理由から、コーディネータの役割は別のTMに委譲できます。参加者は、2PCメッセージを参加者間で交換するのではなく、それぞれのTMとメッセージを交換します。関連するTMは相互に通信し、上記の2PCプロトコルスキーマを実行して各参加者を「代表」し、トランザクションを終了します。このアーキテクチャでは、プロトコルは完全に分散化されており(中央処理コンポーネントやデータ構造を必要としません)、ネットワークノードの数(ネットワークサイズ)に応じて効率的にスケールアップします。
この共通アーキテクチャは、2PC以外のアトミックコミットメントプロトコルの配布にも効果的です。なぜなら、そのようなプロトコルはすべて同じ投票メカニズムとプロトコル参加者への結果の伝播を使用するからです。[ 1 ] [ 2 ]
データベース研究では、プロトコルの最適化[ 1 ] [ 2 ] [ 3 ]と特定のシステムの動作仮定の下でのプロトコル操作の節約によってコストを削減しながら、2フェーズコミットプロトコルの利点を最大限に活用する方法が研究されてきました。
推定アボートや推定コミットは、このような一般的な最適化です。[ 2 ] [ 3 ] [ 5 ]コミットまたはアボートのいずれかのトランザクションの結果についての仮定は、2PC プロトコルの実行中に参加者によるメッセージとログ操作の両方を節約できます。たとえば、推定アボートの場合、障害からのシステム回復中に、回復手順によってトランザクションのコミットのログに記録された証拠が見つからない場合、トランザクションがアボートされたと想定し、それに応じて動作します。これは、アボートがログに記録されるかどうかは問題ではなく、この仮定の下ではそのようなログを節約できることを意味します。通常、最適化の種類に応じて、障害からの回復中に追加操作のペナルティが支払われます。したがって、最適化の最良のバリエーションがある場合は、障害とトランザクションの結果の統計に応じて選択されます。
ツリー2PCプロトコル[ 2 ](ネスト2PC、または再帰2PCとも呼ばれる)は、コンピュータネットワークにおける2PCの一般的な変種であり、基盤となる通信インフラストラクチャをより有効に活用します。分散トランザクションの参加者は通常、ツリー構造(呼び出しツリー)を定義する順序で呼び出されます。呼び出しツリーでは、参加者がノード、エッジが呼び出し(通信リンク)です。2PCプロトコルによるトランザクションの完了には同じツリーが一般的に使用されますが、原理的には別の通信ツリーも使用できます。ツリー2PCでは、コーディネータが通信ツリー(反転ツリー)のルート(最上位)と見なされ、参加者は他のノードです。コーディネータは、トランザクションを開始したノード(他の参加者によって再帰的(推移的)に呼び出される)である場合もあれば、同じツリー内の別のノードがコーディネータの役割を担う場合もあります。コーディネータからの 2PC メッセージはツリーの「下」に伝播されますが、コーディネータへのメッセージは、参加者がその下のすべての参加者から「収集」してから、適切なメッセージをツリーの「上」に送信します (中止メッセージは受信後すぐに、または現在の参加者が中止を開始した場合に「上」に伝播されます)。
動的 2 フェーズ コミット (Dynamic two-phase commitment, D2PC) プロトコル[ 2 ] [ 6 ]は、Tree 2PC の変形で、事前に決定されたコーディネータはありません。これは、以前に提案されたいくつかの最適化を包含しています。合意メッセージ (はい票) は、すべてのリーフから伝播し始め、各リーフはトランザクションに代わってタスクを完了すると (準備完了になると) なります。中間 (リーフではない) ノードは、合意メッセージをまだ受信していない最後の (単一の) 隣接ノードに合意メッセージを送信すると、準備完了を送信します。コーディネータは、合意メッセージをトランザクション ツリー上で競合させ、衝突する場所で動的に決定されます。メッセージは、トランザクション ツリー ノードで衝突してコーディネータになるか、ツリー エッジで衝突します。後者の場合、2 つのエッジ ノードのうちの 1 つがコーディネータ (任意のノード) として選出されます。 D2PC は、時間的に最適です (特定のトランザクション ツリーのすべてのインスタンス、および任意の特定の Tree 2PC プロトコル実装の間。すべてのインスタンスは同じツリーを持ち、各インスタンスはコーディネータとして異なるノードを持ちます)。最適なコーディネータを選択することで、D2PC はコーディネータと各参加者の両方を可能な限り最短時間でコミットし、各トランザクション参加者 (ツリー ノード) でロックされたリソースを可能な限り早く解放できるようにします。