24.4. 高可用性のためのウォームスタンバイ

継続的アーカイブを使用して、プライマリサーバが停止した場合に操作を引き継ぐ準備がなされた1つ以上の待機サーバ高可用性 (HA)クラスタ設定を作成することができます。 この機能はよくウォームスタンバイログシッピングとして言及されます。

この機能のためにプライマリサーバと待機サーバは協調して動作しますが、サーバ間の関係はあまり強くありません。 プライマリサーバは継続的アーカイブモードで動作し、各待機サーバは継続的復旧モードで動作し、プライマリからのWALファイルを読み取ります。 この機能を有効にするために、データベーステーブルを変更する必要はありません。 ですので、他のリプリケーション手法と比べて、管理に係るオーバーヘッドが低くなります。 また、この設定がプライマリサーバに与える性能上の影響も相対的に低いものです。

1つのデータベースサーバから他へのWAL記録の直接的な移動はよく、ログシッピングと表現されます。 PostgreSQLは、ある時点でWAL記録が1ファイル(WALセグメント)として転送されることを意味するファイルベースのログシッピングを実装します。 WALファイル(16MB)は、距離的に近くのシステムであろうと、同じサイトの他のシステムであろうと、地球の反対側にあるシステムであろうが、簡単かつ安価に転送することができます。 この技法のために必要な帯域は、プライマリサーバのトランザクション比率に応じて変わります。 また、記録ベースのログシッピングも手続きを独自に開発することで可能です。 項24.4.4で説明します。

ログシッピングが非同期であることは注記しなければなりません。 つまり、トランザクションがコミットされた後にWAL記録が転送されます。 この結果、プライマリサーバで破滅的な失敗が起こり、転送前のトランザクションが失われた場合、データ損失期間が存在することになります。 archive_timeoutパラメータを使用することで、データ損失期間を制限することができます。 このパラメータは必要ならば数秒程度まで設定することができます。 しかし、こうした小さな値は、ファイル転送に必要な帯域を大きく増大させます。 1分未満程度のデータ損失期間が必要ならば、記録ベースのログシッピングを検討する方が良いでしょう。

待機サーバは、継続的に復旧処理を行っているため、アクセスには利用できません。 修復処理の性能は十分よく、一度実施されれば、待機サーバが完全な状態から逸脱するのは一時的にしかすぎません。 結果としてこの能力を、高可用性を提供するためのウォームスタンバイ設定として参照します。 保管済みのベースバックアップからのサーバのリストアとロールフォワードはおそらく長期間かかります。 このため、この技法は高可用性ではなく災害復旧時向けの対策を提供するだけです。

24.4.1. 計画

少なくともデータベースサーバの見地から、できる限り似せた形でプライマリサーバと待機サーバを作成することが通常のお勧めです。 具体的には、テーブル空間に関連したパス名はそのまま渡されますので、テーブル空間機能を使用する場合は、プライマリサーバと待機サーバのテーブル空間用のマウントポイントを同一にする必要があります。 プライマリサーバでCREATE TABLESPACEを実行する場合、コマンドを実行する前に、必要となる新しいマウントポイントをプライマリサーバ、待機サーバの両方で作成しなければならないことは覚えておいてください。 ハードウェアは正確に同じである必要はありません。 しかし、経験上、アプリケーションとシステムの有効期間を通して、2つの異なるシステムを管理するより2つの同一のシステムを管理するほうが簡単です。 いずれにしてもハードウェアアーキテクチャは同じでなければいけません。 たとえば32ビットシステムから64ビットシステムへのシッピングはうまく動作しません。

通常、PostgreSQLのメジャーリリースレベルで異なるサーバ間でのログシッピングは不可能です。 マイナーリリースの更新期間はディスク書式を変更しないというのが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();

restore_command に待機する実施例は pg_standby という名前のcontribモジュールとして提供されています。この例は特定の構成や環境を提供するため必要に応じて拡張できます。

