メインコンテンツへスキップ
友田 陽大
PostgreSQL 運用・信頼性
PostgreSQL
アーキテクチャ設計

PostgreSQL バックアップ & PITR 実践(pg_dump / 継続的アーカイブ / WAL / Point-in-Time Recovery・v18対応)

PostgreSQL のバックアップと復旧を本番品質で設計する実践ガイド。論理(pg_dump)・物理・継続的アーカイブの3方式の使い分け、pg_dump/pg_restoreの実コマンド、WALアーカイブとpg_basebackupによるPITR(任意の時点への復旧)の設定と復旧手順、PostgreSQL 17の増分バックアップ、復旧訓練の重要性、マネージドの自動PITRまでを、公式ドキュメントに忠実に解説します。

公開日
読了時間
10分
著者
友田 陽大
シェア

バックアップの話で最も大事なのは、コマンドの細部ではありません。**「いざというとき、本当に戻せるのか」**です。取れているつもりのダンプが壊れていた、復旧手順を誰も知らなかった、戻すのに丸一日かかった——これらは全部、復旧をテストしていないことが原因です。

この記事は、PostgreSQL のバックアップと復旧を「戻せる」前提で設計するためのガイドです。3方式の使い分けから、PITR(任意の時点への復旧)の設定と実際の復旧手順まで、公式ドキュメントに忠実に解説します。本番運用ガイド §2の深掘り——運用で最初に固めるべき領域です。

この記事のルール:バックアップ方式・コマンド・PITR の仕様・PostgreSQL 18/17 の機能は PostgreSQL 18 公式ドキュメント(2026年6月時点) に基づきます。RPO/RTO という用語は運用設計の一般語(公式ドキュメントの語ではない)として使います。マネージド(RDS等)の自動化はベンダー機能として明記します。


1. まず指標で考える:RPO と RTO

方式選定の前に、2つの指標で要件を言語化します。

  • RPO(Recovery Point Objective):障害時にどれだけのデータ損失を許容するか。「最大15分」「ゼロ」など。
  • RTO(Recovery Time Objective):障害からどれだけ早く復旧する必要があるか。「1時間以内」など。

この2つが方式を決めます。「夜次ダンプだけ」なら RPO は最大24時間(前回ダンプ以降を失う)。「1分も失えない」なら継続的アーカイブやレプリケーションが要ります。要件を数字にしてから方式を選ぶ——これが順番です。


2. 3つのバックアップ方式

PostgreSQL のバックアップは公式に3方式。

