ホットバックアップ PITR

PostgreSQL 8 の目玉機能のひとつに、PITR(Point-in time Recovery)がある。

  • システムを停止せずにバックアップを採取できる(ホットバックアップ)
  • (最新でも、過去のある時点でも)好きな時点に戻せる

という特徴がある、バックアップ&レストアの仕組みです。

基本的には、時点のデータベースの内容をコピーしておいて(ベースバックアップ)、それに対してジャーナル(WALファイル)をもとにベースバックアップ採取時点から、復旧させたい時点までの処理を実行するというわかりやすい仕組みです。

今回は、これを試してみることにします。
自己責任でどうぞ。
参考:
PostgreSQL8.1.0文書「オンラインバックアップとPITR」
WEB+DB PRESS vol.37 「PostgreSQLにおけるバックアップ&リカバリ

環境
CentOS 5
PostgreSQL 8.1.9-1.el5(yum

準備

WALファイルを保存するディレクトリをつくる。

[root@lam.local] #mkdir -p /usr/local/pg_backup/xlog_archive
[root@lam.local] #chown -R postgres:postgres /usr/local/pg_backup

pg_xlogディレクトリを外部に移しておく。

[root@lam.local] #mv /var/lib/pgsql/data/pg_xlog /usr/local/pg_backup
[root@lam.local] #ln -s /usr/local/pg_backup/pg_xlog /var/lib/pgsql/data/pg_xlog

WALファイルの保存設定

[root@lam.local] #su postgres

[postgres@lam.local] #cd ~
[postgres@lam.local] #pwd
/var/lib/pgsql
[postgres@lam.local] #ls
backups  data  pgstartup.log

[postgres@lam.local] #vi data/postgresql.conf
archive_command = '/bin/cp %p /usr/local/pg_backup/xlog_archive/%f'

[postgres@lam.local] #exit
[root@lam.local] #service postgresql restart

ベースバックアップの採取

[root@lam.local] #su postgres
[postgres@lam.local] #cd ~
[postgres@lam.local] #psql -c "select pg_start_backup('Label')" test_db

Labelでは、バックアップ操作を識別する時に使用する任意の文字列。
「推奨方法は、格納先のバックアップダンプファイルの完全パスを使用すること」とのことだそう。
データベースはここでは「test_db」としていますが、接続可能なデータベースならなんでもいいそうです。
(どれにしてもデータベースクラスタ全体のバックアップを採取できる)

[postgres@lam.local] #tar cf /usr/local/pg_backup/data.tar data
[postgres@lam.local] #ls /usr/local/pg_backup/data.tar
data.tar

[postgres@lam.local] #psql -c "select pg_stop_backup()" test_db

これで、ベースバックアップ(/usr/local/pg_backup/data.tar)を採取できました。
と、同時に、/usr/local/pg_backup/xlog_archiveにバックアップ履歴ファイルが作成されていると思います。
復旧するときは、このベースバックアップと、WALファイルを用いて行います。

ためしにいろいろ操作

復旧の前に、バックアップ採取時移行の処理として適当にデータベースに操作を加えます。
適当に。(復旧できたことがわかるように、どんなことをしたかは覚えておいてね。)

障害発生!

データベースクラスタが破損した!
ってことにして、データを消しちゃいます。

[root@lam.local] #service postgresql stop
[root@lam.local] #rm -rf /var/lib/pgsql/data

復旧

ベースバックアップを展開。

[postgres@lam.local] #pwd
/var/lib/pgsql
[postgres@lam.local] #tar xvf /usr/local/pg_backup/data.tar

リカバリ設定ファイルを用意。

[postgres@lam.local] #cp /usr/share/pgsql/recovery.conf.sample data/recovery.conf
[postgres@lam.local] #vi data/recovery.conf
restore_command = 'cp /usr/local/pg_backup/xlog_archive/%f %p'

これでサービスを起動させれば、自動的に最新の時点まで戻される。

[root@lam.local] #service postgresql start

最新ではなく、特定の時点の状態に戻したい場合は、recovery.confで、
recovery_target_time = '2004-12-09 22:36:17 JST'
などとしておけばよい。


なお、インデックスを使用する場合は、

[postgres@lam.local] #psql table
table=# REINDEX DATABASE table;

等としてインデックスを再構築しておく。
Ludiaとか。