これまでの節で説明した組み込みのスタンバイモードの他の方法として、アーカイブ場所を順次問い合わせるrestore_command
を使用する方法があります。
これはバージョン8.4以前では唯一の利用可能な選択肢でした。
このリファレンス実装としてpg_standbyを参照してください。
このモードでは、サーバは1度に1つのWALファイルを適用することに注意してください。
このため問い合わせ用にスタンバイサーバを使用する場合(ホットスタンバイを参照)、マスタにおける動作とそれがスタンバイで可視になるまでの間に、WALファイルをみたすために必要とする時間に相当する、遅延が存在します。
archive_timeout
を使用して遅延を短くすることができます。
また、この方法とストリーミングレプリケーションと組み合わせることができないことにも注意してください。
プライマリおよびスタンバイサーバの両方で発生する操作は通常の継続的なアーカイブ処理とリカバリ処理です。 2つのデータベースサーバが連携する唯一の点は、両者が共有するWALファイルのアーカイブです。 プライマリがアーカイブに書き出し、スタンバイがアーカイブから読み取ります。 注意して他のプライマリサーバ由来のWALアーカイブが混在しないことを確実にしなければなりません。 さもないと混乱が発生します。 スタンバイ操作でのみ必要なものですので、アーカイブは必ずしも巨大になりません。
2つの疎結合サーバを協調させる秘訣は簡単で、スタンバイサーバにて使用されるrestore_command
です。
これは次のWALファイルを問い合わせ、それをプライマリから利用可能になるまで待機します。
このrestore_command
はスタンバイサーバのrecovery.conf
ファイルで指定されます。
通常のリカバリ処理はWALアーカイブからファイルを要求し、ファイルが利用できなければ失敗を報告します。
スタンバイ処理では、次のWALファイルを入手できないことは異常ではありませんので、スタンバイは利用可能になるまで待機しなければなりません。
.history
で終わるファイルについては、待機する必要はなく、非ゼロの終了コードを返さなければなりません。
restore_command
を待機させるには、次のWALファイルの存在を確認した後にループする独自のスクリプトを作成することで実現できます。
また、restore_command
に割り込み、ループを終了させ、ファイルが存在しないというエラーをスタンバイサーバに返す、フェイルオーバーを発生させる何らかの方法がなければなりません。
これがリカバリ処理を停止しますので、スタンバイサーバは通常のサーバになります。
restore_command
の擬似コードの一例は以下です。
triggered = false; while (!NextWALFileReady() && !triggered) { sleep(100000L); /* wait for ~0.1 sec */ if (CheckForExternalTrigger()) triggered = true; } if (!triggered) CopyWALFileForRecovery();
待機を行うrestore_command
の実例はpg_standbyモジュール内で提供されています。
これは上記のロジックをどのように正確に実装するかについての参照として使用すべきです。
また、これを特定の設定または環境をサポートするため必要に応じて拡張することができます。
フェイルオーバーを通知する手段は計画・設計段階で重要な部分です。
考えられる選択肢の1つはrestore_command
です。
これは各WALファイルに対して1度実行されるものですが、restore_command
を実行するプロセスは各ファイルに対して起動・終了します。
このようにデーモンやサーバプロセスはありませんので、シグナルやシグナルハンドラを使用することはできません。
したがって、restore_command
はフェイルオーバーの通知には適していません。
特にプライマリサーバ上の既知のarchive_timeout
設定と連係して使用できるならば、単純なタイムアウト機能を使用することができます。
しかし、これはネットワーク障害や高負荷なプライマリサーバによりフェイルオーバーが始まってしまうため、どちらかというとエラーになりやすいものです。
実現可能ならば、明示的な通知用ファイルの作成などの通知機構の方が理想的です。
この代替方式を使用してスタンバイサーバを構築する短めの手順を以下に示します。 各段階の詳細については、注記していますので、前の節を参照してください。
できる限り同じようにプライマリシステムとスタンバイシステムを設定してください。 同じリリースレベルのPostgreSQLの同一コピーの導入も含みます。
プライマリサーバで、継続的アーカイブをスタンバイサーバ上のディレクトリ上にWALをアーカイブするように設定してください。 プライマリサーバで、archive_mode、archive_commandおよびarchive_timeoutが適切に設定されていることを確認してください(25.3.1を参照してください)。
プライマリサーバでベースバックアップを作成(25.3.2を参照してください)し、スタンバイサーバでこのデータをロードしてください。
スタンバイサーバで、上記の通り待機を行うrestore_command
を使用して、ローカルなWALアーカイブからリカバリ処理を実行してください(25.3.4を参照してください)。
リカバリ処理はWALアーカイブを読み取り専用として扱います。 このため、WALファイルがスタンバイシステムにコピーされた後、スタンバイデータベースサーバによる読み取りと同時にWALファイルをテープにコピーすることができます。 このように、高可用性スタンバイサーバの実行を、災害からのリカバリを目的とした長期的な保管と同時に行うことができます。
試験のためにプライマリサーバとスタンバイサーバを同じシステムで稼動させることができます。 これによりサーバ堅牢性が向上することも、高可用性と呼べることもありません。
この代替手法を用いたレコード単位のログシッピングの実装も可能ですが、利用者側の開発が必要です。 さらに、完全なWALファイルが転送された後のみで、変更がホットスタンバイ問い合わせで可視になります。
外部プログラムはpg_walfile_name_offset()
関数(9.26を参照)を呼び出して、WALの現在の終了点のファイル名と正確なバイトオフセットを見つけ出すことができます。
そして、WALファイルに直接アクセスし、直前の既知のWAL終了点から現在の終了点までのデータをスタンバイサーバにコピーすることができます。
この方法では、データ損失期間はコピー処理プログラムの実行周期となります。
非常に短くすることができますし、部分的に使用されたセグメントファイルを強制的にアーカイブするため無駄な帯域もありません。
スタンバイサーバのrestore_command
スクリプトがWALファイル全体しか扱うことができないことに注意してください。
このため、逐次的にコピーしたデータは通常はスタンバイサーバで利用することができません。
プライマリサーバが停止した時のみこれを使用します。
その場合、プライマリサーバが立ち上がる前に、最後の部分的なWALファイルがセカンダリサーバに渡されます。
この処理の正しい実装では、データコピープログラムとrestore_command
スクリプトとの連係が必要です。
PostgreSQLバージョン9.0から、同じ利点をより少ない設定で実現できるストリーミングレプリケーション(26.2.5参照)を使用することができます。