pg_rewind — PostgreSQLのデータディレクトリを、そこから派生した他のデータディレクトリと同期する
pg_rewind [option...] { -D | --target-pgdata } directory { --source-pgdata= | directory--source-server= } connstr
pg_rewindは、PostgreSQLのクラスタのタイムラインが分岐した後、クラスタをその複製のクラスタに同期するためのツールです。 典型的なシナリオとしては、フェイルオーバー後、新しいマスターに追従するスタンバイとして、古いマスターサーバをオンラインに戻す、というのがあります。
実行結果は、ターゲットデータディレクトリをソースディレクトリと置き換えたのと等しくなります。 リレーションファイルのうちの変化のあったブロックだけがコピーされます。 それ以外のすべてのファイルは、設定ファイルを含め、すべてのファイルがコピーされます。 新しいベースバックアップを取ったり、rsyncのようなツールを使う場合と比較して、pg_rewindはクラスタ内の変更されていないブロックを読出す必要がないという利点があります。 データベースが大きく、クラスタ間で変更されているブロックの割合が小さい場合には、極めて高速になります。
pg_rewindはソースとターゲットクラスタ内のタイムラインヒストリーを調べ、それらがどの時点で異なるものになったのかを調べます。
差異が発生した分岐点までずっと遡ることにより、ターゲットクラスタ内のpg_walディレクトリ内の分岐点に到達するWALを見つけようとします。
変化の分岐点は、ターゲット側のタイムライン中、ソース側のタイムライン中、あるいはそれら共通の祖先の中に見つかる可能性が高いです。
分岐点のあと間をおかずシャットダウンされたような典型的なフェイルオーバーのシナリオにおいては、これは特に問題になりません。
しかし、分岐点の後にターゲットクラスタが長時間運用されていた場合には、古いWALファイルはもう存在しないかもしれません。
この場合は、WALアーカイブから手動でpg_walディレクトリにコピーすることができます。
あるいは、recovery.confを設定することにより、起動時に取得できます。
pg_rewindの利用は、フェイルオーバーに留まりません。
たとえば、スタンバイサーバは昇格してから書き込みトランザクションを実行し、再びスタンバイになるために巻き戻すこともできます。
pg_rewindを実行した後、最初にターゲットサーバを起動すると、そのサーバはリカバリモードに入り、分岐点以降ソースサーバで生成されたWALをすべてリプレイします。
pg_rewindが実行された時にWALがソースサーバになくてpg_rewindのセッションではコピーできなかった場合は、ターゲットサーバが起動した時にWALを読む込めるようになっていなければなりません。
適切なrestore_commandを設定したrecovery.confファイルをターゲットデータディレクトリに置くことで、これを達成できます。
pg_rewindを使用するには、ターゲットサーバ上でpostgresql.confのwal_log_hintsオプションが有効になっているか、initdbでクラスタを初期化した時にデータチェックサムが有効になっていなければなりません。
どちらもデフォルトでは無効です。
full_page_writesも有効でなければなりませんが、これはデフォルトで有効です。
処理中に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で使われる関数を実行する権限を持つロールまたはスーパーユーザロールでの通常の(レプリケーションでない)接続でなければなりません。 このオプションはソースサーバが実行中であることとリカバリモードではないことを必要とします。
-n--dry-runターゲットディレクトリを実際に更新する以外はすべてのことを行います。
-P--progress進行状況のレポートを有効にします。このオプションを有効にすると、データをソースクラスタからコピーする際のおおよその進行状況をレポートします。
--debug主に開発者がpg_rewindをデバッグするのに役立つ冗長なデバッグ出力を印字します。
-V--versionバージョン情報を表示して終了します。
-?--helpヘルプを表示して終了します。
--source-serverオプションを使用する場合、pg_rewindは
libpqで利用できる環境変数を使用します(34.14を参照)。
オンラインのクラスタをソースとして使用して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レコードについて、変更されたデータブロックを記録します。 これにより、ソースクラスタが分岐した以降に、ターゲットクラスタで変更されたすべてのデータブロックのリストが作成されます。
ファイルシステムへの直接アクセス(--source-pgdata)かSQL (--source-server)を使って、変更のあったすべてのブロックを、ソースクラスタからターゲットクラスタにコピーします。
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を適用します。(厳密に言うと、pg_rewindはWALの適用はせず、単にバックアップラベルファイルを作るだけです。 それにより、PostgreSQLが起動する時、チェックポイントより前方のすべてのWALが適用されます)