pg_rman とは

pg_rman とは PostgreSQL のバックアップ/リストア管理ツールです。

PostgreSQL 付属のバックアップ手段にはダンプと PITR があります。ダンプはリストアしてもバックアップした時点の状態まで戻ってしまいますが、PITR を用いればバックアップした時点から稼働時の直前まで任意の時点の状態にリストアできるといった利点があります。しかし、PITR のバックアップ/リストアは煩雑な手順が必要となります。

pg_rman は PITR の機能を簡易なコマンドで扱うことができます。また、バックアップの世代管理ができることも魅力の一つです。

2018年 10月時点の最新バージョンは 1.3.7 で、PostgreSQL 9.2.x から 10.x まで対応するパッケージが用意されており、Linux 上で動作します。各種の UNIX でも概ね動作すると考えられます。Windows には対応していません。
注意点としては、バージョン 1.3.7 は 1.3.6 以前のバージョンと互換性がなく、1.3.7 で復旧させるには 1.3.7 で取得したフルバックアップが必要となります。

詳細は pg_rman プロジェクトページをご覧ください。

pg_rman を用いたリストアの一例
PC 向けゲームポータルサイトのシステム構成図

機能

pg_rman は以下の機能を持っています。

  • 全体バックアップに加え、増分バックアップが可能
  • バックアップの圧縮が可能
  • バックアップの世代管理やバックアップ一覧を表示できる
  • バックアップの対象はデータベースクラスタの他にアーカイブログ、サーバログが含めることができる
  • タイムライン指定、リカバリしたい日付時刻指定が可能
  • データベースクラスタ外のテーブルスペースを含めたバックアップが可能

基本的な使い方

まず最初に pg_rman のインストールを行います。
ソースコードからのインストールの場合、ソースコードをダウンロードした後に以下のコマンドを実行します。

$ cd pg_rman
$ make USE_PGXS=1
$ make USE_PGXS=1 install

RPM パッケージも用意されており、そちらは pg_rman-*.rpm という RPM ファイルをインストールすれば完了です。

インストールを終えたら、バックアップファイルや管理情報を保存するバックアップカタログの初期化を行います。このとき、postgresql.conf の以下の設定をしておくことで、pg_rman の設定ファイルの初期値を設定することができます。

$ vi postgresql.conf
archive_mode = on
archive_command = 'cp %p /mnt/arch/%f'
wal_level = archive
log_directory = 'pg_log'

さらに以下のパスを環境変数化しておくと今後 pg_rman のコマンドが短くてすみます。
※ 実用環境ではなるべくバックアップカタログパスは DB 稼動ホスト内のパスではなく、ネットワークマウントしたストレージ内のパスを指定してください。

$ export BACKUP_PATH=<バックアップカタログパス>
$ export PGDATA=<PostgreSQL データベースクラスタパス>

バックアップカタログを初期化します。

$ pg_rman init

これで準備は完了です。次は実際にバックアップを取得してみましょう。以下は全体バックアップの例です。

$ pg_rman backup --backup-mode=full

バックアップが完了しました。ただし、後にバックアップの検証を行う必要があります。

$ pg_rman validate

validate によるバックアップの検証はバックアップ直後に行う必要はありませんが、なるべく早い段階で行なってください。検証がなされていないバックアップはリストアができませんし、次回の増分バックアップも行えません。

全体バックアップを行なった後は増分バックアップが可能です。増分バックアップは前回のバックアップから変更のあったファイル・ページのみのバックアップです。下の例では–with-serverlog を指定することでサーバログもバックアップとして取得しています。ここでもやはり、増分バックアップもバックアップの検証を行ないます。

$ pg_rman backup --backup-mode=incremental --with-serverlog
$ pg_rman validate

では次にバックアップが取得できているか確認してみましょう。

$ pg_rman show
============================================================================
Start                Time   Total    Data     WAL     Log  Backup   Status
============================================================================
2014-08-06 19:15:18    0m    ----    16kB    67MB    ----    67MB   OK
2014-08-06 19:09:18    0m    20MB    ----    50MB    ----    66MB   OK

show コマンドによって今まで取得したバックアップの一覧表示が可能です。バックアップの開始時刻が新しいほうが上に表示されていることに注意してください。Status が OK となっていればリストアに利用することができます。

では、取得したバックアップからデータベースクラスタをリストアしてみましょう。現在のデータベースクラスタは削除されるのでご注意ください。

まず、リストアを行う前に PostgreSQL サーバを停止してください。

$ pg_ctl stop -m immediate

なるべく最新の状態に戻したい場合は特にオプションを付けずに restore コマンドを実行します。このとき、既存のデータベースクラスタが残っている場合はアーカイブ前の WAL がバックアップされます。また、その WAL は次の全体バックアップを取得するまで保存されます。

