現在位置: ホーム / OSSブログ / PostgreSQLのバックアップとリストア

PostgreSQLのバックアップとリストア

データベースにとってバックアップは最後の命綱です。バックアップとリストアを完全に理解することは安全なデータベース運用には欠かせません。今回は PostgreSQL9.3 を用いて、バックアップとリストアの全機能を簡単に紹介します。

■ データベースのバックアップとリストア

PostgreSQL では以下の方法が利用できます。

  • ファイルのバックアップ (ただし、オフラインバックアップのみ)
  • ファイルシステムのスナップショット (オンラインバックアップ可能)
  • pg_dump / pg_dumpall コマンドによるバックアップ (オンラインバックアップ可能)
  • アーカイブログによるバックアップ (非同期にバックアップ & 任意時点へのリカバリ可能)

レプリケーションもバックアップの一種と考えることも可能です。しかし、レプリケーションの場合

  • 操作ミス、攻撃などによるデータ破壊が発生した場合に対応できない

という欠点があります。ディスクのミラーリングなどの冗長性確保をデータのバックアップととらえないことと同様に、ここではレプリケーションはバックアップには入れないことにします。ここでは説明しませんが、レプリケーションを行いながらアーカイブログを利用したバックアップを行うことも簡単です。

■ バックアップの種類と特徴

PostgreSQL データベースをバックアップに利用できる方法を順番に紹介します。

■■ファイルのバックアップ

♦ 利点

  • バックアップ / リストアが高速

♦ 欠点

  • オンラインでのバックアップ / リストアができない
  • 一部のテーブル / データベースのバックアップ / リストアができない
  • 同じバージョンの PostgreSQL でなければならない

initdb コマンドで指定する PostgreSQL のデータクラスタのディレクトリを丸ごとバックアップする方法です。この方法はファイルをバックアップするので高速です。リストアもファイルのリストアなので高速です。データベースは停止していなければなりません。ファイルバックアップを PostgreSQL 動作中に行うとデータベースにファイルに不整合が発生し、リストアしても使えないデータを取得することになります。

コマンド例

tar -jcvf backup.tar.bz2 /usr/local/pgsql/data 

■■ファイルシステムのスナップショット

♦ 利点

  • バックアップ / リストアが高速
  • バックアップはオンラインで可能(スナップショット取得開始時点での整合性を維持できる場合)

♦ 欠点

  • オンラインでのリストアができない
  • 一部のテーブル / データベースのバックアップ/リストアができない
  • OS のファイルシステムに依存する (いつでも使えない)
  • リストアする場合にデータベースが強制終了した後の状態になる (エラーが発生するだけで、実際に問題となることはない)
  • 同じバージョンの PostgreSQL でなければならない

ファイルシステムがスナップショットの取得時に整合性を保てる場合、スナップショットをバックアップに利用できます。Btrfs、XFS などのファイルシステムは整合性を保ったスナップショットの取得が可能です。スナップショットはファイルのバックアップ / リストアよりさらに高速です。

コマンド例 (Btrfs)

btrfs subvolume snapshot /usr/local/pgsql/data /usr/local/pgsql/data/snapshot1 

■■pg_dump/pg_dumpallコマンド

♦ 利点

  • オンラインでのバックアップ / リストアが可能
  • テーブル / データベース単位でのバックアップ / リストアが可能
  • リモートホストのバックアップ / リストアが可能
  • PostgreSQL バージョンアップ時のバックアップ / リストアとして利用可能

♦ 欠点

  • バックアップ / リストアが低速

PostgreSQL の pg_dump コマンドを利用するとオンラインでのバックアップ / リストア、テーブル、データベース毎のバックアップ / リストアが可能になります。データベース全体でなく、一部をバックアップ / リストアできることが利点です。データベースによってはオンラインバックアップで整合性のあるバックアップを取得できなかったり、ロックが発生する物もあります。PostgreSQL の場合、ロック無しに整合性のあるバックアップを取得できます。

PostgreSQL のバージョンアップ (例えば、9.3 から 9.4 へのバージョンアップ) にはデータのバックアップ / リストアを行うか、pg_upgrade コマンドによるデータベースファイルのアップグレードが必要です。ファイル / スナップショットによるバックアップはバージョンアップの為のバックアップ & リストアには利用できません。pg_dumpall とリストア、または pg_upgrade によるアップグレードが必要です。

コマンド例

# バックアップ pg_dump -p 5433 -h 10.10.10.10 dbname > backup_file # リストア psql -p 5433 -h 10.10.10.10 dbname < backup_file  

■■アーカイブログによるバックアップ

♦ 利点

  • オンラインでバックアップ / リストアが可能
  • バックアップが高速
  • 常に新しい差分バックアップが取得可能
  • 任意時点へのリカバリ (PITR) が可能

♦ 欠点

  • バックアップ / リストアの為のセットアップが必要
  • ベースバックアップの取得が必要
  • リストアが低速 (特にベースバックアップが古い場合)
  • バックアップデータが大きくなる
  • 同じバージョンの PostgreSQL でなければならない

