pg_rewind — PostgreSQLのデータディレクトリを、そこから派生した他のデータディレクトリと同期する
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.conf
のwal_log_hintsオプションが有効になっているか、initdbでクラスタを初期化した時にデータチェックサムが有効になっていなければなりません。
どちらもデフォルトではonではありません(無効です)。
full_page_writesもon
(有効)でなければなりませんが、これはデフォルトで有効です。
処理中に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アーカイブから取り出します。
--debug
主に開発者がpg_rewindをデバッグするのに役立つ冗長なデバッグ出力を印字します。
--no-ensure-shutdown
pg_rewindは、巻き戻す前にターゲットサーバが正常にシャットダウンされていることを要求します。 デフォルトでは、ターゲットサーバが正常にシャットダウンされていなければ、pg_rewindはターゲットサーバをシングルユーザモードで起動し、まずクラッシュリカバリを完了して停止します。 このオプションを渡すことで、pg_rewindはこれを飛ばして、サーバが正常にシャットダウンされていない場合にはすぐにエラーを発生します。 その場合、ユーザが自身で状況を扱うことが期待されます。
-V
--version
バージョン情報を表示して終了します。
-?
--help
ヘルプを表示して終了します。
--source-server
オプションを使用する場合、pg_rewindは
libpqで利用できる環境変数を使用します(33.14を参照)。
環境変数PG_COLOR
は診断メッセージで色を使うかどうかを指定します。
可能な値はalways
、auto
、never
です。
オンラインのクラスタをソースとして使用して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;
最近に昇格したオンラインのクラスタをソースとして使ってpg_rewindを実行するときには、コントロールファイルが最新のタイムライン情報を反映するように昇格後にCHECKPOINT
を実行する必要があります。
タイムライン情報はpg_rewindが指定されたソースクラスタを使ってターゲットクラスタを巻き戻しできるかどうか検査するのに使われます。
基本的なアイデアは、ファイルシステムレベルの変更を、すべてをソースクラスタからターゲットクラスタにコピーする、というものです。
ソースクラスタのタイムライン履歴がターゲットクラスタから分岐した時点より前の最後のチェックポイントから始めて、ターゲットクラスタのWALログをスキャンします。
各々のWALレコードについて、変更されたデータブロックを記録します。
これにより、ソースクラスタが分岐した以降に、ターゲットクラスタで変更されたすべてのデータブロックのリストが作成されます。
WALファイルの中にもう存在しないものがある場合は、失われたファイルをWALアーカイブで探すよう-c
オプションを付けてpg_rewindを再実行してみます。
ファイルシステムへの直接アクセス(--source-pgdata
)かSQL (--source-server
)を使って、変更のあったすべてのブロックを、ソースクラスタからターゲットクラスタにコピーします。
これでリレーションファイルは、ソースとターゲットのWALタイムラインが分岐した時点より前で最後に完了したチェックポイントの時点に加えて、分岐後にターゲットで変更されたブロックを含んだソースでの現在の状態に相当する状態になります。
新しいリレーションファイルやWALセグメント、pg_xact
や設定ファイルなどを含めて、それ以外のファイルをすべてソースクラスタからターゲットクラスタにコピーします。
ベースバックアップと同様に、ディレクトリpg_dynshmem/
、pg_notify/
、pg_replslot/
、pg_serial/
、pg_snapshots/
、pg_stat_tmp/
、および、pg_subtrans/
の内容は、ソースクラスタからコピーされるデータから省かれます。
pgsql_tmp
で始まるすべてのファイルやディレクトリは省かれます。
ファイルbackup_label
、tablespace_map
、pg_internal.init
、postmaster.opts
、および、postmaster.pid
も同様です。
フェイルオーバーで作成されたチェックポイントでWALリプレイを開始するためにbackup_label
ファイルを作成し、動作中のソースから巻き戻す場合にはpg_current_wal_insert_lsn()
の結果として定義される最小の整合のとれたLSNを、停止したソースから巻き戻す場合には最後のチェックポイントLSNをpg_control
ファイルに設定します。
ターゲットが起動すると、PostgreSQLは必要なWALをすべてリプレイします。それにより、データディレクトリが整合のとれた状態になります。