ポイント・イン・タイム・リカバリ (PITR)

ポイント・イン・タイム・リカバリ (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 データベースのリストア方法について解説します。