アーカイブログによるバックアップが最も手順が複雑ですが、常に差分バックアップが取得可能であること、任意時点へのリカバリ (PITR - Point In Time Recovery) が可能であることは大きなメリットです。アーカイブログは普通のファイルなので、NFS などを利用してリモートのシステムに保存することも可能です。リモートの PostgreSQL をコールドスタンバイとした冗長構成を取ることも可能です。

■ アーカイブログによるバックアップの仕組み

PostgreSQL はデータベースのデータファイルに直接データを書き込みません。WAL (Write Ahead Log) と呼ばれるバイナリのトランザクションログにデータ操作を記録します。その後、実際のデータファイルに更新を反映していきます。WAL により、電源断などの障害が発生した場合のリカバリと、ディスクヘッドの動きを最小限にしてデータベースの動作を高速化しています。

つまり、アーカイブログにはデータベースへの操作が順番に全て記録されています。元となるデータベースのバックアップ (ベースバックアップ) とその後のアーカイブログがあれば、直近の状態にまでリストアできます。リストアする時にはアーカイブログを利用しデータベース操作を 「再生」 するので、通常のリストアより時間がかかります。 (例 : 同じレコードを何度も更新している場合、全ての更新が 「再生」 される) つまり、障害時のダウンタイムを少くするには、頻繁にベースバックアップを取得しなければなりません。

■■ ベースバックアップの取得

ベースバックアップの取得にはオフラインで取得する方法(データファイルを利用する方法)とオンラインで取得する方法(専用コマンドを利用する方法)の 2 種類があります。オンラインで利用できる pg_basebackup コマンドが最も簡単にベースバックアップを取得できます。通常は pg_basebackup コマンドを利用すると良いでしょう。

pg_basebackup の利用例

# ローカルデータベースの tar.bz2 形式のベースバックアップを取得 pg_basebackup -D - -Ft | bzip2 > backup.tar.bz2 # リモートホスト(remote)のデータベースクラスタをローカルに作成 pg_basebackup -h remote -D /usr/local/pgsql/data 

pg_basebackup コマンドはレプリケーションアクセスが必要です。pg_hba.conf で pg_basebackup コマンドを実行するユーザーに replication の許可をします。

pg_hba.conf の例

# Allow replication connections from localhost, by a user with the # replication privilege. local replication username trust host replication username 127.0.0.1/32 trust host replication username ::1/128 trust 

postgresql.conf の max_wal_sender 設定のデフォルトは 0 です。最低でも 1 以上でないと pg_basebackup コマンドは実行できないので修正します。

postgresql.conf の例

max_wal_sender = 1 

■■ WALアーカイブの有効化

デフォルトの場合、アーカイブログは 16MB 毎に作成され pg_xlog ディレクトリに保存されます。必要がなくなったアーカイブログは自動的に削除されます。アーカイブログによるバックアップを行う場合、アーカイブログファイルを消す前に他の場所にコピーします。これは postgresql.conf にアーカイブログに必要な設定を行い、ファイルをコピーするコマンドを書きます。

♦ WALアーカイブの有効化の手順

  1. wal_level 設定を archive (または hot_standby) に設定する
  2. archive_mode 設定を on に設定する
  3. archive_command 設定にコピーコマンドを設定する

archive_command の設定例

archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' # Unix archive_command = 'copy "%p" "C:¥¥server¥¥archivedir¥¥%f"' # Windows 

これでアーカイブログが保存できます。

■■ アーカイブログを利用したリカバリ

♦ ここでは同じサーバーにリカバリする手順を紹介します。

  1. サーバーを停止する。
  2. 少なくともデータクラスタ内の pg_xlog ディレクトリをコピーする。(可能であればデータクラスタのファイル全てを保存する)
  3. データクラスタ内の全てのファイルを削除する。
  4. pg_basebackup で作成したベースバックアップをリストアする。
  5. もし pg_xlog ディレクトリに内にファイルがある場合は全て削除する。(ファイル、スナップショットのベースバックアップの場合は pg_xlog 内にファイルが残っている)
  6. ステップ 2 での WAL ファイルがある場合、pg_xlog ディレクトリにコピーする
  7. リカバリーコマンドを recovery.conf に記述する。pg_hba.conf ファイルでリカバリ中にユーザーが接続しないように設定する。
  8. サーバーを起動する。リカバリーモードとなり、リカバリが開始される。リカバリーが完了すると recovery.conf は recovery.done に名前が変更される。
  9. データが意図通りにリストアされているか確認する。問題ない場合は pg_hba.conf を修正し、ユーザーのアクセスを許可し、サーバーを再起動する。

■■recovery.conf の設定

recovery.conf ファイルには次の 3 つのコマンド設定が行えます。

restore_command 設定の例

restore_command = 'cp /mnt/server/archivedir/%f "%p"' # UNIX restore_command = 'copy "C:¥¥server¥¥archivedir¥¥%f" "%p"' # Windows 