$ pg_rman restore

任意の時点の内容をリストアしたい、例えば2014年8月6日の19:12:00の時点に遡りたいときは以下のように入力します。

$ pg_rman restore --recovery-target-time '2014-08-06 19:12:00'

リストアが終了したら、PostgreSQL サーバを起動してください。起動と同時にリカバリが実行されます。

$ pg_ctl start

応用的な使い方

バックアップの情報の詳細表示

show コマンドにより過去に取得したバックアップ一覧が表示できましたが、引数を追加することでより詳細な情報を得ることができます。

  • timeline を追加し、バックアップのタイムラインとバックアップモードを表示
    $ pg_rman show timeline
    ============================================================
    Start                Mode  Current TLI  Parent TLI  Status
    ============================================================
    2014-08-06 19:15:18  INCR            1           0  OK
    2014-08-06 19:09:18  FULL            1           0  OK
    
  • Start 列に示された日付時刻を指定して、そのバックアップに関する詳細を表示
    $ pg_rman show '2014-08-06 19:15:18'
    # configuration
    BACKUP_MODE=INCREMENTAL
    WITH_SERVERLOG=false
    COMPRESS_DATA=false
    # """"""""result
    TIMELINEID=1
    START_LSN=0/07000028
    STOP_LSN=0/070000b8
    START_TIME"""""""" ='2014-08-06 19:15:18'
    END_TIME='2014-08-06 """"""""19:15:20'
    RECOVERY_XID=1822
    RECOVERY_TIME"""""""" ='2014-08-06 19:15:20'
    TOTAL_DATA_BYTES=20876021
    READ_DATA_BYTES=16604
    READ_ARCLOG_BYTES=67109496
    WRITE_BYTES=67126100
    BLOCK_SIZE=8192
    XLOG_BLOCK_SIZE=8192
    STATUS=OK

一番古いバックアップの内容をリカバリする場合、RECOVERY_TIME を確認しておきましょう。なぜなら、最初のバックアップ時に戻す Start 列に示された日付時刻ではなく RECOVERY_TIME を指定する必要があるからです。(つまり、pg_rman がリカバリ可能なのは一番古いバックアップの RECOVERY_TIME からの時点ということです。)

レプリケーション使用時のスタンバイ側バックアップ

PostgreSQL 9.0 以降のレプリケーションをお使いの場合、スタンバイ側からバックアップを取得することが可能です。単体サーバ利用時とはバックアップ時の指定が異なります。以下の設定の場合のコマンドを示します。

マスタサーバのホスト名:master
スタンバイサーバのホスト名:localhost
スタンバイサーバのポート名:5432

$ pg_rman backup --backup-mode=full --host=master --standby-host=localhost --standby-port=5432

バックアップの削除

必要のないバックアップを delete コマンドで削除できます。

$ pg_rman delete <リストアが必要な日付時刻>

ここで、リストアが必要な日付時刻を指定していることに注意してください。つまり、delete コマンドは指定した日付時刻のバックアップを削除するのではなく、指定した日付時刻へのリカバリに不必要なバックアップを削除しています。

また、バックアップ時にデータの保持期限(世代数か保存日数)を指定し、保持期限を過ぎると削除する設定が可能です。(削除されるタイミングは次回の backup コマンド実行時です。)

(少なくとも 3 世代以上、かつ、10 日間以上保存)

$ pg_rman backup --keep-data-generations=3 --keep-data-days=10

バックアップデータ以外にアーカイブ WAL のみの保持期限やサーバログのみの保持期限に関しても同様に指定できます。

pg_basebackup との比較

pg_basebackup コマンドは PostgreSQL 9.1 から標準で使用できるようになったオンラインバックアップコマンドです。このコマンドの登場により、以前よりもベースバックアップの取得が容易になりました。

pg_rman と比較すると以下の様なことが言えます。

    • pg_rman が優れている点
      • バックアップの世代管理が可能
      • アーカイブログ、サーバログもバックアップ対象にできる
      • 増分バックアップが可能
      • PostgreSQL 8.2 から対応

 

  • pg_basebackup が優れている点
    • リモート操作が可能
    • PostgreSQL の標準コマンドである

おわりに

PostgreSQL バックアップ管理ツール pg_rman はいかがだったでしょうか。

PostgreSQL 9.1 から pg_basebackup コマンドが登場し、バックアップ作業が簡易になるという利点こそ薄れましたが、バックアップの世代管理が可能な点など、まだまだ pg_rman に軍配が上がる点は多いようです。

今回紹介しきれなかった機能やオプションなどは日本語マニュアルがありますので、ユーザマニュアルをご覧ください。