PostgreSQLは常に、クラスタのデータディレクトリ以下のpg_xlog/ディレクトリ内で先行書き込みログ(WAL)を管理しています。 このログはデータベースのデータファイルに行われた全ての変更を記述します。 このログは主にクラッシュ時の安全性を目的としています。 システムがクラッシュしたとしても、最後のチェックポイント以降に作成されたログ項目を"やり直し"することで、データベースを整合性を維持した状態にリストアすることができます。 しかし、この存在するログファイルを使用して、データベースのバックアップ用の第3の戦略が可能になりました。 ファイルシステムレベルのバックアップとWALファイルのバックアップを組み合わせるという戦略です。 復旧が必要ならば、バックアップをリストアし、その後にバックアップされたWALファイルをやり直すことで、現時点までのバックアップを生成できます。 管理者にとって、この方法はこれまで説明した方法よりかなり複雑になりますが、以下のような大きな利点が複数あります。
開始時点のバックアップは完全な整合状態である必要はありません。 そのバックアップ内の内部的な不整合はログのやり直しによって修正されます (これは、クラッシュからの復旧時に行われることと大きな違いはありません)。 ですので、ファイルシステムのスナップショット機能を必要としません。 単にtarなどのアーカイブツールが必要です。
WALファイルの並びを数に制限なく連ねてやり直せますので、単にWALファイルの保管を続けることで連続したバックアップを達成できます。 これは、完全なバックアップを頻繁に行うことが困難な、大規模なデータベースでは特に有用です。
WAL項目のやり直しを最後まで行わなければならないということはありません。 やり直しを任意の時点までで停止することができ、それにより、その時点までのデータベースの整合性を持ったスナップショットを得ることができます。 このような技術がポイントインタイムリカバリを補助するものであり、元となるベースバックアップの取得時点以降の任意の時点の状態にデータベースをリストアすることが可能になります。
連続的に一連のWALファイルを、同一のベースバックアップをロードしている別のマシンに配送することで、"ウォームスタンバイ"システムを保有することができます。 つまり、任意の時点でその2番目のマシンを、ほぼ現時点のデータベースの複製を持った状態で有効にすることができます。
通常のファイルシステムバックアップ技術の場合と同様、この方法は、一部ではなく、データベースクラスタ全体のリストア処理のみをサポートできます。 また、保管用に大量の格納領域を必要とします。 ベースバックアップは大きくなる場合があり、また、高負荷なシステムでは保管しなければならないWALの流量をメガバイト単位で生成します。 しかし、これは、高信頼性が必要な、多くの状況でむしろ好まれるバックアップ手法です。
継続的アーカイブ(多くのデータベースベンダでオンラインバックアップとも呼ばれます)を使用して復旧を成功させるためには、少なくともバックアップの開始時点まで遡る、連続した一連の保管済みWALファイルが必要です。 ですので、運用するためには、最初のベースバックアップを取得する前にWALファイルを保管する手順を設定し試験しなければなりません。 したがって、まずWALファイルの保管機構について説明します。
理論上、PostgreSQLシステムの稼動により、不定長のWAL記録の並びが生成されます。 システムは物理的にこの並びを、通常1つ16メガバイト(このサイズはPostgreSQLの構築時に変更可能です)の、WALセグメントファイルに分割します。 このセグメントファイルには、概念的なWALの並び内の位置を反映した、数字の名前が付与されます。 WAL保管を行わない場合、システムは通常数個のセグメントファイルを生成し、また、不要となったセグメントファイルの名前をより大きなセグメント番号に変更することでそれを"再回収"します。 直前のチェックポイントより前の内容を持つセグメントファイルは使用されないと仮定され、再回収されます。
WALデータを保管する場合、完成したセグメントファイルのそれぞれの内容を取り出し、再利用のために回収される前にそのデータをどこかに保存することが必要です。 アプリケーションと利用できるハードウェアに依存しますが、数多くのの"データをどこかに保存する"方法があります。 例えば、NFSでマウントした他のマシンのディレクトリにセグメントファイルをコピーすること、あるいは、テープ装置に書き出すこと(元々のファイル名を識別する手段があることを確認してください)、それらを一度にまとめてCDに焼くこと、そのほか全く異なったなんらかの方法などです。 できる限り高い柔軟性をデータベース管理者に提供するために、PostgreSQLは、どのように保管がなされたかについて一切想定しないようになっています。 その代わりにPostgreSQLは、管理者に完全なセグメントファイルをどこか必要な場所にコピーするシェルコマンドを指定させます。 このコマンドは単純なcpでも構いませんし、また、複雑なシェルスクリプトを呼び出しても構いません。 全て管理者に任されています。
使用するシェルコマンドはarchive_command設定パラメータで指定されます。 実際には、postgresql.confファイルで常に設定することになります。 この文字列内では%pは全て保管するファイルのパス名に置換され、%fは全てファイル名部分のみに置換されます。 (パス名は、サーバの作業用ディレクトリ、つまり、クラスタのデータディレクトリから見て相対的なものです。) コマンド内に%文字自体を埋め込む必要があれば%%と記述してください。 最も簡単でよく使用されるコマンドは以下のようなものになります。
archive_command = 'cp -i %p /mnt/server/archivedir/%f </dev/null'
これは、保管可能なWALセグメントを/mnt/server/archivedirディレクトリにコピーします (これは一例です。推奨するものではなく、また、全てのプラットフォームで動作しない可能性があります)。
この保管用コマンドはPostgreSQLサーバを稼動させるユーザと同じ所有権で実行されます。 保管される一連のWALファイルには、実質、データベース内の全てが含まれていますので、保管したデータをのぞき見から確実に保護しなければならないでしょう。 例えば、グループや全員に読み込み権限を付与していないディレクトリにデータを保管してください。
保管用コマンドが成功した場合のみにゼロという終了ステータスを返すことが重要です。 PostgreSQLは、ゼロという結果に基づいて、WALセグメントファイルの保管が成功したことを想定し、そのファイルを削除したり回収するかもしれません。 しかし、非ゼロのステータスは、PostgreSQLに対してファイルが保管されなかったことを通知し、成功するまで周期的に再試行させます。
通常保管用コマンドは既存の保管済みファイルの上書きを行わないように設計されなければなりません。 これは、管理者のミス(例えば2つの異なるサーバの出力を同一の保管用ディレクトリに送信してしまうなど)といった場合から保管状況の整合性を保護するための安全策として重要です。 実際に既存のファイルを上書きしないこと、かつ、その場合に非ゼロのステータスを返すことを確認するために使用する保管用コマンドを試験することを勧めます。 一部のプラットフォームではcp -iがこれを正しく行うこと、他のプラットフォームでは行われないことがわかっています。 選択したコマンドだけではこうした状況を正しく扱えない場合は、保管済みファイルが既存かどうかを検査するコマンドを追加しなければなりません。 例えば、以下のようなコマンドは、ほとんどのUnix系のプラットフォームで正しく動作します。
archive_command = 'test ! -f .../%f && cp %p .../%f'
保管設定を設計する時には、操作者の介入が必要であったり、保管場所の容量不足の理由で保管用コマンドが繰り返し失敗した時にどうなるかを考慮してください。 例えば、オートチェンジャ機能のないテープに書き出している場合に発生する可能性があります。 テープが一杯になった場合、テープを交換するまで保管を行うことができなくなります。 こうした状況を相対的に早く解消できるように、適切に操作者に対しエラーや要求を確実に連絡できるようにしなければなりません。 この状況が解消するまで、WALセグメントファイルはpg_xlog/ディレクトリ内に格納され続けます。
サーバのWALデータの生成に要する平均速度に追いついている限り、保管用コマンドの処理速度は重要ではありません。 保管プロセスが多少遅れたとしても通常の操作は続けられます。 保管処理がかなり遅くれると、災害時に損失するデータの量が増加することになります。 また、これはpg_xlog/ディレクトリ内に多くの保管処理待ちのセグメントファイルが格納され、ディスク容量が不足する状況になる可能性があることを意味します。 保管処理が確実に意図通りに動作しているかを監視することを推奨します。
保管用コマンドを作成する時、保管されるファイル名は64文字長までの、ASCII文字と数字とドットのどんな組合せでも構わないことが前提です。 元の相対パス(%p)を記憶する必要はありませんが、ファイル名(%f)を記憶する必要はあります。
WAL保管によってPostgreSQLデータベースでなされた変更は全てリストアすることができますが、設定ファイルはSQL操作ではなく手作業で変更されますので、設定ファイル(postgresql.conf、pg_hba.conf、およびpg_ident.conf)になされた変更までリストアしないことに注意してください。 通常のファイルシステムバックアップ手続きでバックアップされる場所に設定ファイルを保持する方が良いでしょう。 設定ファイルの設置場所を変更する方法については項17.2を参照してください。
アーカイブコマンドは完全なWALセグメントに対してのみ呼び出されます。 このため、サーバが少ししかWAL流量がない(処理を行わないなぎの期間がある)場合、トランザクションの完了とアーカイブ格納領域への安全な記録との間に長期にわたる遅延があることになります。 古い未アーカイブのデータをどうするかについて制限を付けるために、archive_timeoutを設定して、強制的にサーバを新しいWALセグメントにある程度の間隔で切り替えるようにすることができます。 強制切り替えにより早期に閉ざされたアーカイブ済みファイルは完全に完了したファイルと同じ大きさを持つことに注意してください。 そのため、非常に小さなarchive_timeoutを使用することはお勧めしません。 格納領域を膨張させてしまいます。 通常ならば分単位のarchive_timeout設定が合理的です。
終わったばかりのトランザクションが確実に保管させたい場合、pg_switch_xlog
を使用して手作業でセグメント切り替えを強制することができます。
この他のWAL管理に関連した関数を表9-47に列挙します。
ベースバックアップの作成手順は比較的簡単です。
WAL保管が有効であり、正常に動作することを確認してください。
データベースにスーパーユーザとして接続し、以下のコマンドを発行してください。
SELECT pg_start_backup('label');
ここでlabelは、バックアップ操作を一意に識別するために使用する任意の文字列です
(推奨方法は、格納先のバックアップダンプファイルの完全パスを使用することです)。
pg_start_backup
は、バックアップ情報を持つbackup_labelという名前のバックアップラベルファイルを、クラスタディレクトリ内に作成します。
このコマンドを実行した時にクラスタ内のどのデータベースに接続したのかは注意する必要はありません。 この関数が返す結果は無視できますが、エラーが発生した場合は作業を進める前に対応してください。
tarやcpioなどの使い慣れた任意のファイルシステムバックアップツールを使用して、バックアップを実行してください。 この作業時に、データベースの通常の操作を停止することは不要ですし、望ましい方法でもありません。
再度、スーパーユーザとしてデータベースに接続し、以下のコマンドを発行してください。
SELECT pg_stop_backup();
これはバックアップモードを終了し、次のWALセグメントへの自動切換えを行います。 この切り替えの理由は、バックアップ期間中に書き出された最後のWALファイルがすぐに保管できるよう準備することです。
バックアップ期間中に使用されたWALセグメントファイルが保管されれば、それで終了です。
pg_stop_backup
の結果で識別されるファイルは、バックアップを終了させるために保管しなければならない最後のセグメントです。
すでにarchive_commandを設定していますので、これらのファイルの保管は自動的に発生します。
多くの場合、これはかなり高速に行われますが、バックアップの完了を確認できるように、保管システムを監視し、これが実施されたことを確認することを勧めます。
使用したいと思っているいくつかのバックアップツールは複写している途中でファイルが変更されると警告もしくはエラーを報告するかも知れません。この情況は正常で、稼働しているデータベースのベースバックアップを取っている場合はエラーではありません。ですから、この種の警告と本当のエラーとをどう区別するかの確信が必要です。例えば、rsyncのバージョンによっては"消滅したソースファイル"に対して別の退出コードを返し、そしてこの退出コードをエラーではないと受け付けるするドライバスクリプトを記述することができます。同時にGNU tarのバージョンによっては、tarがそれを複写している途中でファイルが切り捨てられると致命的なエラーと区別をつけられないエラーコードを返します。幸いにも、GNU tar 1.16およびそれ以降のバージョンでは、バックアップ中にファイルが変更されると1で、それ以外のエラーの時は2でプログラムから抜けます。
pg_start_backup
から実際のバックアップの開始時刻までの経過時間やバックアップの終了時刻からpg_stop_backup
までの経過時間は特に気にする必要はありません。
数分の遅れは何も問題ありません。
(しかし、通常full_page_writesを無効にしてサーバを稼動している場合、バックアップモードではfull_page_writesが実質的に強制されていますので、pg_start_backup
からpg_stop_backup
までの間の性能劣化に気が付くでしょう。)
しかし、これらの操作を順番に、重なることなく実施することについて十分に注意する必要があります。
さもないと、バックアップを台無しにしてしまいます。
バックアップダンプに、データベースクラスタディレクトリ(例えば/usr/local/pgsql/data)以下にある全てのファイルが含まれていることを確認してください。 このディレクトリ以下に存在しないテーブル空間を使用している場合、注意して、同様にそれらを含めてください (そして、バックアップダンプがリンクとしてシンボリックリンクを保存していることを確認してください。 さもないとリストアはテーブル空間を台なしにしてしまいます)。
しかし、クラスタディレクトリのpg_xlog/サブディレクトリにあるファイルをバックアップダンプから省くことができます。 これは多少面倒ですが、リストア処理中の失敗の危険性を低減できますので、行う価値があります。 pg_xlog/がクラスタディレクトリ外のどこかを指し示すシンボリックリンクの場合は調整が簡単です。 これは性能上の理由でよく使用される設定です。
このバックアップを使用したいと思ったら、バックアップの実行期間とそれ以降に生成された全てのWALセグメントファイルをまず取っておかなければなりません。
これを手伝うために、pg_stop_backup
関数はバックアップ履歴ファイルを生成し、WAL保管領域に保存します。
このファイルの名前は、バックアップを使用可能にするために保管しなければならない最初のWALセグメントファイルにちなんで付けられます。
例えば、最初のWALファイルが0000000100001234000055CDの場合、バックアップ履歴ファイルは0000000100001234000055CD.007C9330.backupといった名前になります。
(このファイル名の2番目の番号はWALファイル内の正確な位置を示し、これは通常無視できます。)
バックアップの期間(バックアップ履歴ファイルで指定されたように)に使用された、ファイルシステムバックアップとWALセグメントファイルを安全に保管した後、数値的に小さい名前を持つWALセグメントは、ファイルシステムバックアップの回復にもう必要がないので、削除できます。
とは言っても、データが回復できることを完全に保証するため、いくつかのバックアップセットの保存を検討すべきでしょう。
バックアップ履歴ファイルは小さなテキストファイルです。それにはpg_start_backup
に与えたラベル文字列と、バックアップ開始と終了の時刻とWALセグメントが入っています。関連付けられたダンプファイルが何処に保管されたかを特定するためラベルを使用するとすれば、どのダンプファイルをリストアするかを行うには保管された履歴ファイルからで充分です。
最後のベースバックアップまで遡ることができる全ての保管済みWALファイルを保持する必要がありますので、ベースバックアップの実行間隔は通常、保管済みWALファイルを格納する領域をどれだけ拡張したいかによって決定されます。 また、復旧処理に費すことができる時間がどの位許されるかについても考慮しなければなりません。 復旧が必要になった時に、システムはこれらのセグメントを全てやり直しする必要がありますが、最後のベースバックアップからの経過時間が長ければその分やり直しに時間がかかります。
また、pg_start_backup
関数がデータベースクラスタディレクトリ内にbackup_labelという名前のファイルを作成することに注意してください。
これは、その後、pg_stop_backup
によって削除されます。
当然ながら、このファイルはバックアップダンプファイルの一部として保管されます。
バックアップラベルファイルには、pg_start_backup
に付与したラベル文字列とpg_start_backup
が実行された時刻、最初のWALファイルの名前が含まれます。
したがって、当惑した時にバックアップダンプファイルの中身を検索し、そのダンプファイルがどのバックアップセッションに由来したものかを確認することができます。
サーバが停止している時にバックアップダンプを作成することも可能です。
この場合、わかりきったことですが、pg_start_backup
やpg_stop_backup
を使用することができません。
そのため、どのバックアップダンプが、どのWALファイルと関連し、どこまで戻せばよいかを独自の方法で残さなければなりません。
通常は、上述の継続的アーカイブ手順に従う方をお勧めします。
さて、最悪の事態が発生し、バックアップから復旧する必要が出てきたものとします。 以下にその手順を説明します。
もし稼動しているのであればサーバを停止してください。
もし容量があるのであれば、後で必要になる場合に備えてクラスタデータディレクトリ全体とテーブル空間を全て一時的な場所にコピーしてください。 この予防措置は、既存のデータベースを2つ分保持できるだけの空き領域を必要とします。 十分な領域がない場合でも、少なくともクラスタデータディレクトリ以下のpg_xlogディレクトリの内容だけはコピーしなければなりません。 ここには、システムが停止する前に保管されなかったログファイルが含まれているからです。
クラスタデータディレクトリ以下、および、使用中のテーブル空間の最上位ディレクトリ以下にある既存の全てのファイルとサブディレクトリを削除してください。
バックアップダンプからデータベースファイルをリストアしてください。 ファイルが正しい所有権(rootではなくデータベースシステムユーザです!)でリストアされていることを確認してください。 テーブル空間を使用している場合は、pg_tblspc/内のシンボリックリンクが正しくリストアされていることを検証する必要があります。
pg_xlog/内にあるファイルを全て削除してください。 これらはバックアップダンプから生成されたものであり、おそらく現在のものより古く使用できないものです。 pg_xlog/をまったく保管していなければ、再作成してください。 また、同様にpg_xlog/archive_status/というサブディレクトリも確実に作成してください。
手順2で退避させた未保管のWALセグメントファイルがあるのであれば、pg_xlog/にコピーしてください (問題が発生し、初めからやり直さなければならない場合に未変更のファイルが残るように、移動させるのではなくコピーすることが最善です)。
復旧コマンドファイルrecovery.conf(Recovery Settingsを参照)をクラスタデータディレクトリに作成してください。 また、一時的にpg_hba.confを編集し、復旧完了を確認できるまで一般ユーザが接続できないようにする必要があるかもしれません。
サーバを起動してください。 サーバは復旧モードに入り、必要な保管済みWALファイル群の読み込みを行います。 外部的なエラーにより復旧が中断したら、サーバを単に再起動させて、復旧処理を継続してください。 復旧処理が完了したら、(偶然にクラッシュしてしまったとしても再度復旧モードに入らないように)postmasterはrecovery.confの名前をrecovery.doneに変更します。 その後通常のデータベース操作を開始します。
データベースの内容を検査し、希望する時点まで復旧できていることを確認してください。 復旧できなかった場合は手順1に戻ってください。 全て問題なければ、ユーザが使用できるようにpg_hba.confを正常状態に戻してください。
ここで重要となるのは、復旧コマンドファイルを設定することです。 このファイルで、どのように復旧させたいのかやどこまで復旧させたいかを記述します。 recovery.conf.sample(通常はインストレーションのshare/ディレクトリに格納されています)を手本として使用することができます。 recovery.confで絶対に指定しなければならないことは、保管済みWALファイルセグメントからどのように戻すかをPostgreSQLに通知するrestore_commandです。 archive_command同様、これはシェルコマンド文字列です。 ここには、対象のログファイルの名前で置換される%fやログファイルのコピー先を示すパスで置換される%pを含めることができます。 (パス名はサーバの作業用ディレクトリ、つまり、クラスタのデータディレクトリ)から見た相対パスです。) コマンド内に%文字自体を埋め込む必要があれば%%と記載してください。 最も簡単でよく使われるコマンドは以下のようなものです。
restore_command = 'cp /mnt/server/archivedir/%f %p'
これは事前に保管されたWALセグメントを/mnt/server/archivedirディレクトリからコピーします。 当然ながら、もっと複雑なもの使用することができます。 例えば、操作者に適切なテープをマウントさせることを要求するようなシェルスクリプトでさえ可能です。
このコマンドが失敗した時に非ゼロの終了ステータスを返すことが重要です。 このコマンドは、保管場所に存在しないログファイルを問い合わせるかもしれませんが、その場合でも非ゼロを返さなければなりません。 これはエラー状態ではありません。 また、%pのファイル名部分は%fと異なることに注意してください。 ですので、これらが相互に置き換え可能であるとは考えないでください。
保管場所で見つけられなかったWALセグメントはpg_xlog/から検索されます。 これにより、最近の未保管のセグメントを使用することができます。 しかし、保管場所から利用できるセグメントはpg_xlog/内のファイルよりも優先的に使用されます。 システムは保管済みファイルから取り出す時に既存のpg_xlog/の内容を上書きしません。
通常は利用可能な全てのWALセグメントを使用して復旧処理が行われます。 これは、データベースを現時点まで(利用可能なWALセグメントで得られる限り現在に近い時点まで)リストアします。 しかし、少し過去の時点まで(例えば経験不足のデータベース管理者が主トランザクションテーブルを削除してしまう直前まで)復旧させたい場合、単にrecovery.conf内で要求する停止時点を指定してください。 停止時点は、"recovery target"として既知の停止時点で指定することも、日付と時刻で指定することも、完了した特定のトランザクションIDで指定することもできます。 本ドキュメントの執筆時点では使用するトランザクションIDの識別を補助するツールがありませんので、ほとんどの場合は日付と時刻による指定のみを使用することになるでしょう。
注意: 停止時点はバックアップの終了時刻(つまり、
pg_stop_backup
の時刻)よりも後の時点を指定しなければなりません。 あるベースバックアップを使用してそのバックアップを行っている最中の時点まで復旧させることはできません (こうした時点まで復旧させるには、その前のベースバックアップまで戻って、そこからロールフォワードしてください)。
復旧時にWALデータの破損がわかると、その時点までの復旧を行いますが、サーバを起動させません。 こうした場合、"復旧対象"に破損時点より前の時点を指定することで、復旧処理が正常に完了できるよう、復旧プロセスを初めからやり直すことができます。 システムクラッシュなど外的理由により復旧処理が失敗した場合やWALアーカイブがアクセスできなくなった場合、復旧処理を単に再起動させることができます。 この場合は失敗した時点とほぼ同じところから再開します。 復旧処理の再起動は、次のような通常操作時のチェックポイント処理とほぼ同様に動作します。 サーバは定期的にすべての状態をディスクに強制し、再度スキャンする必要がない処理済みのWALデータを示すpg_controlファイルを更新します。
以下の設定は、recovery.confでのみ設定可能であり、リカバリ期間にのみ適用されます。 これは、その後に行う実行するリカバリごとに再設定しなければなりません。 リカバリが始まった後に変更することはできません。
WALファイル群の保管済みセグメントを取り出すために実行するシェルコマンドです。 このパラメータは必須です。 文字列中の%fは全て保管場所から取り出すファイル名で置き換えられ、%pは全てサーバ上のコピー先のパス名で置き換えられます。 (パス名はサーバの作業用ディレクトリ、つまり、クラスタのデータディレクトリ)から見た相対パスです。) コマンド中に%文字そのものを埋め込むには%%と記述してください。
このコマンドで重要な点は、成功した場合にのみ0終了ステータスを返すことです。 このコマンドは保管場所に存在しないファイル名を問い合わせることがあります。 問い合わせがある場合は非ゼロを返さなければなりません。 以下に例を示します。
restore_command = 'cp /mnt/server/archivedir/%f "%p"' restore_command = 'copy /mnt/server/archivedir/%f "%p"' # Windows
このパラメータはリカバリ処理をどこまで行うかを示す時刻を指定します。 多くても1つのrecovery_target_timeとrecovery_target_xidを指定することができます。 デフォルトでは、WALログの終わりまでリカバリします。 また、正確な停止時点はrecovery_target_inclusiveによって変わります。
このパラメータはリカバリ処理をどこまで進めるかを示すトランザクションIDを指定します。 トランザクションIDはトランザクションの開始時に順番に割り当てられますが、トランザクションの終了はこの順序通りではないということに注意してください。 リカバリされるトランザクションは、指定したIDより前にコミットされたトランザクションです(オプションで指定したIDを含めることもできます)。 多くても1つのrecovery_target_xidとrecovery_target_timeを指定することができます。 デフォルトでは、WALログの終わりまでリカバリします。 また、正確な停止時点はrecovery_target_inclusiveによって変わります。
指定したリカバリ対象の直後で停止する(true)か、リカバリ対象の直前で停止する(false)かを指定します。 そのリカバリで指定されたrecovery_target_timeにもrecovery_target_xidにも適用されます。 これは、対象コミット時刻やIDに正確に一致したトランザクションをそのリカバリに含めるかどうかを示します。 デフォルトはtrueです。
どの時系列でリカバリを行うかを指定します。 デフォルトはベースバックアップを取得した時点と同じ時系列に従ってリカバリが行われます。 このパラメータは、ポイントインタイムリカバリの後に達した状態に戻さなければならないような複雑な再リカバリ時にのみ設定する必要があります。 詳細は項23.3.4を参照してください。
過去のある時点までデータベースを復旧できる機能は、SFのタイムトラベルやパラレルユニバース(ブラックホールの先の対の宇宙)に類似した、多少の複雑性があります。 例えば、データベースの元の履歴で、火曜日の夕方5:15PMに重要なテーブルを削除したとします。 慌てずに、バックアップを取り出して、火曜日の夕方5:14PMの時点にリストアし、データベースを起動させます。 データベース世界のこの履歴では、そのテーブルを削除していません。 しかし、後になって、結局これは大した問題ではなかったことがわかったと仮定すると、元の履歴におけるもう少し後まで戻したいと考えました。 データベースは既に起動していますので、一連のWALセグメントファイルの一部は上書きされているかもしれません。 この場合、元に戻したい時点よりも未来の時点まで進んでしまっていますので、戻すことはできません。 ですので、本当ならば、ポイントインタイムで復旧させた後に生成された一連のWAL記録と元のデータベースの履歴において生成されたWAL記録とを区別する必要があります。
こうした問題を扱うためにPostgreSQLには時系列という概念があります。 アーカイブ復旧処理が完了した時はいつでも、一連のWAL記録を特定する新規時系列が復旧後に生成されます。 時系列ID番号はWALセグメントファイル名の一部です。 ですので、新しい時系列はこれまでの時系列で生成されたWALデータを上書きしません。 実際、多くの異なる時系列を保管することができます。 不要な機能と考えるかもしれませんが、命綱になることがしばしばあります。 どの時点まで復旧すればよいか確実でないといった状況を考えてみてください。 その時は、過去の履歴からの分岐点として最善の時点を見つけるために、試行錯誤して何度もポイントインタイムの復旧を行う必要があるでしょう。 時系列がないと、この手続きはすぐに管理不能な混乱を招いてしまいます。 時系列を使用して、後で中断した時系列分岐における状態を含む、過去の任意の状態に復旧させることができます。
新しい時系列が生成される度に、PostgreSQLは、どの時系列がいつどこから分岐したかを示す"時系列履歴"ファイルを作成します。 この履歴ファイルは、複数の時系列を含む保管場所から復旧する時にシステムが正しいWALセグメントファイルを選択できるようにするために必要です。 したがって、履歴ファイルは、WALセグメントファイル同様にWAL保管領域に保管されます。 履歴ファイルは(巨大になるセグメントファイルとは異なり)単なる小さなテキストファイルですので、安価かつ適切に無期限で保管できます。 必要ならば、履歴ファイルにコメントを追加し、この特定の時系列がどのように、なぜ生成されたかについて独自の注釈を付与することができます。 特にこうしたコメントは、実験の結果いくつもの時系列へのチケットがある場合に有用です。
復旧処理のデフォルトは、ベースバックアップが取得された時点の時系列と同一の時系列に沿った復旧です。 別の子時系列に沿って復旧させたい(つまり、復旧試行以降に生成されたある状態に戻りたい)場合はrecovery.confで対象の時系列IDを指定しなければなりません。 ベースバックアップより前に分岐した時系列に沿って復旧することはできません。
本ドキュメント作成時点では、継続的アーカイブ技術にいくつかの制限があります。 将来のリリースでは修正されるはずです。
ハッシュインデックスに対する操作は現在WALログに残りません。したがって、再生してもこれらのインデックスは更新されません。 推奨する回避策は、復旧処理が終わった後に手作業でそうしたインデックスそれぞれに対してREINDEXを行うことです。
もしもベースバックアップが行われている時、CREATE DATABASEコマンドが実行され、ベースバックアップが処理を実行している期間にCREATE DATABASEがコピーしているtemplateデータベースが変更されると、復旧処理はこれらの変更を作成されたデータベースにも同時に伝播させることは確実です。 もちろん、これは望まれる事ではありません。 この危険を回避するには、ベースバックアップ期間中にはすべてのtemplateデータベースを変更しないことが一番です。
CREATE TABLESPACEコマンドはリテラルの絶対パス付でWALにログが記録され、したがって、同じ絶対パスでのテーブル空間作成の時に再生されます。 これは、もしログが異なったマシン上で再生される場合には好ましくありません。 ログ再生がたとえ同一のマシンであっても、新規のデータディレクトリであれば危険です。 なぜなら、再生は元のテーブル空間の内容を上書きし続けるからです。 この種の潜在的な振舞いを防ぐためには、テーブル空間を作成もしくは削除後に新規ベースバックアップを行うのが最良の手段です。
また、デフォルトのWALフォーマットは数多くのディスクページのスナップショットを含んでいるため、かなりかさばるものになってしまっていることに触れておくべきでしょう。 これらのページスナップショットは、クラッシュから回復のために設計されています。 それというのも、回復処理の際には不完全に書き込まれているディスクページを修復しなければならないことがあるからです。 システムのハードウェアやソフトウェアによっては、不完全なディスクページの書き込みが起きてしまう危険性は無視してもよい程微小です。 この場合full_page_writesパラメータを設定してページスナップショットを無効にすることで、アーカイブされたログの総容量を大幅に縮小できます (実際に設定を行う前に、第27章の注意事項と警告を読んでください)。 ページスナップショットを無効にしても PITR処理の際にログが使用できなくなることはありません。 将来の課題は、full_page_writesがたとえオンになっている場合であっても不要なページを取り除き、保管済みWALデータの圧縮を行うことでしょう。 差し当たり管理者は、可能な限りチェックポイント間隔パラメータを大きくすることによって、WALに含まれるページスナップショットの数を削減することができます。