PostgreSQLは、プライマリサーバでの失敗を識別し、スタンバイシステム、スタンバイデータベースサーバに通知するために必要なシステムソフトウェアを提供しません。 こうしたツールは多く存在し、これらにはIPアドレスの移行といった、他のフェイルオーバーを成功させるための機能も組み込まれています。

フェイルオーバーを通知する手段は計画・設計段階で重要な部分です。 restore_commandは各WALファイルに対して1度しか実行されません。 restore_commandを実行するプロセスは各ファイルに対して起動・終了します。 また、デーモンやサーバプロセスはありませんので、シグナルやシグナルハンドラを使用することはできません。 フェイルオーバーの通知には、より長持ちする通知機能が必要です。 三純なタイムアウト機能を使用することができます。 主にプライマリサーバ上の既知のarchive_timeout設定と連係して使用されます。 ネットワーク障害や高負荷なプライマリサーバによりフェイルオーバーが始まってしまうため、どちらかというとエラーになりやすいものです。 実現可能ならば、明示的な通知用ファイルの作成などの通知機構の方がエラーになりにくいです。

WALアーカイブの規模は restore_command%r オプションを使用して最小限に抑えられます。このオプションは復旧が適切に再起動するように保っていなければならないすぐ前のアーカイブファイル名を指定します。これは、アーカイブが待機サーバから書き込み可能であれば、ファイルが必要で無くなった場合アーカイブを破棄するためにも使用されます。

24.4.2. 実装

待機サーバの構築について短めの手順を以下に示します。 各段階の詳細については、注記していますので、前の節を参照してください。

  1. できる限り同じようにプライマリシステムとスタンバイシステムを設定してください。 同じリリースレベルのPostgreSQLの複製も含みます。

  2. プライマリサーバで、継続的アーカイブを待機サーバ上のディレクトリ上にWALを保管するように設定してください。 プライマリサーバで、archive_modearchive_commandおよびarchive_timeoutが適切に設定されていることを確認してください(項24.3.1を参照してください)。

  3. プライマリサーバでベースバックアップを作成(項24.3.2を参照してください)し、待機サーバでこのデータをロードしてください。

  4. 待機サーバで、上記の通り待機を行うrestore_commandを指定したrecovery.confを使用して、ローカルなWALアーカイブから復旧処理を実行してください。 (項24.3.3を参照してください。)

復旧処理はWALアーカイブを読み取りのみとして扱います。 このため、WALファイルがスタンバイシステムにコピーされた後、スタンバイデータベースサーバによる読み取りと同時にWALファイルをテープに複製することができます。 このように、高可用性待機サーバの実行を、長期災害復旧目的のための保管と同時に行うことができます。

試験のために、プライマリサーバとセカンダリサーバを同じシステムで稼動させることができます。 これによりサーバ堅牢性が向上することはありませんし、HAとして稼動するわけでもありません。

24.4.3. フェイルオーバー

プライマリサーバに障害が起こると、待機サーバはフェイルオーバー処理を始めなければなりません。

待機サーバに障害が起こると、必要なフェイルオーバーは行われません。 多少の時間の後に、待機サーバを再起動できれば、再起動可能な復旧処理のため、復旧プロセスも即座に再起動します。 待機サーバを再起動できなければ、新しい完全な待機サーバインスタンスが作成されなければなりません。

プライマリサーバに障害が起こり、その後すぐに再起動した場合、もはやプライマリサーバでなくなっていることを知らせる機構が必要です。 これはSTONITH (Shoot the Other Node In The Head)と一部ではいわれています。 これは、混乱と最悪はデータ損失をもたらしかねない、両システムが自身をプライマリとして認識してしまう状況を防ぐために必要です。

