【PostgreSQL】pg_dumpでバックアップ・リストアする方法をコマンド付きで解説

PostgreSQL

こんにちは、かつコーチです。

「本番データベースのバックアップ、実はコマンド1つも覚えていない」という方は意外と多いのではないでしょうか。

バックアップ(データベースの内容を別の場所に複製しておくこと)は、障害やオペレーションミスからデータを守る最後の砦です。

この記事では、PostgreSQLの標準ツールであるpg_dumppg_restoreを使ったバックアップとリストアの手順を、実際に使うコマンド付きで解説します。

環境構築・SQL基礎編は既読の前提で、運用寄りの内容に絞って進めます。

pg_dumpの基本

pg_dumpとは何か

pg_dumpは、PostgreSQLに標準で付属する論理バックアップ(テーブル定義やデータをSQL文やアーカイブ形式で書き出す方式)のツールです。

対になるpg_dumpallはサーバー全体(複数のデータベース・ロール情報など)をまとめてバックアップするツールで、pg_dumpは指定した1つのデータベース単位でバックアップを取ります。

# 最もシンプルな使い方:SQL形式でテキスト出力
pg_dump -U postgres -d app_production > backup_20260902.sql

このコマンドは、app_productionデータベースの構造とデータをすべてSQL文として書き出します。

出力フォーマットの選び方

pg_dumpには複数の出力フォーマットがあり、用途によって使い分けます。

フォーマットオプション特徴
plain(SQL)-F p(デフォルト)テキストのSQL文。中身が見やすく、psqlでそのまま流し込める
custom-F c圧縮された独自バイナリ形式。pg_restoreが必須。並列リストア・部分リストアが可能
directory-F dディレクトリ形式。並列バックアップ(-jオプション)が可能で大規模DB向き
tar-F ttarアーカイブ形式。custom形式に近いが柔軟性はやや劣る

「中身を確認しやすいバックアップが欲しい」ならplain形式、「大規模DBを効率よくバックアップ・リストアしたい」ならcustom形式かdirectory形式を選ぶのが実践的な判断軸です。

# custom形式でバックアップ(実務で最もよく使う組み合わせ)
pg_dump -U postgres -d app_production -F c -f backup_20260902.dump

特定のテーブルだけをバックアップする

障害調査やデータ移行で、特定テーブルだけ欲しいケースもあります。

# ordersテーブルとその関連テーブルだけをバックアップ
pg_dump -U postgres -d app_production -F c \
  -t orders -t order_items \
  -f orders_only_20260902.dump

-tオプションを複数指定すれば、対象テーブルを絞り込めます。

pg_restoreでリストアする

custom形式からのリストア手順

custom形式・directory形式でバックアップした場合は、pg_restoreコマンドを使ってリストアします。

# 事前に空のデータベースを作成しておく
createdb -U postgres app_production_restored

# custom形式のバックアップをリストア
pg_restore -U postgres -d app_production_restored backup_20260902.dump

plain形式(SQLテキスト)の場合は、pg_restoreではなくpsqlコマンドで流し込みます。

# plain形式(.sql)は psql で実行する
psql -U postgres -d app_production_restored -f backup_20260902.sql

並列リストアで時間を短縮する

大規模データベースのリストアは時間がかかりますが、custom形式・directory形式であれば並列実行が可能です。

# -j オプションで並列度を指定(CPUコア数を目安にする)
pg_restore -U postgres -d app_production_restored -j 4 backup_20260902.dump

筆者が数十GB規模のデータベースをリストアした際、-jオプションなしでは1時間近くかかっていた処理が、-j 4を指定することで20分弱まで短縮できました。

サーバーのCPUコア数・ディスクI/Oに余裕がある場合は、積極的に並列度を上げるのがおすすめです。

つまずきやすいポイント・トラブル対処

❌Before:権限不足でリストアが途中失敗する

リストア対象のデータベースに、バックアップ元と異なるロールでログインしていると、こういうエラーに遭遇します。

