pg_rewind

pg_rewindPostgreSQLのデータディレクトリを、そこから派生した他のデータディレクトリと同期する

概要

pg_rewind [option...] { -D | --target-pgdata } directory { --source-pgdata=directory | --source-server=connstr }

説明

pg_rewindは、PostgreSQLのクラスタのタイムラインが分岐した後、クラスタをその複製のクラスタに同期するためのツールです。 典型的なシナリオとしては、フェイルオーバー後、新しいプライマリに追従するスタンバイとして、古いプライマリサーバをオンラインに戻す、というのがあります。

巻き戻し(rewind)が成功すれば、ターゲットデータディレクトリの状態はソースデータディレクトリのベースバックアップと類似したものになります。 新しいベースバックアップを取ったり、rsyncのようなツールを使うのとは異なり、pg_rewindはクラスタ内の変更されていないリレーションブロックの比較やコピーを必要としません。 既存のリレーションファイルのうちの変化のあったブロックだけがコピーされます。それ以外のすべてのファイルは、新しいリレーションファイルや設定ファイル、WALセグメントを含め、すべてのファイルがコピーされます。 そのため、データベースが大きく、クラスタ間で変更されているブロックの割合が小さい場合には、巻き戻し操作は他の方法に比べて極めて高速になります。

pg_rewindはソースとターゲットクラスタ内のタイムラインヒストリーを調べ、それらがどの時点で異なるものになったのかを調べます。 差異が発生した分岐点までずっと遡ることにより、ターゲットクラスタ内のpg_walディレクトリ内の分岐点に到達するWALを見つけようとします。 変化の分岐点は、ターゲット側のタイムライン中、ソース側のタイムライン中、あるいはそれら共通の祖先の中に見つかる可能性が高いです。 分岐点のあと間をおかずシャットダウンされたような典型的なフェイルオーバーのシナリオにおいては、これは特に問題になりません。 しかし、分岐点の後にターゲットクラスタが長時間運用されていた場合には、古いWALファイルはもう存在しないかもしれません。 この場合は、WALアーカイブから手動でpg_walディレクトリにコピーできます。 あるいは、-cオプションを付けてpg_rewindを実行し、WALアーカイブから自動的に取り出すこともできます。 pg_rewindの利用は、フェイルオーバーに留まりません。 たとえば、スタンバイサーバが昇格してから書き込みトランザクションを実行し、再びスタンバイになるために巻き戻すこともできます。

pg_rewindを実行した後、データディレクトリが整合のとれた状態になるためにはWALリプレイの完了が必要です。 ターゲットサーバは再起動すると、アーカイブリカバリに入り、分岐点の前の最後のチェックポイント以降にソースサーバで生成されたWALをすべてリプレイします。 pg_rewindが実行された時にWALの中にソースサーバにないものがあり、pg_rewindのセッションではコピーできなかった場合は、ターゲットサーバが起動した時にWALを読む込めるようになっていなければなりません。 recovery.signalファイルをターゲットデータディレクトリに置き、postgresql.confに適切なrestore_commandを設定することで、これを達成できます。

pg_rewindを使用するには、ターゲットサーバ上でpostgresql.confwal_log_hintsオプションが有効になっているか、initdbでクラスタを初期化した時にデータチェックサムが有効になっていなければなりません。 どちらもデフォルトではonではありません(無効です)。 full_page_writeson(有効)でなければなりませんが、これはデフォルトで有効です。

警告: 巻き戻し中の失敗

処理中にpg_rewindが失敗した場合、ターゲットのデータフォルダーはリカバリ可能な状態でない可能性があります。 このような場合は、最新のバックアップを取ることをお勧めします。

pg_rewindはソースから設定ファイルをそのままコピーするので、特にターゲットをソースのスタンバイとして再導入する場合には、ターゲットサーバを再起動する前にリカバリのために使われる設定を修正することが必要かもしれません。 巻き戻し操作は終わったもののリカバリの設定をせずにサーバを再起動すると、ターゲットは再びプライマリから分岐するでしょう。

pg_rewindは直接書き込めないファイルが見つかるとすぐに失敗します。 たとえば、ソースサーバとターゲットサーバが読み取り専用のSSLキーと証明書に同じファイルマッピングを使用する場合に発生します。 そのようなファイルがターゲットサーバ上に存在する場合、それらを削除してからpg_rewindを実行することをお勧めします。 巻き戻しを行った後、それらのファイルの一部がソースからコピーされている可能性があります。 その場合は、コピーされたデータを削除して、巻き戻し前に使用していたリンクのセットを元に戻す必要があります。

オプション

pg_rewindは以下のコマンドラインオプションを受け付けます。

-D directory
--target-pgdata=directory

このオプションは、同期するターゲットデータディレクトリを指定します。 ターゲットサーバは、pg_rewindを実行する前に、正常にシャットダウンされていなければなりません。

--source-pgdata=directory

同期するソースサーバのデータディレクトリへのファイルシステム上のパスを指定します。 このオプションを使用する場合は、ソースサーバは正常にシャットダウンされていなければなりません。

--source-server=connstr

ターゲットサーバに同期するソースPostgreSQLサーバに接続するlibpq接続文字列を指定します。 接続は、ソースサーバ(詳しくは注釈を参照)でpg_rewindで使われる関数を実行する権限を持つロールまたはスーパーユーザロールでの通常の(レプリケーションでない)接続でなければなりません。 このオプションはソースサーバが実行中であることと接続を受け付けることを必要とします。