方式何ができる向く場面限界
論理(pg_dump稼働中に一貫スナップショット。SQL/可搬・選択復元・バージョン跨ぎ単一DBの移行・部分復元・小〜中規模DB単位。ロール/テーブルスペースは含まない
物理(ファイルコピー)データファイルを丸ごとコピー単純な全クラスタ複製サーバー停止が必須。クラスタ単位のみ
継続的アーカイブ(WAL)ベースバックアップ+WAL退避で任意の時点に復旧(PITR)本番基幹・低RPO・大規模設定が複雑・クラスタ単位

公式は物理ファイルバックアップについて明確に警告します:「使えるバックアップを得るにはデータベースサーバーを停止しなければならない。全接続を禁止する程度の中途半端な対策では機能しない」。だから稼働中の物理バックアップは、後述の pg_basebackup か、ファイルシステムスナップショットを使います。


3. 論理バックアップ:pg_dump / pg_dumpall

pg_dump最も手軽で可搬性が高い方式。公式曰く「pg_dump のダンプは内部的に一貫しており、pg_dump 開始時点のスナップショットを表す。pg_dump は処理中も他の操作をブロックしない」。稼働中に安全に取れます。

# 1) プレーンSQL(小規模・人間が読める)
pg_dump appdb > appdb.sql
psql -X -d appdb < appdb.sql                      # 復元

# 2) カスタム形式(推奨:圧縮・選択復元・並列復元が可能。復元は pg_restore)
pg_dump -Fc appdb > appdb.dump
pg_restore -d appdb appdb.dump

# 3) ディレクトリ形式 + 並列ダンプ/復元(大きいDBを速く)
pg_dump -Fd -j 4 -f appdb.dir appdb
pg_restore -d appdb -j 4 appdb.dir

最重要の落とし穴pg_dump単一DBしか対象にせず、ロール(ユーザー)・テーブルスペースなどクラスタ全体の定義を含みません。これらは pg_dumpall で別途取ります。

# クラスタ全体(ロール・テーブルスペース込み)
pg_dumpall > cluster.sql
# ロール/テーブルスペースだけ(グローバルのみ)— pg_dump と組み合わせる定番
pg_dumpall --globals-only > globals.sql

pg_dump で完璧」と思っていたら、復元先にロールが無くて権限が全部外れた——よくある事故です。**pg_dumpall -g(globals)+ pg_dump -Fc(各DB)**をセットで運用しましょう。

PostgreSQL 18 では pg_dump/pg_restore--statistics(オプティマイザ統計の移行)、--no-data/--no-schema/--sequence-data などの選択オプションが追加されました。


4. 継続的アーカイブと PITR:任意の時点へ戻す

低RPOの本命が継続的アーカイブです。公式の定義:「この技術はポイント・イン・タイム・リカバリ(PITR)を可能にする。ベースバックアップを取った時点以降の任意の時点にデータベースを復旧できる」。

仕組みは「ベースバックアップ(土台)+WALの継続退避(その後の全変更)」。復旧時は、土台を戻してから WAL を目的の時点まで再生します。

4.1 設定:WALをアーカイブする

# postgresql.conf
wal_level = replica           # replica 以上(archive を含む)
archive_mode = on
# 成功時のみ 0 を返し、既存ファイルを上書きしない(安全装置)
archive_command = 'test ! -f /mnt/archive/%f && cp %p /mnt/archive/%f'

公式が強調する2つの鉄則:

  1. 「アーカイブコマンドは、成功した場合に限り(if and only if)ゼロを返さねばならない」。0を返すと PostgreSQL はそのWALを削除・再利用するため、嘘の成功はWAL消失=復旧不能を招きます。
  2. 「既存のアーカイブファイルを上書きしないよう設計すべき」。管理者ミスからアーカイブの完全性を守る重要な安全機能です(上の test ! -f がそれ)。

実運用では cp ではなく、pgBackRestWAL-G、クラウドストレージ(S3等)への転送に置き換えます。これらは並列・圧縮・暗号化・保持ポリシー・リストア検証まで面倒を見てくれます。

4.2 ベースバックアップ:pg_basebackup

# 稼働中にベースバックアップ(クラスタ全体)。-X stream で自己完結、-R で復旧設定を生成
pg_basebackup -D /backup/base -Ft -z -X stream -c fast -R
#   -Ft: tar形式 / -z: 圧縮 / -X stream: WALを並列ストリーム同梱 / -c fast: 即時チェックポイント
#   -R: standby.signal と接続設定を書き出す(スタンバイ構築にも流用)

公式:「pg_basebackup は稼働中のクラスタのベースバックアップを取る。他のクライアントに影響を与えずに実行できる」。

4.3 復旧:目的の時点まで再生する

障害時、ベースバックアップを展開し、復旧設定を書いて起動すると、PostgreSQL が WAL を再生して目的の時点まで戻します。

# 復旧先の postgresql.conf(または postgresql.auto.conf)
restore_command = 'cp /mnt/archive/%f %p'       # アーカイブからWALを取り出す
recovery_target_time = '2026-06-24 09:41:00+09' # ここまで再生(誤DELETEの直前など)
recovery_target_action = 'promote'              # 到達したら通常稼働へ昇格
# データディレクトリに recovery.signal を置くと「目標復旧→昇格」モードで起動する
touch /var/lib/postgresql/18/main/recovery.signal
pg_ctl start

公式の要点:

  • 「絶対に指定しなければならないのは restore_command——アーカイブからWALを取り出す方法。
  • 復旧目標は recovery_target_time / _lsn / _xid / _name のいずれか(実用的なのは時刻名前付き復元ポイント)。
  • recovery.signal があれば「目標まで復旧して昇格」、standby.signal ならスタンバイとして起動(HA記事)。完了時に信号ファイルは自動削除されます。
  • 停止点はベースバックアップの終了時刻より後でなければならない(バックアップ取得中の時点へは戻せない)。
  • backup_label ファイルは「単なる情報ではなく、復旧処理の正しい動作に不可欠」——消さない。

誤操作からの救済:PITR の真価は「誤った DELETE/DROP の直前に戻せる」こと。recovery_target_time をインシデント直前に設定すれば、人為ミスを巻き戻せます。これは単純なスナップショットにはできない芸当です。


5. 増分バックアップ(PostgreSQL 17+)

PostgreSQL 17増分バックアップが入りました(PG18 の新機能ではない点に注意)。前回バックアップ以降の差分だけを取り、容量と時間を削減します。

# フル → 増分(前回のマニフェストを参照)
pg_basebackup -D /backup/full -X stream
pg_basebackup -D /backup/incr1 --incremental=/backup/full/backup_manifest -X stream

# 増分は単独では使えない。pg_combinebackup でフルと合成してから復元する
pg_combinebackup /backup/full /backup/incr1 -o /backup/restored

公式:「増分バックアップは直接使えない。まず pg_combinebackup で、それが依存する以前のバックアップと合成しなければならない」。PostgreSQL 18 では pg_combinebackup-k/--link(ハードリンク)、pg_verifybackuptar形式検証対応などが追加されました。


6. 「戻せる」を保証する:復旧訓練を自動化する

バックアップ戦略の唯一の正しい検証は、実際に復元してみることです。これをCIや定期ジョブに組み込みます。

#!/usr/bin/env bash
# 定期実行する復旧訓練(最新バックアップを隔離環境に戻し、健全性を検証)
set -euo pipefail

RESTORE_DIR=$(mktemp -d)
trap 'rm -rf "$RESTORE_DIR"' EXIT          # 後始末(冪等・再実行安全)

# 1) 最新のフル+増分を合成して復元
pg_combinebackup /backup/full /backup/incr-latest -o "$RESTORE_DIR/data"

# 2) 隔離ポートで起動し、復旧完了を待つ
pg_ctl -D "$RESTORE_DIR/data" -o "-p 5499" start
until pg_isready -p 5499; do sleep 1; done

# 3) スモークチェック:行数や重要テーブルの存在を検証(戻ったことの証拠)
psql -p 5499 -d appdb -At -c "SELECT count(*) FROM orders" | grep -Eq '^[0-9]+$'

# 4) 停止(健全なら成功。失敗すれば非0で落ち、アラートが鳴る)
pg_ctl -D "$RESTORE_DIR/data" stop
echo "restore drill OK"

可観測性:この訓練ジョブの成否を監視に載せ、失敗=バックアップが壊れているとして即アラートします。「バックアップが取れているか」ではなく「戻せるか」を毎日確認するのが、本物の信頼性です。


7. マネージドの場合(RDS/Aurora/Cloud SQL)

マネージドサービスは、ここまでの継続的アーカイブとPITRを自動化します(ベンダー機能・公式PostgreSQLドキュメント外)。自動スナップショット+WALの継続退避により、コンソールやAPIから「特定タイムスタンプへの復元」が可能です。archive_commandpg_basebackup を手で運用する必要はありません。

ただし、論理バックアップ(pg_dump)は別途検討する価値があります。マネージドのスナップショットはクラスタ単位の物理復元が中心で、「特定のテーブルだけ別環境に復元」「バージョン跨ぎの移行」「マネージド障害に依存しない外部保管」には論理ダンプが有効です。多層防御として、マネージドPITR+定期 pg_dump の外部保管を組み合わせるのが堅実です。


8. まとめ

  • 「戻せる」が正義。RPO/RTO を数字にしてから方式を選び、復旧訓練を自動化する。
  • 3方式:論理(pg_dump、稼働中・可搬・DB単位)/物理(停止必須)/継続的アーカイブ(PITR)。
  • 低RPOは継続的アーカイブarchive_command は成功時のみ0・上書き禁止、pg_basebackup でベース、復旧は restore_commandrecovery_target_timerecovery.signal
  • pg_dump はロール/テーブルスペースを含まない——pg_dumpall -g を併用。
  • 増分バックアップは PG17+--incrementalpg_combinebackup)。
  • マネージドはPITRを自動化するが、論理ダンプの外部保管で多層防御を。

「壊さない」が固まったら、次は「落ちても止まらない」——ストリーミングレプリケーションと高可用性 へ。


参考(PostgreSQL 18 公式ドキュメント)

友田

友田 陽大

経済産業大臣賞 受賞プロダクト開発者。TypeScript + Python + AWS で、SaaS・業界DX・ 実用レベルの生成AI(RAG)を、要件定義からインフラ・運用まで一人で完遂します。

この記事で解説した技術の適用事例

木材流通DXのB2B SaaS — PostgreSQL を中核にマルチテナント・多段商流を支えたデータ基盤

ケーススタディを見る