pg_restore: error: could not execute query: ERROR:  permission denied for schema public
Command was: CREATE TABLE orders (

これは、リストア先のロールに、対象スキーマへのオブジェクト作成権限がないために起こるエラーです。

✅After:–no-ownerオプションと権限設定を組み合わせる

権限が異なる環境にリストアする場合は、所有者情報を無視する--no-ownerオプションを付けます。

# 所有者(OWNER TO)の指定を無視してリストアする
pg_restore -U postgres -d app_production_restored --no-owner backup_20260902.dump

そのうえで、リストア先のロールに必要な権限(CREATE権限など)を事前に付与しておくと、権限エラーを回避できます。

権限管理そのものの詳しい設定方法は、次回の記事(ロールベースの権限管理)で扱います。

❌Before:バックアップを取ったつもりが空ファイルだった

「毎日cronでバックアップを回しているから安心」と思っていたら、実はディスク容量不足でバックアップファイルが0バイトだった、という事故もよくあります。

# ディスクフルの状態で実行すると、エラーが出力されずに不完全なファイルが残ることがある
pg_dump -U postgres -d app_production -F c -f backup.dump
# no space left on device のエラーがログに出ているのに気づかず放置していた

筆者もクライアント案件で、cronのログを誰も見ておらず、3週間分のバックアップがすべて破損していたことに気づいて青ざめた経験があります。

✅After:バックアップ後に検証コマンドを必ず実行する

バックアップを取って終わりにせず、取得したバックアップが正しく復元できるかを必ず検証する運用にします。

# custom形式のバックアップ内容をリストアせずに検証する
pg_restore --list backup_20260902.dump > /dev/null && echo "OK: backup is valid"

このコマンドは、実際にリストアを行わずにアーカイブの整合性だけをチェックできるため、日次バックアップの直後に組み込んでおくと安全です。

さらに、月1回など定期的に別環境へ実際にリストアしてみる「リストアテスト」まで実施できると理想的です。

応用:バックアップの自動化とローテーション

cronで日次バックアップを自動化する

実運用では、cronでバックアップを自動化し、一定期間分を保持するのが基本です。

#!/bin/bash
# backup_daily.sh
DATE=$(date +%Y%m%d)
BACKUP_DIR=/var/backups/postgresql

pg_dump -U postgres -d app_production -F c -f "${BACKUP_DIR}/backup_${DATE}.dump"

# 検証
pg_restore --list "${BACKUP_DIR}/backup_${DATE}.dump" > /dev/null || echo "WARNING: backup validation failed" | mail -s "Backup Alert" admin@example.com

# 30日より古いバックアップを削除
find "${BACKUP_DIR}" -name "backup_*.dump" -mtime +30 -delete
# crontab -e で毎日深夜3時に実行
0 3 * * * /path/to/backup_daily.sh

論理バックアップと物理バックアップの使い分け

pg_dumpは論理バックアップのため、データ量が大きくなるとバックアップ・リストアの両方に時間がかかるという弱点があります。

大規模データベースや、直近の任意の時点まで復元したい(ポイントインタイムリカバリ)要件がある場合は、WAL(Write-Ahead Log)を使った物理バックアップの併用を検討します。

物理バックアップの詳細は運用がより高度になるため、本連載では扱いきれませんが、pg_basebackupというコマンドが標準で用意されている、という点だけ覚えておいてください。

まとめ

この記事のポイント

  • pg_dumpはPostgreSQL標準の論理バックアップツールで、custom形式(-F c)が実務で使いやすい
  • リストアはcustom形式ならpg_restore、plain形式ならpsqlを使う
  • 大規模データベースは-jオプションで並列リストアすると時間を大幅に短縮できる
  • バックアップは取得するだけでなく、pg_restore --listでの検証や定期的なリストアテストまで含めて運用する

次に読むべき記事

  • VACUUMとオートバキュームの仕組み
  • ロールベースの権限管理(CREATE ROLE)
  • よくあるPostgreSQLエラーまとめ

タグ: PostgreSQL, 中級者向け, バックアップ

タイトルとURLをコピーしました