---
title: "PostgreSQLのバックアップ設計｜pg_dumpとPITRの使い分け・復旧検証の手順"
url: "https://www.issoh.co.jp/tech/details/16996/"
published: 2026-08-26
updated: 2026-08-26
categories: ["データベース"]
publisher: "株式会社一創"
---

# PostgreSQLのバックアップ設計｜pg\_dumpとPITRの使い分け・復旧検証の手順

毎晩pg\_dumpを回しているのに、いざ障害が起きると「どこまで戻せるのか」が誰にも答えられない。ダンプファイルは残っているが復元を試したことがない。この二つは別々の失敗に見えて、原因は同じところにあります。取得方法だけを決めて、復旧目標と検証手順を決めていないからです。

この記事は、PostgreSQLのバックアップを取得コマンドの羅列ではなく、復旧できる状態を作る設計として扱う解説です。論理バックアップの形式選択、WALアーカイブによる任意時点への復旧、17系以降の増分バックアップ、そして目標値から方式を決める判断基準までを実行できるコマンド付きで並べます。フル・差分・増分といった方式そのものの一般的な整理は[システムバックアップとは？種類（フル・差分・増分）と方式の選び方](https://www.issoh.co.jp/column/details/13448/)に譲り、ここはPostgreSQL固有の実装だけを扱います。データベース全般の位置づけは[データベースとは？種類・DBMS・RDBとNoSQLの選び方](https://www.issoh.co.jp/tech/details/13012/)を参照してください。数値の前提は18系（2026年8月時点で18.6が最新マイナー）としました。

## まとめ：バックアップ方式を決める前に固める5点

結論を5点で先に置きます。第一に、pg\_dumpは論理バックアップで、取得した瞬間の一貫した断面しか残りません。任意の時点へ戻す要求があるなら、pg\_dumpをいくら細かく回しても要件を満たせないので、最初にここで分岐します。

第二に、pg\_dumpallは18でも平文SQLしか出力しません。形式を選ぶ指定そのものが存在せず、復元はpsqlに限られます。クラスタ全体を圧縮形式で一括保存する方法はないため、ロールとテーブルスペースだけをpg\_dumpallで抜き、データベース本体は個別にpg\_dumpで取る二段構えが実務的な解になります。

第三に、任意時点への復旧はpg\_basebackupで取ったベースバックアップと、継続的に退避したWALの両方が揃って初めて成立します。片方だけでは戻せません。設定は`wal_level`、`archive_mode`、`archive_command`、そして復旧側の`restore_command`の4点が骨格です。

第四に、17系以降の増分バックアップは`summarize_wal`を有効にする必要があり、既定は無効で反映にはサーバの再起動が要ります。しかも取得した増分は単体では起動できず、pg\_combinebackupで元のバックアップと合成する工程を挟みます。

第五に、18でpg\_dumpに統計情報を含める指定が加わりました。既定では含まれないままなので、リストア直後に実行計画が崩れる定番の事故を避けたいなら明示的に指定します。以下、順に根拠を見ていきます。

## pg\_dumpとpg\_dumpallの形式選択と復元コマンドの対応

論理バックアップはSQL文やアーカイブとしてデータを書き出す方式です。公式文書はpg\_dumpについて、同時利用中でも一貫した出力を作り、読み手にも書き手にもロックをかけないと明記しています。稼働中に取れることが前提の道具だと理解しておいてください。

### plain・custom・directory・tarの4形式と使い分けの基準

pg\_dumpの出力形式は4種類あり、選んだ形式で復元コマンドが変わります。平文だけがpsqlで戻す形式で、残りはpg\_restoreを通します。

| 形式     | 指定   | 復元          | 向く場面      |
| ------ | ---- | ----------- | --------- |
| 平文SQL  | \-Fp | psql        | 差分確認・小規模  |
| カスタム   | \-Fc | pg\_restore | 既定の選択肢    |
| ディレクトリ | \-Fd | pg\_restore | 並列取得が要る場合 |
| tar    | \-Ft | pg\_restore | 圧縮不可・順序固定 |

迷ったらカスタム形式を選んでください。既定で圧縮がかかり、復元時に対象を選んだり順序を組み替えたりできます。並列で取りたい場合だけディレクトリ形式にします。並列取得の指定が使えるのはディレクトリ形式だけで、他の形式に付けても働きません。

```
pg_dump -Fc -Z 6 -f appdb.dump appdb
pg_dump -Fd -j 4 -f appdb_dir appdb
pg_restore -d appdb_new -j 4 appdb.dump
```

並列指定は接続数を消費します。指定した数に1を足した本数の接続が開くため、`max_connections`に余裕がない本番環境でそのまま流すと、アプリ側の接続が弾かれます。夜間帯であっても接続上限は先に確認しておきましょう。

### pg\_dumpallが平文SQLしか出せない前提での二段構え

クラスタ全体を対象にするpg\_dumpallには、形式を指定するオプションがありません。18の文書でも出力はpsqlへの入力として使うSQLスクリプトと説明されており、pg\_restoreは受け付けません。数百ギガのクラスタを平文一本で扱うのは現実的ではないため、役割を分けます。

```
pg_dumpall -g > globals.sql
pg_dump -Fc -f appdb.dump appdb
pg_dump -Fc -f logdb.dump logdb
```

グローバルオブジェクトの指定はロールとテーブルスペースだけを抜き、データベースの中身は含みません。テーブルスペースが不要ならロールのみに絞る指定もあります。ここで抜けるのは[PostgreSQLのロールと権限設計｜CREATE ROLEの属性とGRANT・既定権限の決め方](https://www.issoh.co.jp/tech/details/16984/)で扱った属性や所属関係で、復元時はこのSQLを先に流してからデータベース本体を戻す順序になります。

### 18で増えた統計情報のダンプ指定とリストア直後の性能低下対策

移行やリストアの直後だけクエリが極端に遅い、という現象の多くは統計情報が空だからです。18ではpg\_dumpに統計情報を含める指定が加わりました。ただし既定は含めない側で、文書にも既定はダンプしない旨が明記されています。

```
pg_dump -Fc --statistics -f appdb.dump appdb
pg_dump --statistics-only -f stats.sql appdb
```

統計だけを別途書き出す指定もあるため、データ移送は従来どおり行い、統計はあとから流し込む運用も組めます。18ではこのほかに、スキーマだけ・データだけを外す指定や、行レベルセキュリティのポリシーを外す指定も追加されました。検証環境へ本番の構造だけを持っていく作業が、オプション1つで済むようになっています。統計を持ち込まない場合は、復元後にANALYZEを流してから利用者を戻してください。統計の劣化そのものへの対処は[PostgreSQLのVACUUM運用｜autovacuumのしきい値設計とXID周回・肥大の切り分け](https://www.issoh.co.jp/tech/details/16982/)で扱っています。

## pg\_basebackupとWALアーカイブでPITRを組む手順

任意の時点へ戻す仕組みは、クラスタ全体の物理コピーと、その後の更新履歴であるWALの組み合わせで作ります。論理バックアップとは別系統の道具立てで、片方の代わりにはなりません。

### 継続アーカイブを有効にする4つの設定とアーカイブ先の置き場所

まず送り出し側を設定します。`wal_level`はreplica以上、`archive_mode`はon、そして退避方法を`archive_command`か`archive_library`のどちらかで指定します。前者はシェルコマンド、後者はC言語で書かれたモジュールを呼ぶ方式です。

```
wal_level = replica
archive_mode = on
archive_command = 'test ! -f /mnt/backup/wal/%f && cp %p /mnt/backup/wal/%f'
archive_timeout = 300
```

コマンド内の記号は仕様に沿って置き換え可能です。パス全体が入る指定と、ファイル名だけが入る指定の2つがあり、公式の例でも同名ファイルの上書きを防ぐ検査を先に置いています。ここを省くと、タイムライン分岐後に同じ名前のWALが来たとき前の内容を壊します。

更新の少ないシステムでは、WALが埋まるまで退避が起きません。時間指定を入れておけば、その間隔で強制的に切り替わるため、目標復旧時点の粒度を時間で保証できます。退避先は本体と同じディスクに置かないでください。同じ筐体が壊れたときに両方失う構成では、そもそも目的を果たしません。退避先の保護については[PostgreSQLの暗号化｜TLS設定・pgcryptoの列暗号化とTDE不在時の選び方](https://www.issoh.co.jp/tech/details/16986/)を参照してください。

### 復旧時に置くsignalファイルとrecovery\_targetの指定

ベースバックアップの取得はpg\_basebackupで行います。WALの同時取り込みを指定すれば、アーカイブを参照しなくても単体で起動できる状態になります。

```
pg_basebackup -D /mnt/backup/base_20260826 -Ft -z -Xs -P
```

WALの取り込み方法は3種類です。既定はストリーム方式で、バックアップと並行して別接続でWALを受け取ります。取得完了後にまとめて受け取る方式もありますが、その間にWALが再利用されると失敗するため、保持量の設定を上げておく必要があります。

復旧するときは、ベースバックアップを展開したうえで復旧用の設定を書き、データディレクトリに合図となるファイルを置きます。読み取り専用の待機系として起動する場合は別のファイル名になるので、取り違えないでください。

```
restore_command = 'cp /mnt/backup/wal/%f %p'
recovery_target_time = '2026-08-26 09:15:00+09'
recovery_target_action = 'promote'
```

停止位置は時刻のほかに、名前付きの復旧地点、トランザクションID、ログの位置でも指定できます。誤ってテーブルを消した事故なら、その直前の時刻を指定するのが定石です。復旧を始めるにはデータディレクトリにrecovery.signalを作成します。待機系として起動するときはstandby.signalを使います。

### 17系以降の増分バックアップとpg\_combinebackupの必須手順

17系からpg\_basebackupに増分の指定が入りました。前回のバックアップに付いてきたマニフェストファイルを渡すと、差分だけを受け取れます。ただし前提が2つあります。

ひとつはサーバ側の設定です。WALの要約処理を担うプロセスは既定で止まっており、`summarize_wal`を有効にしてサーバを再起動しないと増分取得そのものが成立しません。`wal_level`がminimalのままでは起動できない制約も付きます。もうひとつはサーバのバージョンで、増分の指定は17以降にしか効きません。

```
pg_basebackup -D /mnt/backup/full -Xs
pg_basebackup -D /mnt/backup/incr1 -Xs -i /mnt/backup/full/backup_manifest
pg_combinebackup /mnt/backup/full /mnt/backup/incr1 -o /var/lib/pgsql/18/data
```

増分バックアップは単体では使えません。公式文書も、pg\_combinebackupで依存元のバックアップと合成してからでないと使えないと明記しています。ここを知らずに増分だけを遠隔地へ送っている構成は、災害時に何も戻せない状態です。合成の入力には連鎖する全世代が要るため、途中の1世代が欠けた時点でその後の増分はすべて無価値になります。世代数を増やすほど合成時間も伸びるので、週次でフルを取り直す設計が扱いやすいでしょう。

## RPOとRTOの目標値からバックアップ方式を決める実務の判断基準

方式選定は好みではなく、許容できるデータ損失量と復旧までの時間で決まります。この2つの指標そのものの定義は[リカバリーとは？意味・リストア/バックアップとの違いと企業の実務判断](https://www.issoh.co.jp/column/details/13354/)で扱っているので、ここでは数値から方式へ落とす部分だけを書きます。

### 論理バックアップだけで足りる場面と物理構成が要る場面の線引き

判断は単純です。損失許容が1日単位なら夜間のpg\_dumpで足ります。1時間を切る要求が出た瞬間に、WALアーカイブが必須になります。

| 損失許容 | 復旧時間  | 採る方式       |
| ---- | ----- | ---------- |
| 1日   | 数時間可  | 夜間pg\_dump |
| 数時間  | 1時間以内 | 基本＋WAL退避   |
| 5分以内 | 10分以内 | 退避＋待機系     |
| ほぼ0  | 数分    | 同期レプリカ併用   |

表の下2段はバックアップの話を超えて可用性設計の領域に入ります。待機系を持つ構成でも、論理バックアップは別途必要です。誤ったUPDATEはレプリカにも伝わるため、人的ミスからの復旧手段としては物理複製が役に立ちません。この点を混同した設計を実際によく見かけます。

### RPOを分単位まで詰めるときに追加で必要になる設定と運用費用

分単位を狙うなら、WALの強制切り替え間隔を短くし、退避先を別拠点に置きます。退避が滞ったときの検知も要ります。アーカイブが失敗し続けると、サーバはWALを削除できず領域を食い潰してやがて停止するからです。監視対象に退避の成否と滞留数を必ず入れてください。

費用の面では、退避先の容量が更新量に比例して増加する構造です。更新の多い業務システムでは、日次のフルバックアップ容量よりWALの総量が上回る場面もあります。保持期間を決めずに始めると、半年後に保管費用の話が持ち上がります。世代の削除規則を最初に決めておきましょう。

### マネージドサービスへ寄せたときに残る自前の作業と責任の分界点

クラウドのマネージドサービスを使うなら、退避の仕組み自体は用意されています。[Amazon RDS for PostgreSQLとは？マルチAZ構成・拡張機能の統制と延長サポート課金・DMS移行を実装目線で解説](https://www.issoh.co.jp/tech/details/16972/)で扱った自動バックアップや、[Aurora PostgreSQLとは？対応バージョン・拡張機能とBabelfish・RDSからの移行判断を実装者目線で解説](https://www.issoh.co.jp/tech/details/16970/)の継続的な保護がそれにあたります。

ただし残る作業があります。保持期間の設定、リージョンをまたぐ複製の有無、そして論理バックアップの取得です。マネージド側の仕組みは同一アカウント内の障害には強い一方、アカウント自体を失う事故や、他クラウドへ持ち出す要求には応えられません。四半期に一度は自分の手元にpg\_dumpを落としておく運用を勧めます。

## リストア手順を定期検証して復旧できる状態を保つ運用の組み立て方

バックアップは取得した時点では何も保証していません。戻せることを確かめて初めて資産になります。ここを運用に組み込めているかどうかが、事故のときの差になります。

### 復旧訓練で必ず測る3つの数字とバックアップ台帳に残す確認項目

訓練で測るのは3つです。ひとつめは展開から起動までにかかった実時間で、これが目標復旧時間に収まっているかが確認対象です。ふたつめは復旧できた最終更新時刻で、目標との差が実際の損失量になります。みっつめは復旧後の件数照合で、主要テーブルの行数とチェックサムを取得時と突き合わせます。

記録に残す項目は、実施日、対象世代、所要時間、戻せた時点、照合結果、詰まった箇所の6つで足ります。詰まった箇所の記録がいちばん価値を持ちます。二回目の訓練で同じ場所に引っかかるなら、手順書ではなく構成のほうに問題があると判断してください。

### バージョン互換で詰まる場面とpg\_restoreの実行順序の注意

復旧時に慌てて気づくのがバージョンの向きです。pg\_dumpは自分より古いサーバからは取得でき、出力は自分より新しいサーバへ読み込める前提で作られています。逆向きは通りません。自分より新しいメジャーバージョンのサーバからは、無効なダンプを作る危険を避けるため取得を拒否します。移行作業では新しい側のpg\_dumpを使うのが原則です。

物理バックアップはさらに厳格で、メジャーバージョンをまたいだ復元ができません。18のデータディレクトリを17のサーバで起動することも、その逆もできない仕組みです。手元の作業機に入れたクライアントの版が古いまま作業して失敗する例が多いので、[PostgreSQLのインストール手順｜Windows・Ubuntu別の導入とinitdbで決まる文字コード](https://www.issoh.co.jp/tech/details/16963/)の手順で版を揃えてから臨んでください。復元の順序は、グローバルオブジェクト、データベース作成、本体の順です。

### バックアップ運用を内製で持つ範囲と外部へ委託する範囲の決め方

取得の自動化と監視までは内製で持てます。スクリプトは短く、失敗検知も監視基盤に載せるだけだからです。取得状況を担当者以外にも確認させるなら、読み取り専用ロールで参照口だけを開ける手もあります。手順は[PostgreSQL MCPサーバーの構成と権限設計](https://www.issoh.co.jp/tech/details/17002/)にまとめました。判断が分かれるのは復旧訓練と、方式そのものの見直しでしょう。年に数回しか実施しない作業に社内の練度は溜まりにくく、担当者が変わると手順書だけが残ります。

訓練の設計と立ち会い、そして更新量の増加に合わせた方式の再検討は、外部に置いたほうが結果的に安く付く領域です。開発を委託した相手がそのまま保守も見る体制なら、スキーマ変更のたびに復旧手順を追随させられます。この範囲の請け方は[保守運用 / 内製化支援](https://www.issoh.co.jp/service/system/maintenance/)にまとめています。内製で完結させたい場合も、初回の設計と一度目の訓練だけ伴走してもらい、二度目から自走する進め方が現実的です。

## よくある質問

### pg\_dumpは本番稼働中に実行しても大丈夫ですか？

読み書きをロックしないため、稼働中の実行は想定された使い方です。ただし取得中は長時間のトランザクションが開いたままになり、その間に不要になった行を自動清掃の仕組みが回収できません。大きなデータベースで日中に流すと、肥大化の原因になります。負荷の低い時間帯に寄せ、並列指定を使うなら接続上限を先に確認してください。

### pg\_dumpだけでPITRの代わりになりませんか？

なりません。pg\_dumpが残すのは取得を開始した時点の一貫した断面だけで、その後の更新履歴を持たないためです。1時間おきに取れば損失は最大1時間になりますが、任意の時刻を指定して戻すことはできません。時刻指定が要件なら、ベースバックアップとWALアーカイブの組み合わせを選んでください。

### 増分バックアップを取れば容量を減らせますか？

取得ごとの容量は減りますが、保管総量はそれほど減りません。復元には連鎖する全世代が要り、途中の1世代でも失うとその後が使えなくなるからです。加えて合成の工程が入るぶん復旧時間は伸びます。復旧時間の目標が厳しい場合は、増分の世代数を絞ってフルの頻度を上げる設計にしてください。

### WALアーカイブの保持期間はどれくらいにすべきですか？

最も古いベースバックアップの取得時点より前のWALは、そのバックアップから復旧する用途では使いません。逆に言えば、保持しているベースバックアップのうち最も古いものの時点以降は、すべて残す必要があります。ベースを週次で取るなら、WALは最低でも2週間分を持たせる設計が扱いやすいでしょう。

### 復元したデータベースが取得元より遅いのはなぜですか？

統計情報が引き継がれていない可能性が高いです。18でpg\_dumpに統計を含める指定が入りましたが、既定では含まれません。復元直後にANALYZEを流し、実行計画が想定どおりか確かめてください。それでも遅い場合は、共有バッファなどサーバ側の設定が移行先で既定値に戻っていないかを見てください。

## 関連記事

- [システムバックアップとは？種類（フル・差分・増分）と方式の選び方を発注者視点で解説](https://www.issoh.co.jp/column/details/13448/)（方式そのものの一般的な整理）
- [リカバリーとは？意味・リストア/バックアップとの違いと企業の実務判断](https://www.issoh.co.jp/column/details/13354/)（RPOとRTOの考え方）
- [PostgreSQLのVACUUM運用｜autovacuumのしきい値設計とXID周回・肥大の切り分け](https://www.issoh.co.jp/tech/details/16982/)（長時間トランザクションの影響）
- [PostgreSQLの暗号化｜TLS設定・pgcryptoの列暗号化とTDE不在時の選び方](https://www.issoh.co.jp/tech/details/16986/)（退避先の保護）
- [Amazon RDS for PostgreSQLとは？マルチAZ構成・拡張機能の統制と延長サポート課金・DMS移行を実装目線で解説](https://www.issoh.co.jp/tech/details/16972/)（マネージド側の仕組み）

---

出典: [PostgreSQLのバックアップ設計｜pg\_dumpとPITRの使い分け・復旧検証の手順](<https://www.issoh.co.jp/tech/details/16996/>)（株式会社一創）
