ポイント・イン・タイム・リカバリ (PITR)
鈴木 幸市
オンライン・バックアップを利用して、データベースを故障直前の状態まで復旧させる手順を解説します。 オンライン・バックアップとポイント・イン・タイム・リカバリ (アーカイブ・リカバリ) を利用すると、pg_dump でのバックアップとは異なり、バックアップ時点ではなく、アーカイブログが残っている限り最新の状態までリカバリできるのが利点です。
6.3 オンライン・バックアップとアーカイブログを用いたリストア
PostgreSQL 運転中に取得したベースバックアップとアーカイブログを使ってデータベースをリストアすることができます。 アーカイブログもベースバックアップも、PostgreSQL を運転しているサーバとは別な場所に保存できることが重要です。
アーカイブログとベースバックアップを安全な場所 (PostgreSQL を運転しているサーバとは別の場所) に保存しておくことで、サーバやストレージのハードウェアに障害が起こっても、 データベースをリストアすることが可能になります。
具体的な手順を示します。
1) PostgreSQL サーバの強制終了とデータベースクラスタの削除
まず、データベースを強制的に終了させましょう。 kill コマンドを使ってむりやりデータベースを終了させ、データベースクラスタを消してしまいます。
[koichi@willey pgsql]$ ps -ae | grep postgres 18580 pts/6 00:00:00 postgres 18581 ? 00:00:00 postgres 18583 ? 00:00:00 postgres 18584 ? 00:00:00 postgres 18585 ? 00:00:00 postgres 18586 ? 00:00:00 postgres 18587 ? 00:00:00 postgres [koichi@willey pgsql]$ kill -9 18580 18581 18583 18584 18585 18586 18587
次いでデータベースクラスタを消してしまいます。 その前に、アーカイブ前のWALセグメントをバックアップします。 そうしないと、これらのWALにかかれた更新情報はリカバリされなくなります。 実際には、WALを記録するディレクトリは、他のデータベースセグメントとは別な デバイスに配置し、データベースセグメントにはシンボリックリンクを作るようにし、 データベースセグメントの内容が失われてもWALセグメントは失われないようにする のがおすすめです。
では、WALをバックアップします。
[koichi@willey data]$ cd data [koichi@willey data]$ rsync -a pg_xlog/* /tmp/pg_xlog [koichi@willey data]$ cd ..
次いで、擬似的にデータベースセグメントを消去します。
[koichi@willey pgsql]$ pwd /usr/local/pgsql [koichi@willey pgsql]$ ls bin/ data/ include/ lib/ share/ [koichi@willey pgsql]$ rm -rf data [koichi@willey pgsql]$ ls bin/ include/ lib/ share/
これでデータベースはあとかたもありません。これをこれからリストアします。
2) ベースバックアップの展開と recovery.conf の作成
まず、先ほど作ったベースバックアップからデータベースクラスタを展開します。
[koichi@willey /]$ tar xzf ~/pgsqlbackup.tar.gz [koichi@willey /]$ cd $PGDATA/.. [koichi@willey pgsql]$ pwd /usr/local/pgsql [koichi@willey pgsql]$ ls bin/ data/ include/ lib/ share/
次いで、先ほど退避したWALを戻します。
[koichi@willey data]$ cd data [koichi@willey data]$ rsync -a /tmp/pg_xlog/* pg_xlog
この後、PostgreSQL を再起動するのですが、ここでリカバリの指示を行う必要があります。 この指示は recovery.conf ファイルに記述します。 このファイルはpostgresql.conf ファイルと同じ場所に配置します。
リカバリには、6.2で作ったアーカイブログを必要に応じてWALセグメントを配置する ディレクトリにコピーする必要があります。 これを、recovery.conf ファイルの recovery_command エントリに記述します。 次のようになります。
[koichi@willey data]$ cat recovery.conf restore_command = 'cp /var/postgresql/archivedir/%f "%p"'
3) PostgreSQL の起動
この状態で PosgreSQL を起動します。
[koichi@willey data]$ pg_ctl start pg_ctl: another server might be running; trying to start server anyway server starting
エラーメッセージが表示されるのは、PostgreSQL のサーバプロセスを強制的に終了させたからです。 運転ログには、アーカイブログを使ってリストアがなされた旨が出力されています。
[koichi@willey pg_log]$ cat pg_log/postgresql-2009-11-05_222556.log u:, d::2009-11-05 22:25:56 JST: LOG: database system was interrupted; last known up at 2009-11-05 20:22:59 JST u:, d::2009-11-05 22:25:56 JST: LOG: starting archive recovery u:, d::2009-11-05 22:25:56 JST: LOG: restore_command = 'cp /var/postgresql/archivedir/%f "%p"' ...(略) ...
リカバリの指示に使われた recovery.conf ファイルは recovery.done に名前が変わっています。
[koichi@willey data]$ pwd /usr/local/pgsql/data [koichi@willey data]$ ls PG_VERSION pg_hba.conf pg_subtrans/ postgresql.conf.org backup_label.old pg_ident.conf pg_tblspc/ postmaster.opts base/ pg_log/ pg_twophase/ postmaster.pid global/ pg_multixact/ pg_xlog/ recovery.done pg_clog/ pg_stat_tmp/ postgresql.conf [koichi@willey data]$ cat recovery.done restore_command = 'cp /var/postgresql/archivedir/%f "%p"'
次回は任意の時間の状態に PostgreSQL データベースをリストアする方法、及び、複数のバックアップが混在した場合の PostgreSQL データベースのリストア方法について解説します。