PostgreSQL 9でのレプリケーションのウォッチドッグ

ご挨拶。 私は自分で作った松葉杖を共有したいと思います。誰かが役に立つかもしれません。



主なものについて簡単に



状況をシミュレートします。PostgreSQLサーバーのクラスター(マスターとnレプリカ)があります。 雨の日が来て、1つ(または複数)のレプリカが落ちます。 理由は重要ではありません-鉄片が死亡し、クリーナーがモップでワイヤーを破損したか、UFOが一時的にサーバーの1つを放棄しました。 結果は1つです-レプリカが長い間横たわっていた場合、彼女自身が追いつくことはありませんでした。



その理由は、PostgreSQLの複製プロセス自体です。 データが到着すると、ジャーナルはディスクにドロップされます(デフォルトでは16MBのチャンク)。 ウィザードの構成では、wal_keep_segmentsオプションを使用します。これは、保存するXLOGの最後の部分の数を示します。 パラメータを16に等しくします。 これは、pg_xlogディレクトリに16個のログファイルが同時に存在し、17番目が出現すると、1番目をアーカイブに送信しようとすることを意味します(言い換えると、一定のローテーションがあります)。 そして、レプリカがこれらの16ファイルよりも遅れている場合-マスターに追い付こうとすると、ログに必要なXLOGを受信できないというメッセージが表示されます。 マスターで彼はすでにアーカイブに行きました。 そして、デフォルトのアーカイブコマンドは、原則として次のように見えるためです。



cp %p /var/lib/postgresql/9.0/main/archive/%f







ご覧のとおり、ファイルのアーカイブが誰かに害を及ぼすかどうかのチェックは行われません。

本質的に-これには致命的なものはありません-必要なアーカイブファイルが削除されていない場合は、適切な場所でレプリカにスリップするだけで、ファイル自体が「ロール」します。 不快な瞬間は、負荷に応じて、原則として、1つのファイルではなく、数十/数百/数千をコピーする必要があることです。 さらに、プロセスを監視する必要があります。 ファイルのみをコピーしている間-ウィザードは新しいファイルをアーカイブします。 最悪の場合、レプリカを完全に「リロード」することで保存できます。

そのような喜びに遭遇しないために、私はPerlとBashの混合物に関する小さなスクリプトを書きました。 私は事前に、最高のプログラマのふりをしてはいけません。主な条件はコードの美しさではなく、必要なアクションの実装でした。 スクリプトはここにありますが、今のところは何をするのかを正確に説明します。



仕組み



master01:~# ps aux|grep postg|grep sender

postgres 26132 0.0 0.0 6518660 3052 ? Ss 20:21 0:01 postgres: wal sender process postgres 192.168.12.1(36254) streaming 153/ED957E68

postgres 26133 0.0 0.0 6518660 3056 ? Ss 20:21 0:01 postgres: wal sender process postgres 192.168.12.2(51907) streaming 153/ED957E68

postgres 26135 0.0 0.0 6518660 3060 ? Ss 20:21 0:01 postgres: wal sender process postgres 192.168.12.3(39404) streaming 153/ED957E68

postgres 29142 0.0 0.0 6518724 3084 ? Ss 20:44 0:01 postgres: wal sender process postgres 192.168.12.4(51897) streaming 153/ED957E68

postgres 29320 0.0 0.0 6518724 3084 ? Ss 20:45 0:01 postgres: wal sender process postgres 192.168.12.5(49234) streaming 153/ED957E68

postgres 29453 0.0 0.0 6518724 3084 ? Ss 20:46 0:01 postgres: wal sender process postgres 192.168.12.6(35519) streaming 153/ED957E68









この単純なコマンドからわかるように、プロセスのリストで次を見つけることができます。

1.接続されたレプリカの数。IPアドレスを示します。

2.現在処理中のXLOGの一部。



そして、この設計を管理する人々として、レプリカの数とそのアドレスを知っています。 行の最後の部分に注目しましょう-これは特定のレプリカのXLOGの位置です。 この値からスラッシュを削除し、結果の最後の6文字を切り捨てると、153EDになります。 これは16進数です。



そしてプロセスのリストでこれを見つけることができます:



master01:~# ps aux|grep postg|grep arch

postgres 556 0.0 0.0 66184 1668 ? Ss Oct11 0:23 postgres: archiver process last was 0000000100000153000000EB








行の最後の部分は、アーカイブされたファイルです。 最後の13文字を取得し、それらから6つのゼロを連続して削除します。 153EBを取得します。



これらの2つの数値を比較すると、レプリカは最後にアーカイブされたものより2ステップ古いログを使用していることがわかります。したがって、1つのフラグメントを安全に削除できます。



これらの簡単な操作に基づいて、私のスクリプトは機能します。



1.管理者は、レプリカのリスト(1行に1つ)を/etc/postgresql/9.0/main/slaves.listに追加します。

2.スクリプトは、PostgreSQL構成のarchive_commandとして適合します。

3. XLOGの一部をアーカイブしようとすると、次のことが発生します。

3.1。 接続されたレプリカの数が構成で指定された数と一致するかどうかがチェックされます。

3.2。 すべてが正常な場合、ホストが構成で指定されたものに対応するかどうかを確認します(クラスターを拡張するときに構成に新しいレプリカを書き込むのを忘れた場合に行います)。

3.3。 レプリカ間の最小XLOG位置を計算します(最も遅れているものを探しています)。

3.4。 アーカイブするファイルの名前の数字と前の段落の数字を比較します。



すべての条件が満たされている場合-ファイルをアーカイブにコピーして0を返します。何か問題が発生した場合-1つを返します-PostgreSQLは試行が失敗したと見なし、しばらくすると次の試行を実行します。 /var/log/postgresql/9.0/watchdog.logでプロセスを監視できます



できた! レプリカのリストは、既存のDNSレコード(個人的な利便性のために作成)、または/ etc / hostsでローカルに指定された名前を示すことが理解されます。 これを無効にするには、47〜55行目をコメントアウトする必要があります。



All Articles