restore_command には postgresql.conf の archive_command で指定したディレクトリを指定します。この設定はリカバリに必須です。

archive_cleanup_command 設定の例

archive_cleanup_command = 'pg_archivecleanup /mnt/server/archivedir %r' 

pg_archivecleanup コマンドは不要になったアーカイブログを削除します。一 つのアーカイブログから複数のサーバーをリカバリする場合やアーカイブログを保存したい場合はこの設定は必要ありません。

recovery_end_command 設定はリカバリが完了した場合に一度だけ実行されるコマンドを記述します。

リカバリーターゲット設定は以下の 3 つの設定が利用できます。

  • recovery_target_name (文字列):pg_create_restore_point 関数で指定された時点を指定する。
  • recovery_target_time (timestamp) :時刻を指定する。
  • recovery_target_xid (文字列) :トランザクション ID を指定する。

これら 3 つのうちの 1 つを指定します。また、リカバリーターゲットの取り扱いに次の 3 つのオプションが指定できます。

  • recovery_target_inclusive (論理値) : リカバリーターゲットを含む場合は true、リカバリーターゲットの直前までリストアする場合は false を指定する。
  • recovery_target_timeline (文字列) : タイムラインを指定する。詳しくは PostgreSQL 9.3 マニュアルの 24.3.5. Timelines を参照してください。
  • pause_at_recovery_target (論理値) : リカバリーターゲットに達した場合にリカバリーを停止する。デフォルトは true。

■■実際の実行例

