pg_rman (PostgreSQL のバックアップ/リストア管理ツール)

更新日:2025年1月17日

pg_rman とは

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

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

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

2025年 1月時点の最新バージョンは 1.3.16 で、PostgreSQL 11.x から 17.x まで対応するパッケージが用意されており、Linux 上で動作します。各種の UNIX でも概ね動作すると考えられます。Windows には対応していません。
注意点としては、バージョン 1.3.7 は 1.3.6 以前のバージョンと互換性がなく、1.3.7 で復旧させるには 1.3.7 で取得したフルバックアップが必要となります。また、1.3.9 から 1.3.11 の間のバージョンでは増分バックアップが正しく動かないため、該当のバージョンを使用している場合は、1.3.12 以上にアップデートしてください。

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

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

機能

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

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

基本的な使い方

本記事では、Rocky Linux 9.4、PostgreSQL16.4、pg_rman 1.3.16 を使用して動作検証を行います。
まず最初に pg_rman のインストールを行います。
ソースコードからのインストールの場合、ソースコードをダウンロードした後に以下のコマンドを実行します。

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

RPMを用いたインストールの場合、OSとPostgreSQLのバージョンに合った RPMファイルをダウンロードしインストールすれば完了です。

# rpm -ivh pg_rman-1.3.16-1.pg16.rhel9.x86_64.rpm

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

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

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

$ 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
=====================================================================
 StartTime           EndTime              Mode    Size   TLI  Status
=====================================================================
2024-12-27 15:55:50  2024-12-27 15:55:53  INCR    33MB     1  OK
2024-12-27 15:34:59  2024-12-27 15:35:09  FULL  1179MB     1  OK

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

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

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

$ pg_ctl stop -m immediate

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

$ pg_rman restore

任意の時点の内容をリストアしたい、例えば2024年12月27日の15:40:00時点に遡りたいときは以下のように入力します。最初のバックアップ時に戻すには StartTime 列に示された日付時刻ではなく EndTime 列 を指定する必要があります。(つまり、pg_rman がリカバリ可能なのは一番古いバックアップの EndTime からの時点ということです。)

$ pg_rman restore --recovery-target-time '2024-12-27 15:40:00'

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

$ pg_ctl start

応用的な使い方

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

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

  • detail オプションを追加し、各バックアップの詳細情報を一覧で表示。1.3.0 より前のバージョンでは detail オプションの代わりに timeline オプションを使用してください。
    $ pg_rman show detail
    ======================================================================================================================
     StartTime           EndTime              Mode    Data  ArcLog  SrvLog   Total  Compressed  CurTLI  ParentTLI  Status
    ======================================================================================================================
    2024-12-27 15:55:50  2024-12-27 15:55:53  INCR  1744kB    33MB    36kB    33MB       false       1          0  OK
    2024-12-27 15:34:59  2024-12-27 15:35:09  FULL  1168MB    33MB    ----  1179MB       false       1          0  OK
    
  • Start 列に示された日付時刻を指定して、そのバックアップに関する詳細を表示。
    $ pg_rman show '2024-12-27 15:55:50'
    # configuration
    BACKUP_MODE=INCREMENTAL
    FULL_BACKUP_ON_ERROR=false
    WITH_SERVERLOG=true
    COMPRESS_DATA=false
    # result
    TIMELINEID=1
    START_LSN=0/48000028
    STOP_LSN=0/48000100
    START_TIME='2024-12-27 15:55:50'
    END_TIME='2024-12-27 15:55:53'
    RECOVERY_XID=860
    RECOVERY_TIME='2024-12-27 15:55:52'
    TOTAL_DATA_BYTES=1168336086
    READ_DATA_BYTES=1744904
    READ_ARCLOG_BYTES=33554780
    READ_SRVLOG_BYTES=36708
    WRITE_BYTES=33722266
    BLOCK_SIZE=8192
    XLOG_BLOCK_SIZE=8192
    STATUS=OK

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

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

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

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

バックアップの削除

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

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

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

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

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

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

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

ストレージスナップショットとの連携

pg_rman では、ストレージ・スナップショットがサポートされています。使用しているファイルシステム以下のストレージ基盤でスナップショットが利用可能であり、データベースクラスタやテーブルスペースのボリュームが他の領域と分離していることが前提条件です。

使用するには、{BACKUP_PATH}/snapshot_script ファイルを作成します。バックアップカタログ直下にスクリプトが存在すると、スナップショット機能が利用可能と判断し、pg_rman は自動的にスナップショット機能を使用します。リストア時はスナップショットは使用しません。
バックアップ時にデータベース領域のストレージスナップショットを取得した後、その領域をマウントします。マウントしたスナップショットのデータベースからバックアップファイルをコピーし、コピー完了後はスナップショットは削除されます。

スナップショットスクリプトのサンプルとして、ソースコードに script/snapshot_script_lvm.sh ファイルがが用意されているのでご確認ください。

pg_basebackup との比較

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

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

  • pg_rman が優れている点
    • バックアップの世代管理が可能
    • アーカイブログ、サーバログもバックアップ対象にできる
    • 増分バックアップが可能(ただし、PostgreSQL 17.x系から pg_basebackup でも増分バックアップが可能になった)
    • PostgreSQL 8.2 から対応
    • ストレージスナップショットをサポート
  • pg_basebackup が優れている点
    • リモート操作が可能
    • PostgreSQL の標準コマンドである
    • Windows 環境でも動作する

おわりに

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

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

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