多くのフェイルオーバーシステムでは2つのシステムを使用します。 なんらかのハートビート機構でプライマリとセカンダリを接続し、両者の接続性とプライマリの実行能力を継続的に確認します。 また、第3のシステム(証言サーバと呼ばれます)を使用して、不適切なフェイルオーバーなどの状況を防ぐこともできます。 しかし、さらに複雑になりますので、十分な注意と厳密な検証の基に設定を行わない限り行う意味がありません。

待機サーバでフェイルオーバーが起きた後、運用可能なサーバは1つしかありません。 これは縮退状態として知られます。 以前の待機サーバはプライマリサーバになり、以前のプライマリは停止し、その後も停止し続けるかもしれません。 通常の運用に戻すには、待機サーバを再作成しなければなりません。 以前のプライマリサーバが起動できれば、これを使用しても構いませんし、第三のおそらく新規のシステムを使用しても構いません。 完了すれば、プライマリとスタンバイの役割が切り替わったとみなすことができます。 新しい待機サーバを再作成するまでに第3のサーバを使用して新しいプライマリのバックアップを提供することを選択する人もいますが、これがシステム設定と運用手順を複雑にすることは明らかです。

プライマリサーバから待機サーバへの切り替えは高速ですが、フェイルオーバークラスタを再度準備するのに多少時間が必要です。それぞれのシステムを保守のために定期的に停止することができるので、プライマリからスタンバイへの定期的切り替えは有益です。これは同時に、必要になった時、フェイルオーバー機構が実際に機能するかどうかを確認する試験としても役立ちます。管理手順の文書化を勧めます。

24.4.4. 記録ベースのシッピング

これまで説明したようにPostgreSQLはファイルベースのログシッピングを直接サポートします。 記録ベースのログシッピングを実装することも可能ですが、これには独自の開発が必要です。

外部プログラムから、WALの現在の終了点のファイル名と正確なバイトオフセットを見つけ出すpg_xlogfile_name_offset()関数(項9.23を参照)を呼び出すことができます。 そして、WALファイルに直接アクセスし、直前のWAL終了点から現在の終了点までのデータを待機サーバにコピーすることができます。 この方法では、データ損失期間はコピー処理プログラムの実行周期となります。 非常に短くすることができますが、強制的に部分的に使用されたセグメントファイルを保管するため無駄な帯域もありません。 待機サーバのrestore_commandスクリプトがWALファイル全体を扱い続けることに注意してください。 このため、逐次的にコピーしたデータは通常は待機サーバで利用することができません。 プライマリサーバが停止し再起動できるようになる前に最後の部分的なWALファイルがセカンダリサーバに渡される場合にのみこれが使用できます。 このため、この処理の正しい実装では、データコピープログラムとrestore_commandスクリプトとの連係が必要です。

24.4.5. 逐次的に更新されるバックアップ

ウォームスタンバイ構成では、 プライマリサーバから定期的なベースバックアップを取る手間を省くことができます。 代わりに、待機サーバのファイルをバックアップすることでベースバックアップを作成することができます。 この概念はよく逐次的に更新されたバックアップ、ログ変更累積、または簡単に、変更の累積と言われます。

プライマリサーバからのログシッピングを処理している間に、待機サーバのデータディレクトリをバックアップした場合、そのデータをリロードし、待機サーバの復旧処理を直前の再開点から再開始できます。再開点以前のWALファイルを保持する必要はなくなります。復旧が必要になったら、元のベースバックアップからの復旧よりも逐次的に更新されたバックアップからの復旧の方が高速です。

待機サーバは"活動状態"ではありませんので、バックアップ処理を管理するためにpg_start_backup()pg_stop_backup()を使用することはできません。 どのようにWALセグメントファイルを保持し復旧可能なバックアップを持つかは管理者に負かされています。 待機サーバでpg_controldataを実行し、制御ファイルを検査し、現在のチェックポイントWAL位置を決定するか、もしくはサーバログに値を log_restartpoints オプションで出力できます。

アダルトレンタルサーバー