クラスタの状態
複数のサーバで構成されるクラスタ構成を運用する場合、個々のサーバ単体は正常に稼働しているが、クラスタ全体のサービス状態としては異常が発生しているケースが考えられ、このようなクラスタ特有の障害事象に対応する必要があります。
今回のpgpool-II、PostgreSQLで構成するクラスタ環境では、具体的に以下の事象が想定されます。
- アクティブなpgpool-IIが複数存在する/1つも存在しない
- ストリーミングレプリケーションのプライマリサーバが複数存在する/1つも存在しない
- 同期レプリケーションのスタンバイがすべてダウンしている
- PostgreSQLのプライマリサーバに障害が発生した
pg_monzは、これらの障害事象を検出できるように実装されています。それぞれの障害事象を検出する様子を以下に紹介していきます。
アクティブなpgpool-IIが複数存在する/1つも存在しない
pgpool-IIをwatchdog機能で冗長化する場合、稼働する2台のpgpool-IIサーバのうち1台がアクティブサーバとなりクライアントからのアクセスに使う仮想IPが割り当てられます。
以下の例ではpgpool01、pgpool02がともに稼働しており、仮想IPがアクティブなpgpool01のみに割り当てられている(delegate_ip is existsがUP)ことが分かります。
つまり「仮想IPを保有するpgpool-IIはクラスタ全体で1つ」が正常な状態なので、仮想IPを保有するpgpool-IIが2つ以上存在する、あるいは1つも存在しない状態は異常として検出し、仮想IPの再割り当てなどの対応を早急に行う必要があります。
今回はpgpool02のサーバで「ifconfig eth1:0 192.168.1.100」を実行し、仮想IPを保有するpgpool-IIが2つ以上存在する状態を意図的に発生させてみます。実行後しばらくすると、pgpool02にも仮想IPが割当られている状態に変化します。
仮想IPが割り当てられたpgpool-IIが複数存在することを検出すると、pg_monzでは以下のように重度の障害として通知されます。アクティブな(仮想IPが割り当てられた)pgpool-IIが複数存在する事象はクライアントから正常にSQLを実行できてしまうため発見が遅れがちになりますが、pg_monzを使えば早期に発見と対処が可能です。
ストリーミングレプリケーションのプライマリサーバが複数存在する/1つも存在しない
PostgreSQLのストリーミングレプリケーションを利用する場合、1台がプライマリサーバとなり、その他はスタンバイサーバです。以下の例ではpgsql01がプライマリサーバ、pgsql02、pgsql03がスタンバイサーバとして起動していることが分かります。
つまり「プライマリサーバがクラスタ全体で1つ」が正常な状態なので、プライマリサーバが2つ以上存在する、あるいは1つも存在しない状態は異常として検出し、対処する必要があります。
今回はpgsql03のPostgreSQLサーバのrecovery.confを削除して再起動し、プライマリサーバが2つ存在する状態を意図的に発生させてみます。実行後しばらくすると、pgsql03がプライマリサーバとして認識された状態に変化します。
プライマリサーバが複数存在することを検出すると、pg_monzでは以下のように重度の障害として通知されます。
ストリーミングレプリケーションのプライマリサーバが複数存在する場合、それぞれのプライマリサーバが個別に更新を受け付けることができ、レプリケーションで担保されるべきデータベースの整合性が崩れてしまうため、できるだけ早期に解消させる必要がありますが、それぞれのPostgreSQLサーバに対しては正常にSQLが実行できるため発見が遅れがちになります。pg_monzを使えば早期に発見し対処することが可能です。
同期レプリケーションのスタンバイがすべてダウンしている
PostgreSQLで同期レプリケーションを利用する場合、1台がプライマリサーバ、1台が同期スタンバイサーバ、残りが非同期スタンバイサーバです。PostgreSQLの同期レプリケーションは、同期スタンバイサーバが存在しないとプライマリサーバに対する更新をブロックする仕様となっていますが、この状態でもプライマリサーバは正常に稼働しているように見えるため、発見しづらい事象と言えます。
今回はpgsql02、pgsql03のPostgreSQLサーバを手動で停止し、同期スタンバイサーバが存在しない状態を意図的に発生させてみます。実行後しばらくすると、pgsql02、pgsql03が停止した事象と同期スタンバイ不在のために更新処理がブロックされている事象が検出され、重度の障害として通知されます。
プライマリサーバに障害が発生した
pgpool-IIをマスタスレーブモードでPostgreSQLのストリーミングレプリケーションと組み合わせて運用する場合、PostgreSQLのプライマリサーバ、スタンバイサーバ停止時のフェイルオーバ操作をpgpool-IIで自動化することができます。そのためプライマリサーバに障害が発生しても即座にクラスタのサービスが停止することはありませんが、フェイルオーバが発生して縮退運転になっている状況は早めに把握して、障害サーバの復旧作業を開始したいところです。
今回はpgsql01のPostgreSQLサーバを手動で停止し、プライマリサーバの障害を意図的に発生させてみます。実行後しばらくすると、pgsql01が停止していることとpgsql02がプライマリサーバに昇格していることが分かります。
またフェイルオーバによりスタンバイサーバがプライマリサーバに昇格したことを検出すると、pg_monzでは以下のようにステータスが障害、深刻度は情報レベルとして通知されるので、この通知をきっかけにサーバ管理者はサーバの復旧作業を開始することが可能です。
最後に
本記事ではpg_monzがPostgreSQLの運用にどのように活用できるかを紹介しました。細かい機能については今回紹介した試行環境を使ってぜひご自身で動作を確認してみてください。また、実際に運用で使う場合に不都合な点や追加機能のアイデアなどのフィードバックをお待ちしています。pg_monzのような運用ツールが拡充されることで、PostgreSQLがより使いやすくなり、適用される範囲がより広がっていることを期待しています。
お問い合わせやフィードバックは以下のメーリングリストやGitHubのissueで受け付けています。
- pg_monzユーザーグループ(pg_monz@googlegroups.com)
- pg_monz開発GitHub