PREPARATION
受験対策

OSS-DB入門

第8回 バックアップ・リストア

これまでの回では、主にデータベースの構築について学んできました。今回は、構築したデータベースのバックアップとリストアを行なってみましょう。
ハードウェアの障害やソフトウェアの不具合、操作ミスによる誤った更新や削除といったトラブルに備えて、また、別の環境への移行といったときに、バックアップを取得し、更に、その復元を行うことが必要となります。
データベースを安全に運用するために重要となるバックアップ・リストアについて学んでいきましょう。

バックアップ・リストアにはいくつかの方法があります。

1.ディレクトリ全体のコピーとリストア

物理ファイルをまるごとバックアップするという最もシンプルな方法です。
データベースクラスタが格納されているディレクトリ全体を、rsyncやtarコマンドなどを用いてバックアップとして取得し、リストア先のディレクトリに配置します。
この操作を行う際には、PostgreSQLサーバーを停止しておきます。

2.pg_dump, pg_dumpall, pg_restoreコマンド

PostgreSQLサーバーが動いている状態で行います。
コマンドラインでpg_dumpを実行することによりデータベースのバックアップを取得することができます。
これまでの回で作成したossdbというデータベースのバックアップを取得してみましょう。

$ pg_dump ossdb > ossdb.dump

デフォルトでは標準出力に出力されるため、上記ではossdb.dumpというファイルに出力しています。

pg_dumpの基本的な書式は次の通りです。

pg_dump [接続オプション] [-Fp|-Fc|-Fd|-Ft] [-f ファイル名] [データベース名]

  -Fp…平文(Plain)で出力する。-Fを省力した場合のデフォルト。
  -Fc…カスタム形式で出力する。
  -Fd…ディレクトリ形式で出力する。
  -Ft…tar形式で出力する。
  -f  …出力先に指定するファイル名。省略した場合は標準出力となる。

指定できるオプションは他にもあり、一部のテーブルやDBのスキーマ、データ内容だけを取得するといったことも可能です。

また、すべてのデータベースをバックアップする場合はpg_dumpallコマンドを使用します。

$ pg_dumpall -f db.sql

pg_dumpallの基本的な書式は次の通りです。

pg_dumpall [接続オプション] [-f ファイル名]

pg_dump, pg_dumpallで指定できるオプションは以下のリファレンスマニュアルを参照して下さい。
http://www.postgresql.jp/document/9.1/html/app-pgdump.html
http://www.postgresql.jp/document/9.1/html/app-pg-dumpall.html

先ほど出力したossdb.dumpはテキストファイルです。ファイルの中身を見てみると、SQL文が羅列されていることが確認できます。

このSQLは通常のSQLと同じですので、psqlコマンドで読み込むことができます。
ロード先のデータベースossdb2を新規で作成し、そこへバックアップファイルを読み込むことにしましょう。

$ createdb ossdb2
$ psql -f ossdb.dump ossdb2

カスタム形式やtar形式のように、平文以外の形式でバックアップした場合は、pg_restoreコマンドを使ってリストアします。
ossdb.dumpというファイルにカスタム形式もしくはtar形式でバックアップし、データベースossdb3にリストアしてみましょう。

$ createdb ossdb3
$ pg_dump -Fc -f ossdb.dump ossdb
$ pg_restore -d ossdb3 ossdb.dump

pg_restoreの基本的な書式は次の通りです。

pg_restore [接続オプション] [-d データベース名] [ファイル名]

pg_restoreで指定できるその他のオプションは以下のリファレンスマニュアルを参照して下さい。
http://www.postgresql.jp/document/9.1/html/app-pgrestore.html

pg_dump, pg_dumpall, pg_restoreを用いたバックアップ・リストアは、異なるOSや他のDBMSへの移行、メジャーバージョン間で移行の際に使用します。

3.PITR

PITR(Point In Time Recovery) とは、ベースとなるデータベース全体のバックアップと、PostgreSQLの稼働中に発生した差分のアーカイブログを組み合わせて、直近の状態までデータベースをリカバリする仕組みです。

まずは、バックアップの設定を行います。
posgresql.confを編集します。
「WRITE AHEAD LOG」と書かれているあたりを見て下さい。

編集する箇所を赤線で示しています。
これらをそれぞれ以下のように設定してみましょう。

wal_level = archive
archive_mode = on
archive_command = 'cp "%p" /var/log/postgresql/arch/"%f"'

Write Ahead Log = WALとは、コミットされたトランザクションを反映する前に、いったんすべて書き出しておくためのファイルであり、先行書き込みログと言われます。
WALには、データベース更新情報がどんどん蓄積されていくので、古いファイルをアーカイブするようにします。
WALファイルは、$PGDATA(データベースクラスタが存在するディレクトリであり、PG_VERSIONといった制御ファイルが格納されています)のpg_xlogというディレクトリに格納されますが、これをコピーして安全に保管しておきます。上記例では、/var/log/postgresql/arch/(予め作成しておき、postgresユーザーが書き込みできるようにパーミッションを設定しておいてください)にWALアーカイブを保存しています。可能ならば、データベースが存在する場所と物理的に異なるディスクに保存するのがよいでしょう。