次の実行例は以下の操作を行っています。

  1. 新規データベースを作成 (initdb)
    [pguser@dev tmp]$ initdb pgdata 
  2. アーカイブログに必要な設定ファイルを作成 (postgresql.conf, pg_hba.conf)
    [pguser@dev tmp]$ cp postgresql.conf pg_hba.conf pgdata 
  3. データベースを開始 (pg_ctl start)
    [pguser@dev tmp]$ pg_ctl -D pgdata start 
  4. ベースバックアップを作成 (pg_basebackup)
    [pguser@dev tmp]$ pg_basebackup -D - -Ft | bzip2 > backup.tar.bz2 
  5. データベースを 3 つ作成 (createdb)
    [pguser@dev tmp]$ createdb db1 [pguser@dev tmp]$ createdb db2 [pguser@dev tmp]$ createdb db3 
  6. リカバリターゲット時間となる時間を取得 (select now())
    [pguser@dev tmp]$ psql -c 'select now();' db1 
  7. 誤って db2 をドロップ (dropdb)
    [pguser@dev tmp]$ drop db2 
  8. データベースを停止 (pg_ctl stop)
    [pguser@dev tmp]$ pg_ctl -D pgdata stop 
  9. データベースクラスタを削除 (rm -rf pgdata/*)
    [pguser@dev tmp]$ rm -rf pgdata/* 
  10. ベースバックアップをリカバリ (tar jxvf ../backup.tar.bz2)
    [pguser@dev tmp]$ (cd pgdata/; tar jxvf ../backup.tar.bz2) 
  11. リカバリ設定をコピー (recovery.conf)
    [pguser@dev tmp]$ cp recovery.conf pgdata/ 
  12. データベースを開始&リカバリ開始 (pg_ctl -D pgdata start)
    [pguser@dev tmp]$ pg_ctl -D pgdata start 
  13. リカバリ後に誤ってドロップした db2 が存在することを確認 (psql -l)
    [pguser@dev tmp]$ psql -l 
pguser@dev tmp]$ initdb pgdata The files belonging to this database system will be owned by user "pguser". This user must also own the server process. The database cluster will be initialized with locale "ja_JP.utf8". The default database encoding has accordingly been set to "UTF8". initdb: could not find suitable text search configuration for locale "ja_JP.utf8" The default text search configuration will be set to "simple". Data page checksums are disabled. creating directory pgdata ... ok creating subdirectories ... ok selecting default max_connections ... 100 selecting default shared_buffers ... 128MB creating configuration files ... ok creating template1 database in pgdata/base/1 ... ok initializing pg_authid ... ok initializing dependencies ... ok creating system views ... ok loading system objects' descriptions ... ok creating collations ... ok creating conversions ... ok creating dictionaries ... ok setting privileges on built-in objects ... ok creating information schema ... ok loading PL/pgSQL server-side language ... ok vacuuming database template1 ... ok copying template1 to template0 ... ok copying template1 to postgres ... ok syncing data to disk ... ok WARNING: enabling "trust" authentication for local connections You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb. Success. You can now start the database server using: postgres -D pgdata or pg_ctl -D pgdata -l logfile start [pguser@dev tmp] diff -u pgdata/postgresql.conf postgresql.conf --- pgdata/postgresql.conf 2014-11-28 17:52:54.020012187 +0900 +++ postgresql.conf 2014-11-28 16:36:54.078142219 +0900 @@ -160,7 +160,7 @@ # - Settings - -#wal_level = minimal # minimal, archive, or hot_standby +wal_level = archive # minimal, archive, or hot_standby # (change requires restart) #fsync = on # turns forced synchronization on or off #synchronous_commit = on # synchronization level; @@ -189,9 +189,9 @@ # - Archiving - -#archive_mode = off # allows archiving to be done +archive_mode = on # allows archiving to be done # (change requires restart) -#archive_command = '' # command to use to archive a logfile segment +archive_command = 'test ! -f /tmp/archivedir/%f && cp %p /tmp/archivedir/%f' # command to use to archive a logfile segment # placeholders: %p = path of file to archive # %f = file name only # e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' @@ -207,7 +207,7 @@ # Set these on the master and on any standby that will send replication data. -#max_wal_senders = 0 # max number of walsender processes +max_wal_senders = 2 # max number of walsender processes # (change requires restart) #wal_keep_segments = 0 # in logfile segments, 16MB each; 0 disables #wal_sender_timeout = 60s # in milliseconds; 0 disables [pguser@dev tmp]$ diff -u pgdata/pg_hba.conf pg_hba.conf --- pgdata/pg_hba.conf 2014-11-28 17:52:54.020012187 +0900 +++ pg_hba.conf 2014-11-28 16:37:08.969043881 +0900 @@ -88,6 +88,6 @@ host all all ::1/128 trust # Allow replication connections from localhost, by a user with the # replication privilege. -#local replication pguser trust -#host replication pguser 127.0.0.1/32 trust -#host replication pguser ::1/128 trust +local replication pguser trust +host replication pguser 127.0.0.1/32 trust +host replication pguser ::1/128 trust [pguser@dev tmp]$ cp postgresql.conf pg_hba.conf pgdata cp: `pgdata/postgresql.conf' を上書きしますか? yes cp: `pgdata/pg_hba.conf' を上書きしますか? yes [pguser@dev tmp]$ pg_ctl -D pgdata start server starting [pguser@dev tmp]$ LOG: database system was shut down at 2014-11-28 17:52:54 JST LOG: database system is ready to accept connections LOG: autovacuum launcher started [pguser@dev tmp]$ pg_basebackup -D - -Ft | bzip2 > backup.tar.bz2 NOTICE: pg_stop_backup complete, all required WAL segments have been archived [pguser@dev tmp]$ createdb db1 [pguser@dev tmp]$ createdb db2 [pguser@dev tmp]$ createdb db3 [pguser@dev tmp]$ psql -l Timing is on. Null display is "?". Line style is unicode. Border style is 2. You are connected to database "postgres" as user "pguser" via socket in "/tmp" at port "5432". List of databases ┌───────────┬─────────┬──────────┬────────────┬────────────┬─────────────────────┐ │ Name │ Owner │ Encoding │ Collate │ Ctype │ Access privileges │ ├───────────┼─────────┼──────────┼────────────┼────────────┼─────────────────────┤ │ db1 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ db2 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ db3 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ postgres │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ template0 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ =c/pguser ?│ │ │ │ │ │ │ pguser=CTc/pguser │ │ template1 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ =c/pguser ?│ │ │ │ │ │ │ pguser=CTc/pguser │ └───────────┴─────────┴──────────┴────────────┴────────────┴─────────────────────┘ (6 rows) [pguser@dev tmp]$ psql -c 'select now();' db1 now ------------------------------- 2014-11-28 17:54:26.212748+09 (1 row) [pguser@dev tmp]$ drop db2 [pguser@dev tmp]$ psql -l Timing is on. Null display is "?". Line style is unicode. Border style is 2. You are connected to database "postgres" as user "pguser" via socket in "/tmp" at port "5432". List of databases ┌───────────┬─────────┬──────────┬────────────┬────────────┬─────────────────────┐ │ Name │ Owner │ Encoding │ Collate │ Ctype │ Access privileges │ ├───────────┼─────────┼──────────┼────────────┼────────────┼─────────────────────┤ │ db1 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ db3 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ postgres │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ template0 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ =c/pguser ?│ │ │ │ │ │ │ pguser=CTc/pguser │ │ template1 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ =c/pguser ?│ │ │ │ │ │ │ pguser=CTc/pguser │ └───────────┴─────────┴──────────┴────────────┴────────────┴─────────────────────┘ (5 rows) [pguser@dev tmp]$ pg_ctl -D pgdata stop waiting for server to shut down....LOG: received smart shutdown request LOG: autovacuum launcher shutting down LOG: shutting down LOG: database system is shut down done server stopped [pguser@dev tmp]$ rm -rf pgdata/* [pguser@dev tmp]$ (cd pgdata/; tar jxvf ../backup.tar.bz2) backup_label global/ global/pg_filenode.map global/12692 global/12694 global/12695 global/12825 global/12827 global/12829 global/12830 global/12831 global/12833 global/12834 global/12835 global/12837 global/12838 global/12840 global/12841 global/12842 global/12844 global/12845 global/12846 global/12848 global/12850 global/12851 global/12896 global/12898 global/12692_vm global/12692_fsm global/12831_vm global/12831_fsm global/12835_vm global/12835_fsm global/12842_vm global/12842_fsm global/12846_vm global/12846_fsm global/12945 global/12947 global/12948 pg_xlog/ pg_clog/ pg_clog/0000 pg_notify/ pg_notify/0000 pg_serial/ pg_snapshots/ pg_subtrans/ pg_subtrans/0000 pg_twophase/ pg_multixact/ pg_multixact/members/ pg_multixact/members/0000 pg_multixact/offsets/ pg_multixact/offsets/0000 base/ base/1/ base/1/pg_filenode.map base/1/PG_VERSION base/1/12682 base/1/12684 base/1/12686 base/1/12687 base/1/12688 base/1/12690 base/1/12691 base/1/12696 base/1/12698 base/1/12699 base/1/12700 base/1/12702 base/1/12703 base/1/12704 base/1/12700_fsm base/1/12706 base/1/12708 base/1/12709 base/1/12710 base/1/12711 base/1/12713 base/1/12714 base/1/12715 base/1/12717 base/1/12719 base/1/12720 base/1/12721 base/1/12722 base/1/12724 base/1/12726 base/1/12727 base/1/12728 base/1/12729 base/1/12730 base/1/12731 base/1/12733 base/1/12734 base/1/12735 base/1/12737 base/1/12738 base/1/12739 base/1/12741 base/1/12742 base/1/12743 base/1/12745 base/1/12746 base/1/12747 base/1/12749 base/1/12750 base/1/12751 base/1/12753 base/1/12754 base/1/12755 base/1/12757 base/1/12758 base/1/12759 base/1/12760 base/1/12762 base/1/12763 base/1/12764 base/1/12766 base/1/12767 base/1/12768 base/1/12770 base/1/12771 base/1/12773 base/1/12774 base/1/12776 base/1/12778 base/1/12779 base/1/12780 base/1/12781 base/1/12783 base/1/12785 base/1/12786 base/1/12787 base/1/12788 base/1/12789 base/1/12791 base/1/12792 base/1/12793 base/1/12795 base/1/12797 base/1/12798 base/1/12799 base/1/12801 base/1/12802 base/1/12803 base/1/12805 base/1/12806 base/1/12807 base/1/12808 base/1/12810 base/1/12811 base/1/12812 base/1/12814 base/1/12815 base/1/12816 base/1/12817 base/1/12819 base/1/12820 base/1/12852 base/1/12854 base/1/12855 base/1/12856 base/1/12858 base/1/12859 base/1/12861 base/1/12862 base/1/12863 base/1/12865 base/1/12866 base/1/12867 base/1/12869 base/1/12870 base/1/12871 base/1/12873 base/1/12874 base/1/12875 base/1/12877 base/1/12878 base/1/12879 base/1/12881 base/1/12882 base/1/12883 base/1/12885 base/1/12886 base/1/12888 base/1/12889 base/1/12890 base/1/12892 base/1/12894 base/1/12895 base/1/12899 base/1/12901 base/1/12902 base/1/12903 base/1/12905 base/1/12906 base/1/12908 base/1/12909 base/1/12911 base/1/12913 base/1/12914 base/1/12916 base/1/12918 base/1/12919 base/1/12921 base/1/12923 base/1/12924 base/1/12926 base/1/12928 base/1/12929 base/1/12931 base/1/12933 base/1/12934 base/1/12936 base/1/12938 base/1/12939 base/1/12941 base/1/12943 base/1/12682_vm base/1/12682_fsm base/1/12684_vm base/1/12684_fsm base/1/12688_vm base/1/12688_fsm base/1/12700_vm base/1/12704_vm base/1/12704_fsm base/1/12711_vm base/1/12711_fsm base/1/12722_vm base/1/12722_fsm base/1/12735_vm base/1/12735_fsm base/1/12739_vm base/1/12739_fsm base/1/12743_vm base/1/12743_fsm base/1/12747_vm base/1/12747_fsm base/1/12751_vm base/1/12751_fsm base/1/12755_vm base/1/12755_fsm base/1/12760_vm base/1/12760_fsm base/1/12764_vm base/1/12764_fsm base/1/12774_vm base/1/12774_fsm base/1/12776_vm base/1/12776_fsm base/1/12793_vm base/1/12793_fsm base/1/12799_vm base/1/12799_fsm base/1/12808_vm base/1/12808_fsm base/1/12812_vm base/1/12812_fsm base/1/12817_vm base/1/12817_fsm base/1/12852_vm base/1/12852_fsm base/1/12856_vm base/1/12856_fsm base/1/12859_vm base/1/12859_fsm base/1/12863_vm base/1/12863_fsm base/1/12867_vm base/1/12867_fsm base/1/12871_vm base/1/12871_fsm base/1/12903_vm base/1/12903_fsm base/1/12914_vm base/1/12914_fsm base/1/12919_vm base/1/12919_fsm base/1/12924_vm base/1/12924_fsm base/1/12934_vm base/1/12934_fsm base/1/12771_vm base/1/12771_fsm base/1/12909_vm base/1/12909_fsm base/1/12899_vm base/1/12899_fsm base/1/12929_vm base/1/12929_fsm base/12944/ base/12944/pg_filenode.map base/12944/PG_VERSION base/12944/12682 base/12944/12684 base/12944/12686 base/12944/12687 base/12944/12688 base/12944/12690 base/12944/12691 base/12944/12696 base/12944/12698 base/12944/12699 base/12944/12700 base/12944/12702 base/12944/12703 base/12944/12704 base/12944/12700_fsm base/12944/12706 base/12944/12708 base/12944/12709 base/12944/12710 base/12944/12711 base/12944/12713 base/12944/12714 base/12944/12715 base/12944/12717 base/12944/12719 base/12944/12720 base/12944/12721 base/12944/12722 base/12944/12724 base/12944/12726 base/12944/12727 base/12944/12728 base/12944/12729 base/12944/12730 base/12944/12731 base/12944/12733 base/12944/12734 base/12944/12735 base/12944/12737 base/12944/12738 base/12944/12739 base/12944/12741 base/12944/12742 base/12944/12743 base/12944/12745 base/12944/12746 base/12944/12747 base/12944/12749 base/12944/12750 base/12944/12751 base/12944/12753 base/12944/12754 base/12944/12755 base/12944/12757 base/12944/12758 base/12944/12759 base/12944/12760 base/12944/12762 base/12944/12763 base/12944/12764 base/12944/12766 base/12944/12767 base/12944/12768 base/12944/12770 base/12944/12771 base/12944/12773 base/12944/12774 base/12944/12776 base/12944/12778 base/12944/12779 base/12944/12780 base/12944/12781 base/12944/12783 base/12944/12785 base/12944/12786 base/12944/12787 base/12944/12788 base/12944/12789 base/12944/12791 base/12944/12792 base/12944/12793 base/12944/12795 base/12944/12797 base/12944/12798 base/12944/12799 base/12944/12801 base/12944/12802 base/12944/12803 base/12944/12805 base/12944/12806 base/12944/12807 base/12944/12808 base/12944/12810 base/12944/12811 base/12944/12812 base/12944/12814 base/12944/12815 base/12944/12816 base/12944/12817 base/12944/12819 base/12944/12820 base/12944/12852 base/12944/12854 base/12944/12855 base/12944/12856 base/12944/12858 base/12944/12859 base/12944/12861 base/12944/12862 base/12944/12863 base/12944/12865 base/12944/12866 base/12944/12867 base/12944/12869 base/12944/12870 base/12944/12871 base/12944/12873 base/12944/12874 base/12944/12875 base/12944/12877 base/12944/12878 base/12944/12879 base/12944/12881 base/12944/12882 base/12944/12883 base/12944/12885 base/12944/12886 base/12944/12888 base/12944/12889 base/12944/12890 base/12944/12892 base/12944/12894 base/12944/12895 base/12944/12899 base/12944/12901 base/12944/12902 base/12944/12903 base/12944/12905 base/12944/12906 base/12944/12908 base/12944/12909 base/12944/12911 base/12944/12913 base/12944/12914 base/12944/12916 base/12944/12918 base/12944/12919 base/12944/12921 base/12944/12923 base/12944/12924 base/12944/12926 base/12944/12928 base/12944/12929 base/12944/12931 base/12944/12933 base/12944/12934 base/12944/12936 base/12944/12938 base/12944/12939 base/12944/12941 base/12944/12943 base/12944/12682_vm base/12944/12682_fsm base/12944/12684_vm base/12944/12684_fsm base/12944/12688_vm base/12944/12688_fsm base/12944/12700_vm base/12944/12704_vm base/12944/12704_fsm base/12944/12711_vm base/12944/12711_fsm base/12944/12722_vm base/12944/12722_fsm base/12944/12735_vm base/12944/12735_fsm base/12944/12739_vm base/12944/12739_fsm base/12944/12743_vm base/12944/12743_fsm base/12944/12747_vm base/12944/12747_fsm base/12944/12751_vm base/12944/12751_fsm base/12944/12755_vm base/12944/12755_fsm base/12944/12760_vm base/12944/12760_fsm base/12944/12764_vm base/12944/12764_fsm base/12944/12774_vm base/12944/12774_fsm base/12944/12776_vm base/12944/12776_fsm base/12944/12793_vm base/12944/12793_fsm base/12944/12799_vm base/12944/12799_fsm base/12944/12808_vm base/12944/12808_fsm base/12944/12812_vm base/12944/12812_fsm base/12944/12817_vm base/12944/12817_fsm base/12944/12852_vm base/12944/12852_fsm base/12944/12856_vm base/12944/12856_fsm base/12944/12859_vm base/12944/12859_fsm base/12944/12863_vm base/12944/12863_fsm base/12944/12867_vm base/12944/12867_fsm base/12944/12871_vm base/12944/12871_fsm base/12944/12903_vm base/12944/12903_fsm base/12944/12914_vm base/12944/12914_fsm base/12944/12919_vm base/12944/12919_fsm base/12944/12924_vm base/12944/12924_fsm base/12944/12934_vm base/12944/12934_fsm base/12944/12771_vm base/12944/12771_fsm base/12944/12909_vm base/12944/12909_fsm base/12944/12899_vm base/12944/12899_fsm base/12944/12929_vm base/12944/12929_fsm base/12949/ base/12949/pg_filenode.map base/12949/PG_VERSION base/12949/12682 base/12949/12684 base/12949/12686 base/12949/12687 base/12949/12688 base/12949/12690 base/12949/12691 base/12949/12696 base/12949/12698 base/12949/12699 base/12949/12700 base/12949/12702 base/12949/12703 base/12949/12704 base/12949/12700_fsm base/12949/12706 base/12949/12708 base/12949/12709 base/12949/12710 base/12949/12711 base/12949/12713 base/12949/12714 base/12949/12715 base/12949/12717 base/12949/12719 base/12949/12720 base/12949/12721 base/12949/12722 base/12949/12724 base/12949/12726 base/12949/12727 base/12949/12728 base/12949/12729 base/12949/12730 base/12949/12731 base/12949/12733 base/12949/12734 base/12949/12735 base/12949/12737 base/12949/12738 base/12949/12739 base/12949/12741 base/12949/12742 base/12949/12743 base/12949/12745 base/12949/12746 base/12949/12747 base/12949/12749 base/12949/12750 base/12949/12751 base/12949/12753 base/12949/12754 base/12949/12755 base/12949/12757 base/12949/12758 base/12949/12759 base/12949/12760 base/12949/12762 base/12949/12763 base/12949/12764 base/12949/12766 base/12949/12767 base/12949/12768 base/12949/12770 base/12949/12771 base/12949/12773 base/12949/12774 base/12949/12776 base/12949/12778 base/12949/12779 base/12949/12780 base/12949/12781 base/12949/12783 base/12949/12785 base/12949/12786 base/12949/12787 base/12949/12788 base/12949/12789 base/12949/12791 base/12949/12792 base/12949/12793 base/12949/12795 base/12949/12797 base/12949/12798 base/12949/12799 base/12949/12801 base/12949/12802 base/12949/12803 base/12949/12805 base/12949/12806 base/12949/12807 base/12949/12808 base/12949/12810 base/12949/12811 base/12949/12812 base/12949/12814 base/12949/12815 base/12949/12816 base/12949/12817 base/12949/12819 base/12949/12820 base/12949/12852 base/12949/12854 base/12949/12855 base/12949/12856 base/12949/12858 base/12949/12859 base/12949/12861 base/12949/12862 base/12949/12863 base/12949/12865 base/12949/12866 base/12949/12867 base/12949/12869 base/12949/12870 base/12949/12871 base/12949/12873 base/12949/12874 base/12949/12875 base/12949/12877 base/12949/12878 base/12949/12879 base/12949/12881 base/12949/12882 base/12949/12883 base/12949/12885 base/12949/12886 base/12949/12888 base/12949/12889 base/12949/12890 base/12949/12892 base/12949/12894 base/12949/12895 base/12949/12899 base/12949/12901 base/12949/12902 base/12949/12903 base/12949/12905 base/12949/12906 base/12949/12908 base/12949/12909 base/12949/12911 base/12949/12913 base/12949/12914 base/12949/12916 base/12949/12918 base/12949/12919 base/12949/12921 base/12949/12923 base/12949/12924 base/12949/12926 base/12949/12928 base/12949/12929 base/12949/12931 base/12949/12933 base/12949/12934 base/12949/12936 base/12949/12938 base/12949/12939 base/12949/12941 base/12949/12943 base/12949/12682_vm base/12949/12682_fsm base/12949/12684_vm base/12949/12684_fsm base/12949/12688_vm base/12949/12688_fsm base/12949/12700_vm base/12949/12704_vm base/12949/12704_fsm base/12949/12711_vm base/12949/12711_fsm base/12949/12722_vm base/12949/12722_fsm base/12949/12735_vm base/12949/12735_fsm base/12949/12739_vm base/12949/12739_fsm base/12949/12743_vm base/12949/12743_fsm base/12949/12747_vm base/12949/12747_fsm base/12949/12751_vm base/12949/12751_fsm base/12949/12755_vm base/12949/12755_fsm base/12949/12760_vm base/12949/12760_fsm base/12949/12764_vm base/12949/12764_fsm base/12949/12774_vm base/12949/12774_fsm base/12949/12776_vm base/12949/12776_fsm base/12949/12793_vm base/12949/12793_fsm base/12949/12799_vm base/12949/12799_fsm base/12949/12808_vm base/12949/12808_fsm base/12949/12812_vm base/12949/12812_fsm base/12949/12817_vm base/12949/12817_fsm base/12949/12852_vm base/12949/12852_fsm base/12949/12856_vm base/12949/12856_fsm base/12949/12859_vm base/12949/12859_fsm base/12949/12863_vm base/12949/12863_fsm base/12949/12867_vm base/12949/12867_fsm base/12949/12871_vm base/12949/12871_fsm base/12949/12903_vm base/12949/12903_fsm base/12949/12914_vm base/12949/12914_fsm base/12949/12919_vm base/12949/12919_fsm base/12949/12924_vm base/12949/12924_fsm base/12949/12934_vm base/12949/12934_fsm base/12949/12771_vm base/12949/12771_fsm base/12949/12909_vm base/12949/12909_fsm base/12949/12899_vm base/12949/12899_fsm base/12949/12929_vm base/12949/12929_fsm pg_tblspc/ pg_stat/ pg_stat_tmp/ pg_stat_tmp/global.stat PG_VERSION postgresql.conf pg_hba.conf pg_ident.conf global/pg_control [pguser@dev tmp]$ ls /tmp/archivedir/ 000000010000000000000001 000000010000000000000002.00000028.backup 000000010000000000000002 000000010000000000000003 [pguser@dev tmp]$ cat recovery.conf restore_command = 'cp /tmp/archivedir/%f "%p"' recovery_target_time = '2014-11-28 17:54:26.212748+09' [pguser@dev tmp]$ cp recovery.conf pgdata/ [pguser@dev tmp]$ pg_ctl -D pgdata start server starting [pguser@dev tmp]$ LOG: database system was interrupted; last known up at 2014-11-28 17:53:47 JST LOG: creating missing WAL directory "pg_xlog/archive_status" LOG: starting point-in-time recovery to 2014-11-28 17:54:26.212748+09 LOG: restored log file "000000010000000000000002" from archive LOG: redo starts at 0/2000090 LOG: consistent recovery state reached at 0/20000B8 LOG: restored log file "000000010000000000000003" from archive LOG: recovery stopping before commit of transaction 1892, time 2014-11-28 17:54:34.021328+09 LOG: redo done at 0/30022A0 LOG: last completed transaction was at log time 2014-11-28 17:54:17.830576+09 cp: `/tmp/archivedir/00000002.history' を stat できません: そのようなファイルやディレクトリはありません LOG: selected new timeline ID: 2 cp: `/tmp/archivedir/00000001.history' を stat できません: そのようなファイルやディレクトリはありません LOG: archive recovery complete LOG: database system is ready to accept connections LOG: autovacuum launcher started LOG: archive command failed with exit code 1 DETAIL: The failed archive command was: test ! -f /tmp/archivedir/000000010000000000000003 && cp pg_xlog/000000010000000000000003 /tmp/archivedir/000000010000000000000003 LOG: archive command failed with exit code 1 DETAIL: The failed archive command was: test ! -f /tmp/archivedir/000000010000000000000003 && cp pg_xlog/000000010000000000000003 /tmp/archivedir/000000010000000000000003 LOG: archive command failed with exit code 1 DETAIL: The failed archive command was: test ! -f /tmp/archivedir/000000010000000000000003 && cp pg_xlog/000000010000000000000003 /tmp/archivedir/000000010000000000000003 WARNING: archiving transaction log file "000000010000000000000003" failed too many times, will try again later [pguser@dev tmp]$ psql -l Timing is on. Null display is "?". Line style is unicode. Border style is 2. You are connected to database "postgres" as user "pguser" via socket in "/tmp" at port "5432". List of databases ┌───────────┬─────────┬──────────┬────────────┬────────────┬─────────────────────┐ │ Name │ Owner │ Encoding │ Collate │ Ctype │ Access privileges │ ├───────────┼─────────┼──────────┼────────────┼────────────┼─────────────────────┤ │ db1 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ db2 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ db3 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ postgres │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ │ │ template0 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ =c/pguser ?│ │ │ │ │ │ │ pguser=CTc/pguser │ │ template1 │ pguser │ UTF8 │ ja_JP.utf8 │ ja_JP.utf8 │ =c/pguser ?│ │ │ │ │ │ │ pguser=CTc/pguser │ └───────────┴─────────┴──────────┴────────────┴────────────┴─────────────────────┘ (6 rows) 

■ まとめ

PITR の設定はそれほど難しい物ではありませんが、アーカイブコマンドに間違いがある、アーカイブ先のディレクトリが存在しない、ディレクトリにアクセス権限がない、などの問題があると動作しません。これらのエラーは PostgreSQL のログファイルに記録されます。エラーメッセージを確認すると問題の原因が分かります。操作には慣れておかないといざという時に落ち着いて対処できないと思います。何度かリカバリを試しておくと良いでしょう。

PITR はデータベース操作ミスなどで誤ってデータベースを壊してしまった時の復旧には欠かせません。アーカイブログをコピーするだけなのでオーバーヘッドは小さいです。万が一の場合に備えて、PITR を設定しておくとより安全です。

ベースバックアップを取得してからの時間が長くなればなるほど、データ量も大きくなり、リカバリ時間も長くなります。データ容量を考えながら、ベースバックアップを取得する頻度とアーカイブログの取得を調整すると良いでしょう。

サイオスOSSよろず相談室

サイオスOSSよろず相談室(1)

問い合わせボタン