プロンプトとユースケース
PostgreSQL 18 のプライマリは、論理レプリケーションを通じて分析クラスターおよび外部サブスクライバーに変更を送信します。プライマリは物理スタンバイにフェイルオーバーする可能性があります。「スタンバイが同期されている」ことと「サブスクライバーが追いついている」ことを混同せずに、論理レプリケーションが正しい位置から再開されるように、スロット、設定、サブスクライバーのチェック、および切り替え順序を設計してください。
面接官がテストしていること
- 論理スロット、物理スロット、WAL 保持、およびサブスクライバーが確認した位置を区別できているか。
- フェイルオーバースロットの同期が非同期であり、切り替え前に準備完了を証明する必要があることを理解しているか。
pg_replication_slots、LSN、およびサブスクリプションの状態を使用して安全な切り替えを証明できるか。- 無効なスロット、遅延しているサブスクライバー、計画的な切り替え、および予期せぬ障害に対処できるか。
回答前に明確にすべき質問
- サブスクライバーは PostgreSQL ですか、それとも外部システムですか?また、それらは新しいプライマリに再接続できますか?
- 許容される RPO はゼロ、限定的な LSN ギャップ、または再構築可能なサブスクリプションスナップショットのいずれですか?
- プライマリとスタンバイの間で物理レプリケーションスロットおよび同期スタンバイの制約は設定されていますか?
- 切り替えは自動化されていますか、それとも手動ですか?また、誰が書き込みを凍結し、接続ルーティングを更新しますか?
30秒の回答フレームワーク
切り替え後も存続させる必要がある各論理スロットに対して failover を有効にし、その状態がホットスタンバイに同期されるようにします。また、引き継ぎスタンバイが永続化していない進行状況をサブスクライバーが確認できないよう、物理同期制約を設定します。切り替えの前に、スタンバイ上のすべての必要なスロットが synced であり、一時的(non-temporary)ではなく、無効化されていないことを確認します。スタンバイを昇格させ、接続を更新し、サブスクライバーが新しいプライマリから消費していることを確認してから、書き込みの凍結を解除します。非同期同期が遅れている場合は、切り替えを遅らせるか、文書化された RPO と再構築コストを受け入れます。
ステップバイステップの詳細解説
1. 論理レプリケーションスロットが保存するもの
論理スロットは、デコードの進行状況と、サブスクライバーによってまだ確認されていない WAL 保持境界を保存します。スロットはサブスクライバーの健全性シグナルではありません。停止したサブスクライバーはプライマリに WAL を保持させ、ディスクを消費させる可能性があります。
2. フェイルオーバースロットの作成
PostgreSQL 18 では、論理スロットの作成時に failover を設定すること、およびサブスクリプション作成時における対応するオプションがサポートされています。以下の SQL は説明用です。対象バージョンおよびデプロイ方法に照らして正確な引数と権限を確認してください。
SELECT *
FROM pg_create_logical_replication_slot('analytics_slot', 'pgoutput', false, true);フェイルオーバーフラグによりスロット状態をスタンバイに同期できるようになりますが、同期が完了したことを証明するものではありません。
3. スタンバイの同期設定
スタンバイは、sync_replication_slots などの論理スロット同期の受信と適用を有効にする必要があります。プライマリは synchronized_standby_slots を使用して特定の物理スロットが最初に追いつくことを要求でき、論理サブスクライバーの進行状況が引き継ぎを行うスタンバイを追い越すのを防ぎます。
4. なぜ非同期の準備完了に個別のチェックが必要なのか
スロット同期は状態を非同期にコピーします。プライマリ障害時、スタンバイはデータページを持っていても、最新のスロット位置を持っていない可能性があります。即座に昇格させると、サブスクライバーが開始ポイントを失ったり、重複やギャップが発生したりする可能性があります。
5. 切り替え前のスロット状態の確認
候補スタンバイで pg_replication_slots をクエリします。必要な各スロットが同期されており、一時的ではなく、無効化の理由がないことを確認し、その結果をサブスクライバーインベントリと照合します。
SELECT slot_name,
synced,
temporary,
invalidation_reason,
confirmed_flush_lsn
FROM pg_replication_slots
WHERE slot_type = 'logical';必要なすべてのスロットが合格した場合にのみ、スタンバイを引き継ぎ準備完了としてマークする必要があります。
6. PostgreSQL サブスクライバー向けの追加チェック
PostgreSQL サブスクライバーの場合は、サブスクライバーが同期されたスロットと互換性のある位置を消費していることも確認します。プライマリからスタンバイへの物理的な遅延だけでは不十分です。サブスクリプションの状態、最後に受信した LSN、およびビジネス遅延を組み合わせます。
7. 外部サブスクライバーの切り替え
外部システムは通常、PostgreSQL のスロット状態を自動的に解釈できません。切り替えオーケストレーターは、消費を凍結または一時停止し、スタンバイを昇格させ、接続とスロット名を更新し、その後、データがスキップされていないことを証明するためにべき等なイベントとアプリケーションオフセットを使用する必要があります。
8. 障害およびリカバリパス
計画的な切り替えでは、すべてのスロットが同期されるまで待つことができます。予期しない障害では、RPO の決定(ギャップの許容、トラフィックの遅延、またはサブスクリプションの再構築)が必要です。回復した旧プライマリは、すぐに書き込みパスに再参加してはなりません。それを隔離し、物理レプリケーションを再構築し、スロットとサブスクリプションの状態を再確認します。
トレードオフと境界
- フェイルオーバースロットは論理レプリケーションの回復可能性を向上させますが、スロット同期と WAL 監視の複雑さを増大させます。
- 完全なスロット同期を待つとギャップは減少しますが、フェイルオーバー時間が長くなる可能性があります。
synchronized_standby_slotsは物理スタンバイに対する論理的な進行を制約しますが、すべての外部サブスクライバーに対してエンドツーエンドのゼロ損失を提供するわけではありません。- 無効なスロット、容量上限に近いストレージ、および長期間停止しているサブスクライバーには、切り替えスクリプトだけでなく、アラートとクリーンアップが必要です。
実装計画とエビデンス
- PostgreSQL 18 テストクラスターでフェイルオーバー論理スロットを作成し、プライマリ/スタンバイの設定と権限を確認する。
- サブスクライバーの停止、WAL の蓄積、非同期スロット、および突然のプライマリ喪失を注入し、LSN とリカバリ結果を記録する。
- 切り替え前の
pg_replication_slotsクエリを自動化し、そのスロットインベントリをサブスクライバーと比較する。 - 計画的および予期しない障害パスで、一時停止、昇格、再接続、追いつき、およびロールバックを訓練する。
- PostgreSQL 18 の Logical Replication Failover、Logical Decoding、および Streaming Replication のドキュメントに照らしてパラメータと制限を確認する。
よくある間違いとフォローアップ質問
間違い 1: スタンバイのデータがあることで論理的な引き継ぎ準備が整ったと思い込むこと
スロットの状態は非同期に同期されます。データページが追いついていることは、スロットの位置が使用可能であることを証明しません。同期フィールドと無効化フィールドを検査してください。
間違い 2: 物理レプリケーションの遅延のみを監視すること
サブスクライバーの消費、確認済みスロット LSN、保持されている WAL、およびビジネス遅延も監視してください。物理レプリケーションが正常に見えても、論理バックログが増加する可能性があります。
間違い 3: フェイルオーバーオプションを自動切り替えとして扱うこと
これはスロット状態の同期を有効にするものであり、スタンバイの昇格、接続の更新、または外部サブスクライバーの検証を行うものではありません。切り替えには依然としてオーケストレーションと訓練が必要です。
フォローアップ: スロットが同期される前に昇格できますか?
明示的な RPO、ギャップ、または再構築の決定がある場合に限られます。デフォルトのゲートは同期を待機し、結果を記録する必要があります。
フォローアップ: 重複消費をどのように回避しますか?
イベント ID またはソース LSN を永続化し、切り替え後に検証可能な位置から再開し、リプレイに対してべき等な処理と照合を使用します。