継続的アーカイブを使用して、プライマリサーバが停止した場合に操作を引き継ぐ準備がなされた1つ以上のスタンバイサーバで高可用性 (HA)クラスタ設定を作成することができます。 この機能はよくウォームスタンバイやログシッピングとして参照されます。
この機能のためにプライマリサーバとスタンバイサーバは協調して動作しますが、サーバ間の関係はあまり強くありません。 プライマリサーバは継続的アーカイブモードで動作し、各スタンバイサーバは継続的復旧モードで動作し、プライマリからのWALファイルを読み取ります。 この機能を有効にするために、データベーステーブルを変更する必要はありません。 ですので、他のリプリケーション手法と比べて、管理に係るオーバーヘッドが低くなります。 また、この設定がプライマリサーバに与える性能上の影響も相対的に低いものです。
1つのデータベースサーバから他へのWALまたは"ログ"記録の直接的な移動はよく、ログシッピングとして解説されます。 PostgreSQLは、ある時点でWAL記録が1ファイル(WALセグメント)として転送されることを意味するファイルベースのログシッピングを実装します。 WALファイルは、距離的に近くのシステムであろうと、同じサイトの他のシステムであろうと、地球の反対側にあるシステムであろうが、簡単かつ安価に転送することができます。 この技法のために必要な帯域は、プライマリサーバのトランザクション比率に応じて変わります。 また、記録ベースのログシッピングも手続きを独自に開発することで可能です。 項23.4.4で説明します。
ログシッピングが非同期であることは注記しなければなりません。 つまり、トランザクションがコミットされた後にWAL記録が転送されます。 この結果、プライマリサーバで破滅的な失敗が起こり、転送前のトランザクションが失われた場合、データ損失期間が存在することになります。 archive_timeoutパラメータを使用することで、データ損失期間を制限することができます。 このパラメータは必要ならば数秒程度まで設定することができます。 しかし、こうした小さな値は、ファイル転送に必要な帯域を大きく増大させます。 1分未満程度のデータ損失期間が必要ならば、記録ベースのログシッピングを検討する方が良いでしょう。
スタンバイサーバは、継続的に復旧処理を行っているため、アクセスには利用できません。 修復処理の性能は十分よく、一度実施されれば、スタンバイサーバが完全な状態から逸脱するのは一時的にしかすぎません。 結果としてこの能力を、高可用性を提供するためのウォームスタンバイ設定として参照します。 保管済みのベースバックアップからのサーバのリストアとロールフォワードはおそらく長期間かかります。 このため、この技法はHAではなく災害からの復旧向けの対策を提供します。
少なくともデータベースサーバの見地から、できる限り似せた形でプライマリサーバとスタンバイサーバを作成することが通常のお勧めです。 具体的には、テーブル空間に関連したパス名はそのまま渡されますので、テーブル空間機能を使用する場合は、プライマリサーバとスタンバイサーバのテーブル空間用のマウントポイントを同一にする必要があります。 プライマリサーバでCREATE TABLESPACEを実行する場合、コマンドを実行する前に、必要となる新しいマウントポイントをプライマリサーバ、スタンバイサーバの両方で作成しなければならないことは覚えておいてください。 ハードウェアは正確に同じである必要はありません。 しかし、経験上、アプリケーションとシステムの有効期間を通して、2つの異なるシステムを管理するより2つの同一のシステムを管理するほうが簡単です。 いずれにしてもハードウェアアーキテクチャは同じでなければいけません。 たとえば32ビットシステムから64ビットシステムへのシッピングはうまく動作しません。
通常、メジャーリリースレベルで異なるサーバ間でのログシッピングは不可能です。 マイナーリリースの更新期間はディスク書式を変更しないというのがPostgreSQLグローバル開発グループの方針ですので、プライマリサーバとスタンバイサーバとの間でマイナーリリースレベルの違いがあってもうまく動作するはずです。 しかし、この場合、公的なサポートは提供されません。 できる限りプライマリサーバとスタンバイサーバとで同じリリースレベルを使用してください。 新しいマイナーリリースに更新する場合、もっとも安全な方針はスタンバイサーバを先に更新することです。 新しいマイナーリリースは以前のマイナーリリースのWALファイルを読み込むことはできますが、逆はできないかもしれません。
スタンバイサーバを有効にするために必要な特殊なモードは存在しません。 プライマリサーバとスタンバイサーバで発生する操作は、完全に通常の継続的アーカイブと継続的復旧作業です。 2つのデータベースサーバが連係する唯一の点は、両者で共有されるWALファイルのアーカイブです。 プライマリサーバはこのアーカイブを書き出し、スタンバイサーバはこれを読み込みます。 別のプライマリサーバ向けのWALアーカイブが紛れ込まないように注意しなければなりません。 さもないと混乱します。
2つの疎に関連したサーバを協調させる魔法は単純で、スタンバイサーバで使用されるrestore_commandです。 これはプライマリサーバで利用可能となった次のWALファイルを待機します。 このrestore_commandはスタンバイサーバのrecovery.confファイルで指定されます。 通常の復旧処理はWALファイルからファイルを要求し、ファイルが利用できなければ失敗します。 スタンバイ処理では、通常は次のファイルは利用できませんので、この状態を許容し、利用可能になるまで待機しなければなりません。 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();
PostgreSQLは、プライマリサーバでの失敗を識別し、スタンバイシステム、スタンバイデータベースサーバに通知するために必要なシステムソフトウェアを提供しません。 こうしたツールは多く存在し、これらにはIPアドレスの移行といった、他のフェイルオーバーを成功させるための機能も組み込まれています。
フェイルオーバーを通知する手段は計画・設計段階で重要な部分です。 restore_commandは各WALファイルに対して1度しか実行されません。 restore_commandを実行するプロセスは各ファイルに対して起動・終了します。 また、デーモンやサーバプロセスはありませんので、シグナルやシグナルハンドラを使用することはできません。 フェイルオーバーの通知には、より長持ちする通知機能が必要です。 三純なタイムアウト機能を使用することができます。 主にプライマリサーバ上の既知のarchive_timeout設定と連係して使用されます。 ネットワーク障害や高負荷なプライマリサーバによりフェイルオーバーが始まってしまうため、どちらかというとエラーになりやすいものです。 実現可能ならば、明示的な通知用ファイルの作成などの通知機構の方がエラーになりにくいです。
スタンバイサーバの構築について短めの手順を以下に示します。 各段階の詳細については、注記していますので、前の節を参照してください。
できる限り同じようにプライマリシステムとスタンバイシステムを設定してください。 同じリリースレベルのPostgreSQLの複製も含みます。
プライマリサーバで、継続的アーカイブをスタンバイサーバ上のディレクトリ上にWALを保管するように設定してください。 プライマリサーバで、archive_commandおよびarchive_timeoutが適切に設定されていることを確認してください(項23.3.1を参照してください)。
プライマリサーバでベースバックアップを作成(項23.3.2を参照してください)し、スタンバイサーバでこのデータをロードしてください。
スタンバイサーバで、上記の通り待機を行うrestore_commandを指定したrecovery.confを使用して、ローカルなWALアーカイブから復旧処理を実行してください。 (項23.3.3を参照してください。)
復旧処理はWALアーカイブを読み取りのみとして扱います。 このため、WALファイルがスタンバイシステムにコピーされた後、スタンバイデータベースサーバによる読み取りと同時にWALファイルをテープに複製することができます。 このように、高可用性スタンバイサーバの実行を、長期災害復旧目的のための保管と同時に行うことができます。
試験のために、プライマリサーバとセカンダリサーバを同じシステムで稼動させることができます。 これによりサーバ堅牢性が向上することはありませんし、HAとして稼動するわけでもありません。
プライマリサーバに障害が起こると、スタンバイサーバはフェイルオーバー処理を始めなければなりません。
スタンバイサーバに障害が起こると、必要なフェイルオーバーは行われません。 多少の時間の後に、スタンバイサーバを再起動できれば、再起動可能な復旧処理のため、復旧プロセスも即座に再起動します。 スタンバイサーバを再起動できなければ、新しい完全なスタンバイサーバを用意しなければなりません。
プライマリサーバに障害が起こり、その後すぐに再起動した場合、もはやプライマリサーバでなくなっていることを知らせる機構が必要です。 これはSTONITH (Shoot the Other Node In The Head)と一部ではいわれています。 これは、混乱と最悪はデータ損失をもたらす、両システムが自身をプライマリとして認識してしまう状況を防ぐために必要です。
多くのフェイルオーバーシステムでは2つのシステムを使用します。 なんらかのハートビート機構でプライマリとセカンダリを接続し、両者の接続性とプライマリの実行能力を継続的に確認します。 また、第3のシステム(証言サーバと呼ばれます)を使用して、不適切なフェイルオーバーなどの問題を防ぐこともできます。 しかし、さらに複雑になりますので、十分な注意と厳密な試験をもって設定を行わない限り有益ではありません。
スタンバイサーバでフェイルオーバーが起きた後、運用可能なサーバは1つしかありません。 これは縮退状態として知られます。 以前のスタンバイサーバはプライマリサーバになり、以前のプライマリは停止し、その後も停止し続けるかもしれません。 通常の運用に戻すには、スタンバイサーバを再作成しなければなりません。 以前のプライマリサーバが起動できれば、これを使用しても構いませんし、第三のおそらく新規のシステムを使用しても構いません。 完了すれば、プライマリとスタンバイの役割が切り替わったとみなすことができます。 新しいスタンバイサーバを再作成するまでに第3のサーバを使用して新しいプライマリのバックアップを提供することを選択する人もいますが、これがシステム設定と運用手順を複雑にすることは明らかです。
プライマリサーバからスタンバイサーバへの切り替えは高速ですが、フェイルオーバークラスタを再度準備するのに多少時間が必要です。 各システムを保守のために停止することもできますので、通常でもプライマリからスタンバイへの切り替えが起こります。 これを、障害時に必要な作業が本当に行われるかを確認する、フェイルオーバー機構の試験として活用できます。 上述の管理手順をお勧めします。
これまで説明したようにPostgreSQLはファイルベースのログシッピングを直接サポートします。 記録ベースのログシッピングを実装することも可能ですが、これには独自の開発が必要です。
外部プログラムから、WALの現在の終了点のファイル名と正確なバイトオフセットを見つけ出すpg_xlogfile_name_offset()
関数(項9.20を参照)を呼び出すことができます。
そして、WALファイルに直接アクセスし、直前のWAL終了点から現在の終了点までのデータをスタンバイサーバにコピーすることができます。
この方法では、データ損失期間はコピー処理プログラムの実行周期となります。
非常に短くすることができますが、強制的に部分的に使用されたセグメントファイルを保管するため無駄な帯域もありません。
スタンバイサーバのrestore_commandスクリプトがWALファイル全体を扱い続けることに注意してください。
このため、逐次的にコピーしたデータは通常はスタンバイサーバで利用することができません。
プライマリサーバが停止し再起動できるようになる前に最後の部分的なWALファイルがセカンダリサーバに渡される場合にのみこれが使用できます。
このため、この処理の正しい実装では、データコピープログラムとrestore_commandスクリプトとの連係が必要です。
ウォームスタンバイ構成では、 プライマリサーバから定期的なベースバックアップを取る手間を省くことができます。 代わりに、スタンバイサーバのファイルをバックアップすることでベースバックアップを作成することができます。 この概念はよく逐次的に更新されるバックアップ、ログ累積、または簡単に、変更の累積といわれます。
スタンバイサーバのファイルをバックアップし、プライマリサーバからログシッピングされている場合、そのデータをリロードし、直前の再開点から復旧処理を再開することができます。 再開点以前のWALファイルを保持する必要はなくなります。 復旧が必要になったら、元のベースバックアップからの復旧よりも逐次的に更新されたバックアップからの復旧の方が高速です。
スタンバイサーバは"活動状態"ではありませんので、バックアップ処理を管理するためにpg_start_backup()
とpg_stop_backup()
を使用することはできません。
どのようにWALセグメントファイルを保持し復旧可能なバックアップを持つかは管理者に負かされています。
スタンバイサーバでpg_controldataを実行し、制御ファイルを検査し、現在のチェックポイントWAL位置を決定することで、これを行うことができます。