データベーススペシャリスト 2019年 午前2 問15
問題文
分散データベースシステムにおいて、複数のデータベースサイトを更新する場合に用いられる2相コミットの処理手順のうち、適切なものはどれか。
選択肢
ア:主サイトが各データベースサイトにコミット準備要求を発行した場合、各データベースサイトは、準備ができていない場合だけ応答を返す。
イ:主サイトは、各データベースサイトにコミットを発行し、コミットが失敗した場合には、再度コミットを発行する。
ウ:主サイトは、各データベースサイトのロックに成功した後、コミットを発行し、各データベースサイトをアンロックする。
エ:主サイトは、コミットが可能であることを各データベースサイトに確認した後、コミットを発行する。(正解)
🔒 解説は解答すると表示されます
二相コミット制御【午前2解説】
正解の理由
正解は エ であり、主サイト(コーディネータ)が各データベースサイト(参加者)に「コミット可能か」を問い合わせて全員が「準備完了(Yes)」と応答したときに初めてコミットを指示する、という2相コミット(Two-Phase Commit, 2PC)の基本手順を正しく表しています。これにより、分散トランザクションの原子性(全員が成功するか全員が失敗するか)を保証します。
解法ステップ
- 問題文が「複数サイトを更新する場合の手順」を問うている点から、分散トランザクションのプロトコルを想起する。代表は2相コミット。
- 2相コミットのフェーズを確認する:
- 第1フェーズ(prepare/vote): コーディネータ→参加者に「準備要求」、参加者はログに準備状態を書き、Yes/Noで応答。
- 第2フェーズ(commit/abort): すべてYesならコーディネータがコミットを指示、1つでもNoまたはタイムアウトがあればアボートを指示。
- 選択肢を上記の手順と照合し、通信順序や応答の意味が一致するものを選ぶ。これが エ。
選択肢別の誤答解説
- ア: 「準備ができていない場合だけ応答を返す」としている点が誤り。実際は参加者は必ず応答(Yes/No またはタイムアウト)を返し、Yes(準備完了)ならローカルに準備ログを書きロック、Noなら準備不能を応答してコーディネータはアボートを決定します。応答が無い(タイムアウト)も失敗扱いです。
- イ: 「まずコミットを発行し、失敗したら再度コミットを発行する」という順序が誤り。コミットの可否確認(prepare)を行わずにコミットを突きつけると原子性が保証されません。失敗時の再試行は単純ではなく、ログとリカバリ手順に基づく協調処理が必要です。
- ウ: 「ロック成功後にコミットを発行する」とあるが、ここは誤解を招く表現です。2相コミットではまず各参加者が「prepare(準備)」を実行して可否を返し、コーディネータが全員の準備完了を確認してからコミットを指示します。順序は prepare → commit です。ウの記述は「個別にロックして即コミット指示する」ように読め、分散原子性を満たさないため誤りです。さらに、参加者のロック解除はコミットまたはアボート指示後に行われます。
- エ: 正しい。コーディネータが各参加者にコミット可能かを確認(第1フェーズ)し、全員が可能であればコミット指示(第2フェーズ)を行う。
よくある誤解
- 参加者は「準備できないときだけ応答する」:常に応答(Yes/No)またはタイムアウトで返すのが正しい。応答が無ければタイムアウトとして扱う。
- コミットを単純に再送すれば良い:失敗時は単純再送では整合性が崩れる可能性があるため、ログに基づくリカバリ処理やコーディネータの役割が重要。
- 2相コミットはノンブロッキングである:実際はコーディネータ障害時に参加者がブロックされる(待ち状態)可能性がある(ブロッキング問題)。
補足コラム
- 2PCの状態遷移:コーディネータは「INIT → WAIT_VOTES → DECIDE(commit/abort) → COMPLETE」、参加者は「INIT → PREPARED(ローカルに準備ログ)→ COMMITTED/ABORTED」となる。準備段階で参加者はディスクに準備ログを書き込むことで、障害復旧時に決定を再生できます。
- ブロッキング対策としては、三相コミット(3PC)や分散合意プロトコル(Paxos, Raft)を用いる設計が現代的です。ただし3PCにも前提条件(非同期モデルでの安全性制約)があります。
- 実装上は、タイムアウト設定、永続化(WAL)、リカバリ・ログの管理が重要です。
FAQ
Q1: 参加者がprepareにYesを送った後でクラッシュしたらどうなるか?
A1: 参加者はprepareログを永続化しているため、復旧後にログを見てコーディネータの決定を待ち、コーディネータからcommit/abort指示を受けて状態を確定します。コーディネータが不在の場合はリカバリ手順(タイムアウト・再選出など)に従います。
A1: 参加者はprepareログを永続化しているため、復旧後にログを見てコーディネータの決定を待ち、コーディネータからcommit/abort指示を受けて状態を確定します。コーディネータが不在の場合はリカバリ手順(タイムアウト・再選出など)に従います。
Q2: コーディネータが故障したらトランザクションはどうなるか?
A2: コーディネータ故障中は参加者が決定を待ちブロックする可能性がある(ブロッキング問題)。復旧後、コーディネータはログを確認して決定を再送するか、分散システムの設計によりフォールトトレラントなコーディネータ再選出が行われます。
A2: コーディネータ故障中は参加者が決定を待ちブロックする可能性がある(ブロッキング問題)。復旧後、コーディネータはログを確認して決定を再送するか、分散システムの設計によりフォールトトレラントなコーディネータ再選出が行われます。
Q3: 2PCはなぜ使われるのか?
A3: ネットワーク越しの複数サイトでの更新を「原子性・一貫性」を保ちながら実行するためのシンプルで実装しやすいプロトコルだからです。ただし可用性やブロッキングの課題があります。
A3: ネットワーク越しの複数サイトでの更新を「原子性・一貫性」を保ちながら実行するためのシンプルで実装しやすいプロトコルだからです。ただし可用性やブロッキングの課題があります。
関連キーワード: 二相コミット、2PC、分散トランザクション、コミットプロトコル、参加者(participant)、コーディネータ(coordinator)

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