postgresql.confの編集内容を反映するために、PostgreSQLサーバーを再起動しましょう。

WALの設定に関する詳細は以下のリファレンスマニュアルを参照してください。
http://www.postgresql.jp/document/9.1/html/runtime-config-wal.html

次に、データベース全体のバックアップ(これをベースバックアップと言います)を取得します。

PostgreSQLサーバーに接続して、pg_start_backup()によりバックアップ開始を宣言します。
SELECT pg_start_backup('201301')

PostgreSQLでのスーパーユーザーで実行することに注意してください。
pg_start_backupに与える引数は、バックアップにつけるラベルであり任意の文字列を指定します。

データベースクラスタのバックアップを取得します。(OSのスーパーユーザーで行います)
$ su root
# cd /var/lib/postgresql/9.1
# tar zcvf backup2012301.tar.gz main

pg_stop_backup()を実行して、バックアップ終了を宣言します。
SELECT pg_stop_backup();

これでバックアップが取得出来ました。PITRによるリカバリの準備が整ったことになります。

※PostgreSQL9.1では、pg_basebackupというコマンドラインツールを用いてベースバックを行うこともできます。

それでは、リカバリをしてみましょう。

まずは、ベースバックアップを行います。
PostgreSQLサーバーを停止して、データベースクラスタを退避し、さきほど取得したバックアップから復元します。
$ su root
# cd /var/lib/postgresql/9.1
# mv main main_org
# tar zxvf backup201301.tar.gz

古いWALアーカイブを削除し、最新のWALアーカイブをコピーします。
# cd main
# rm -rf pg_xlog
# cp -rp /var/log/postgresql/arch pg_xlog

リカバリ設定を行うため、設定ファイルrecovery.confを作成します。
サンプルが用意されていますので、これをコピーして使うことにしましょう。

# cp /usr/share/postgresql/9.1/recovery.conf.sample recovery.conf

recovery.confを編集します。
recovery.conf 中の"restore_command"にWALアーカイブをコピーするコマンドを設定します。

restore_command = 'cp /var/log/postgresql/arch/%f %p '

PostgreSQLサーバーを起動しましょう。
リカバリが終わると、recovery.confはrecovery.doneとリネームされます。

※/var/log/postgresql/arch/ にはアーカイブ済みのWALが保存され、未アーカイブのWAL(これをオンラインWALと言います)はpg_xlogに残っています。PITRは、厳密には、ベースバックアップ+WALアーカイブ+オンラインWALで最新状態に復元しますが、上記の方法はオンラインWALを用いていない不完全リカバリと呼ばれます。

リカバリ設定ファイルについての詳細はオンラインマニュアルを参照してください。
http://www.postgresql.jp/document/9.1/html/recovery-config.html

PITRによるバックアップ・リストアは、バックアップ時点ではなく、アーカイブログが残っている限り最新の状態までリカバリできるのが特長です。

最後に

バックアップ・リストアは、データベースを運用する上で非常に重要です。大切なデータが失われないように、そして、万が一の際に復旧ができるようにしておくことが、堅牢なデータベースシステムを構築するために必要となりますので、しっかり学んでおきたいところです。
pg_dumpのようなコマンドで簡単に行う方法はよいとして、PITRによる方法は難しいと感じる方も多いのではないでしょうか。まずはコマンドによる方法をしっかりと身につけておきましょう。
PITRについては、管理ツールとしてpg_rmanというものがあり、運用を簡単に行うことができます。
http://code.google.com/p/pg-rman/

障害対策として、レプリケーションによる冗長化も非常に有効です。PostgreSQLでは、ストリーミングレプリケーションがバージョン9.0より標準実装され、特に、9.1では同期レプリケーションをサポートするようになりました。(それ以前のバージョンでもオプションツールを用いてレプリケーションを行うことができます)

今回の内容については、PostgreSQL日本語ドキュメントも是非ご参照ください。

第24章 バックアップとリストア
http://www.postgresql.jp/document/9.1/html/backup.html

 

執筆:
村上 恵氏(OSS-DB Silver認定者)株式会社オークニーにて、PostGISを含むFOSS4G(Free Open Source Software for Geospatial)ソフトウェアを軸としたアプリケーションやサービスの開発に従事。

アドバイザー:
森 亮 氏 株式会社オークニー代表取締役
2002年にオークニーを設立し、代表取締役に就任。マッピング・ GIS・LBS・ITS関連プロジェクトのビジネスコンサルティングを経て、現在は会社経営の傍ら、『入門Webマッピング』(Tyler Mitchell原著;オライリー・ジャパン発行)の翻訳、Open Source Geospatial財団日本支部の代表者を務めるなど、FOSS4G(オープンソース地理空間ソフトウェア)の普及活動に取り組んでいる。

監修:
松田 神一

LPI-Japan
Platinum Sponsors

関連資格