-R
--write-recovery-conf

出力ディレクトリでstandby.signalを作成し、postgresql.auto.confに接続設定を追加します。 このオプションでは--source-serverは必須です。

-n
--dry-run

ターゲットディレクトリを実際に更新する以外はすべてのことを行います。

-N
--no-sync

デフォルトでは、pg_rewindはファイルがすべて安全にディスクに書き込まれるのを待ちます。 このオプションにより、pg_rewindは待つことなく戻るようになります。これは速いのですが、直後にオペレーティングシステムがクラッシュした場合、データディレクトリの破損が残るかもしれません。 一般に、このオプションはテストするためには有用ですが、稼働用のインストレーションでは使うべきではありません。

-P
--progress

進行状況のレポートを有効にします。このオプションを有効にすると、データをソースクラスタからコピーする際のおおよその進行状況をレポートします。

-c
--restore-target-wal

WALファイルがpg_walディレクトリにもはや存在しない場合、ターゲットクラスタ設定内で定義されているrestore_commandを使ってWALファイルをWALアーカイブから取り出します。

--config-file=filename

ターゲットクラスタ用に指定されたメインサーバ設定ファイルを使用します。 これは、pg_rewindがこのクラスタ上での巻き戻し操作のためにpostgresコマンドを内部的に使用している場合(-c/--restore-target-walオプションを指定してrestore_commandを取得している場合や、クラッシュリカバリの完了を強制する場合)に影響します。

--debug

主に開発者がpg_rewindをデバッグするのに役立つ冗長なデバッグ出力を印字します。

--no-ensure-shutdown

pg_rewindは、巻き戻す前にターゲットサーバが正常にシャットダウンされていることを要求します。 デフォルトでは、ターゲットサーバが正常にシャットダウンされていなければ、pg_rewindはターゲットサーバをシングルユーザモードで起動し、まずクラッシュリカバリを完了して停止します。 このオプションを渡すことで、pg_rewindはこれを飛ばして、サーバが正常にシャットダウンされていない場合にはすぐにエラーを発生します。 その場合、ユーザが自身で状況を扱うことが期待されます。

-V
--version

バージョン情報を表示して終了します。

-?
--help

ヘルプを表示して終了します。

環境

--source-serverオプションを使用する場合、pg_rewindlibpqで利用できる環境変数を使用します(34.15を参照)。

環境変数PG_COLORは診断メッセージで色を使うかどうかを指定します。 可能な値はalwaysautoneverです。

注釈

オンラインのクラスタをソースとして使用してpg_rewindを実行するとき、スーパーユーザの代わりにソースのクラスタ上でpg_rewindで使われる関数を実行できる権限を持ったロールを使うことができます。 rewind_userという名前のこのようなロールの作り方を以下に示します。

CREATE USER rewind_user LOGIN;
GRANT EXECUTE ON function pg_catalog.pg_ls_dir(text, boolean, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_stat_file(text, boolean) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text) TO rewind_user;
GRANT EXECUTE ON function pg_catalog.pg_read_binary_file(text, bigint, bigint, boolean) TO rewind_user;

どうやって動くのか

基本的なアイデアは、ファイルシステムレベルの変更を、すべてをソースクラスタからターゲットクラスタにコピーする、というものです。

  1. ソースクラスタのタイムライン履歴がターゲットクラスタから分岐した時点より前の最後のチェックポイントから始めて、ターゲットクラスタのWALログをスキャンします。 各々のWALレコードについて、変更されたデータブロックを記録します。 これにより、ソースクラスタが分岐した以降に、ターゲットクラスタで変更されたすべてのデータブロックのリストが作成されます。 WALファイルの中にもう存在しないものがある場合は、失われたファイルをWALアーカイブで探すよう-cオプションを付けてpg_rewindを再実行してみます。

  2. ファイルシステムへの直接アクセス(--source-pgdata)かSQL (--source-server)を使って、変更のあったすべてのブロックを、ソースクラスタからターゲットクラスタにコピーします。 これでリレーションファイルは、ソースとターゲットのWALタイムラインが分岐した時点より前で最後に完了したチェックポイントの時点に加えて、分岐後にターゲットで変更されたブロックを含んだソースでの現在の状態に相当する状態になります。

  3. 新しいリレーションファイルやWALセグメント、pg_xactや設定ファイルなどを含めて、それ以外のファイルをすべてソースクラスタからターゲットクラスタにコピーします。 ベースバックアップと同様に、ディレクトリpg_dynshmem/pg_notify/pg_replslot/pg_serial/pg_snapshots/pg_stat_tmp/、および、pg_subtrans/の内容は、ソースクラスタからコピーされるデータから省かれます。 pgsql_tmpで始まるすべてのファイルやディレクトリは省かれます。 ファイルbackup_labeltablespace_mappg_internal.initpostmaster.opts、および、postmaster.pidも同様です。

  4. フェイルオーバーで作成されたチェックポイントでWALリプレイを開始するためにbackup_labelファイルを作成し、動作中のソースから巻き戻す場合にはpg_current_wal_insert_lsn()の結果として定義される最小の整合のとれたLSNを、停止したソースから巻き戻す場合には最後のチェックポイントLSNをpg_controlファイルに設定します。

  5. ターゲットが起動すると、PostgreSQLは必要なWALをすべてリプレイします。それにより、データディレクトリが整合のとれた状態になります。