PostgreSQLには標準で pg_dump と pg_restore というツールが付属しています。MySQLの
mysqldump に相当する論理バックアップツールですが、カスタム形式(-Fc)や並列リストア(-j)など、より柔軟な運用オプションを備えています。この記事では、pg_dump / pg_restore の実践的な使い方をRHEL 9.4 / Ubuntu 24.04 LTS(PostgreSQL 16)の実環境出力例を交えて解説します。単一DBのダンプから全DB一括バックアップ(pg_dumpall)・cronによる自動化・別サーバーへの移行・リストア失敗時の対処まで網羅します。
この記事のポイント
・pg_dump -Fc(カスタム形式)が本番運用での推奨フォーマット
・pg_restore -j N で並列リストアするとリストア時間を大幅短縮できる
・全DBを一括バックアップするにはpg_dumpallを使う
・cronで自動化する際は.pgpassファイルでパスワードを安全に管理する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
論理バックアップとは何か——pg_dumpが守れる範囲と守れない範囲
pg_dumpは 論理バックアップ ツールです。テーブル定義・データ・インデックス・シーケンスなどのDB内容をSQL文や独自形式で書き出します。物理バックアップ(ファイルシステムレベルのコピー)とは異なる特性を持ちます。論理バックアップが得意なこと:
・特定のデータベース・テーブルだけを取り出せる
・異なるPostgreSQLバージョン間での移行に使える
・異なるOS・アーキテクチャへの移行が可能
・圧縮率が高い(カスタム形式で自動圧縮)
論理バックアップの限界:
・ダンプ取得時点のスナップショットのため、その後のトランザクションは含まれない
・テラバイト級の超大規模DBではダンプ・リストアに時間がかかる
・ポイントインタイムリカバリ(PITR)はWALアーカイブと組み合わせた物理バックアップが適切
一般的なWebサービスやバッチシステムのデータベース(数GB~数十GB規模)では、pg_dumpによる論理バックアップが十分な選択肢です。
pg_dumpの基本的な使い方
1. 単一データベースをプレーンSQLでバックアップする
最もシンプルなバックアップ方法です。出力はSQL文のテキストファイルになります。# postgresユーザーに切り替えて実行 sudo -u postgres pg_dump mydb > /var/lib/pgsql/backup/mydb_20260824.sql # -f オプションで出力ファイルを指定する書き方でも同じ結果 sudo -u postgres pg_dump mydb -f /var/lib/pgsql/backup/mydb_20260824.sql
$ head -16 /var/lib/pgsql/backup/mydb_20260824.sql -- -- PostgreSQL database dump -- -- Dumped from database version 16.3 -- Dumped by pg_dump version 16.3 SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET xmloption = content; SET client_min_messages = warning; SET row_security = off;
2. カスタム形式(-Fc)でバックアップする(推奨)
本番環境では カスタム形式(-Fc) を使うことを強く推奨します。理由は以下の3つです。・自動圧縮でファイルサイズがプレーンSQLの約30~50%に抑えられる
・pg_restoreで特定のテーブルだけを選択してリストアできる
・並列リストア(-j N)が使えて大規模DBでも短時間で復元できる
# カスタム形式でダンプ(拡張子は .dump が慣例) sudo -u postgres pg_dump -Fc mydb -f /var/lib/pgsql/backup/mydb_20260824.dump # ファイルサイズを確認(プレーンSQLより大幅に小さい) ls -lh /var/lib/pgsql/backup/mydb_20260824.dump -rw-r--r-- 1 postgres postgres 4.2M Aug 24 09:00 /var/lib/pgsql/backup/mydb_20260824.dump
・-Fc: カスタム形式(圧縮済み・pg_restore専用)
・-Fp: プレーンSQL形式(テキスト・psqlでリストア可能、デフォルト)
・-Fd: ディレクトリ形式(-j N による並列バックアップに対応)
・-t テーブル名: 特定のテーブルだけをダンプ
・-s: スキーマ(テーブル定義)のみダンプ(データなし)
・-a: データのみダンプ(スキーマなし)
・-Z 0~9: 圧縮レベル(0=無圧縮、9=最大圧縮、デフォルトは6)
特定テーブルだけをバックアップする場合:
# ordersテーブルだけをカスタム形式でダンプ sudo -u postgres pg_dump -Fc -t orders mydb -f /var/lib/pgsql/backup/mydb_orders_20260824.dump
3. 全データベースを一括バックアップする(pg_dumpall)
複数のデータベースとロール情報・テーブルスペース設定を含む全体バックアップには pg_dumpall を使います。# 全データベースとロール情報をダンプ(プレーンSQL形式のみ対応) sudo -u postgres pg_dumpall -f /var/lib/pgsql/backup/all_databases_20260824.sql # ファイルサイズを確認 ls -lh /var/lib/pgsql/backup/all_databases_20260824.sql -rw-r--r-- 1 postgres postgres 28M Aug 24 09:05 /var/lib/pgsql/backup/all_databases_20260824.sql
psql コマンドで行います。ロール情報だけを別途バックアップしたい場合:
# ロール(ユーザー・グループ)定義のみを取り出す sudo -u postgres pg_dumpall -g -f /var/lib/pgsql/backup/roles_20260824.sql
pg_restoreで復元する手順
1. カスタム形式(-Fc)のダンプを復元する
カスタム形式のダンプはpg_restore コマンドでリストアします。リストア先のデータベースをあらかじめ作成しておく必要があります。# リストア先DBを作成 sudo -u postgres createdb mydb_restore # pg_restoreでリストア(-d でリストア先DBを指定) sudo -u postgres pg_restore -d mydb_restore /var/lib/pgsql/backup/mydb_20260824.dump # 完了後にデータ件数を確認 sudo -u postgres psql -d mydb_restore -c "SELECT schemaname, tablename, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC LIMIT 5;" schemaname | tablename | n_live_tup --------------+-------------+------------ public | orders | 125847 public | users | 45231 public | products | 3812 public | categories | 148 public | sessions | 87654 (5 rows)
# -j 4 で4並列リストア(CPUコア数に合わせて調整。-Fc形式のみ対応) sudo -u postgres pg_restore -d mydb_restore -j 4 /var/lib/pgsql/backup/mydb_20260824.dump
# ordersテーブルのみをリストア(カスタム形式の利点) sudo -u postgres pg_restore -d mydb_restore -t orders /var/lib/pgsql/backup/mydb_20260824.dump
2. プレーンSQL(-Fp)ダンプを復元する
プレーンSQL形式のダンプはpg_restore ではなく psql コマンドでリストアします。# プレーンSQL形式のリストア(リストア先DBを事前に作成しておく) sudo -u postgres createdb mydb_restore sudo -u postgres psql -d mydb_restore -f /var/lib/pgsql/backup/mydb_20260824.sql # pg_dumpall の全DB一括ダンプをリストア(DB作成コマンドも含まれる) sudo -u postgres psql -f /var/lib/pgsql/backup/all_databases_20260824.sql
3. 別サーバーへデータを移行する
pg_dumpとpg_restoreはパイプで接続できるため、ダンプファイルを作成せずに旧サーバーから新サーバーへ直接転送できます。# 旧サーバーで実行: カスタム形式でダンプしてSSH経由で新サーバーへ転送 sudo -u postgres pg_dump -Fc mydb | ssh new-server "sudo -u postgres pg_restore -d mydb_new -" # または新サーバー側から旧サーバー(192.168.1.10)に接続してpg_dumpを実行 pg_dump -h 192.168.1.10 -U postgres -Fc mydb | pg_restore -d mydb_new -
cronで自動バックアップを設定する
1. .pgpassでパスワードを安全に管理する
cronでpg_dumpを自動実行する場合、パスワードをシェルスクリプト内に直接書くのは避けるべきです。PostgreSQLが提供する .pgpass ファイルを使うと、パスワードをファイルとして安全に管理できます。# postgresユーザーのホームディレクトリに .pgpass を作成 # 形式: hostname:port:database:username:password echo "localhost:5432:mydb:backup_user:バックアップ用パスワード" > /var/lib/pgsql/.pgpass chmod 600 /var/lib/pgsql/.pgpass chown postgres:postgres /var/lib/pgsql/.pgpass
2. バックアップシェルスクリプトを作成する
# /usr/local/bin/pg_backup.sh として作成 #!/bin/bash BACKUP_DIR="/var/lib/pgsql/backup" DB_NAME="mydb" DATE=$(date +%Y%m%d) BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.dump" # バックアップ取得(カスタム形式) pg_dump -U backup_user -Fc "${DB_NAME}" -f "${BACKUP_FILE}" # 7日より古いバックアップを削除(世代管理) find "${BACKUP_DIR}" -name "${DB_NAME}_*.dump" -mtime +7 -delete # バックアップサイズをログに記録 ls -lh "${BACKUP_FILE}" >> "${BACKUP_DIR}/backup.log"
# スクリプトに実行権限を付与 chmod 755 /usr/local/bin/pg_backup.sh chown postgres:postgres /usr/local/bin/pg_backup.sh # postgresユーザーのcrontabに登録(毎日02:00に実行) sudo -u postgres crontab -e # 以下の1行を追加して保存 0 2 * * * /usr/local/bin/pg_backup.sh
3. バックアップファイルの整合性を確認する
定期的にリストアテストを行うのが理想ですが、最低限ダンプファイルが破損していないかを確認できます。# カスタム形式の内容一覧を表示(エラーなく表示できれば破損なし) sudo -u postgres pg_restore -l /var/lib/pgsql/backup/mydb_20260824.dump | head -20 ; ; Archive created at 2026-08-24 02:00:15 JST ; dbname: mydb ; TOC Entries: 38 ; Compression: 6 ; Dump Version: 1.14-0 ; Format: CUSTOM ; Integer: 4 bytes ; Offset: 8 bytes ; Dumped from database version: 16.3 ; Dumped by pg_dump version: 16.3 ; ; Selected TOC Entries: ; 225; 1259 16384 TABLE public orders postgres 226; 1259 16392 TABLE public users postgres 227; 1259 16401 TABLE public products postgres 228; 1259 16410 TABLE public categories postgres 229; 1259 16419 TABLE public sessions postgres
トラブルシュートとエラー対処
1. pg_dump: error: connection to server on socket failed
原因: PostgreSQLサービスが停止しているか、実行ユーザーにソケット接続権限がない。対処:
systemctl status postgresql-16 でサービスの状態を確認し、停止していれば起動する。また、pg_dumpを実行しているユーザーが postgres ロールとして接続できるかを psql で確認する。# サービス状態の確認 systemctl status postgresql-16 # RHEL 9.4での正常な出力例 * postgresql-16.service - PostgreSQL 16 Database Server Loaded: loaded (/usr/lib/systemd/system/postgresql-16.service; enabled) Active: active (running) since Sun 2026-08-24 09:00:01 JST; 2h 5min ago # 接続確認 sudo -u postgres psql -c "\conninfo" You are connected to database "postgres" as user "postgres" via socket in "/var/run/postgresql" at port "5432".
2. pg_restore: error: could not execute query: ERROR: relation already exists
原因: リストア先のデータベースに同名のテーブルが既に存在している。対処1:
pg_restore --clean オプションを付けると、オブジェクト作成前に DROP 文を発行してくれる(最も手軽)。対処2: リストア先DBを一度削除して再作成してからリストアする(確実)。
# --clean で既存オブジェクトをDROPしてから再作成 sudo -u postgres pg_restore --clean -d mydb_restore /var/lib/pgsql/backup/mydb_20260824.dump # または リストア先DBを削除→再作成してからリストア(より確実) sudo -u postgres dropdb mydb_restore sudo -u postgres createdb mydb_restore sudo -u postgres pg_restore -d mydb_restore /var/lib/pgsql/backup/mydb_20260824.dump
3. pg_dump: error: query failed: ERROR: permission denied for table xxx
原因: バックアップに使っているユーザーが、対象テーブルへのSELECT権限を持っていない。対処:
postgres スーパーユーザーでダンプを実行するか、バックアップ専用ユーザーに必要な権限を付与する。# バックアップ専用ユーザーにSELECT権限を付与する例 sudo -u postgres psql -d mydb mydb=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO backup_user; GRANT mydb=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO backup_user; ALTER DEFAULT PRIVILEGES
4. 「No space left on device」でダンプが途中で失敗する
原因: バックアップ先ディスクの容量不足、またはinode枯渇。対処:
df -h でディスク空き容量を、df -i でinode使用率を確認する。カスタム形式(-Fc)は自動圧縮が効くためプレーンSQLより大幅にファイルサイズを削減できる。古い世代のバックアップを削除して空き容量を確保するか、バックアップ先を別ディスクに変更する。本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| 単一DBをカスタム形式でバックアップ | pg_dump -Fc mydb -f mydb.dump |
| 単一DBをプレーンSQLでバックアップ | pg_dump mydb -f mydb.sql |
| 特定テーブルだけをバックアップ | pg_dump -Fc -t テーブル名 mydb -f tbl.dump |
| 全DBを一括バックアップ | pg_dumpall -f all_db.sql |
| カスタム形式ダンプをリストア | pg_restore -d mydb mydb.dump |
| 並列リストアで高速化 | pg_restore -d mydb -j 4 mydb.dump |
| プレーンSQLダンプをリストア | psql -d mydb -f mydb.sql |
| ダンプ内容の一覧表示(破損確認) | pg_restore -l mydb.dump |
| 既存オブジェクトをDROPしてリストア | pg_restore --clean -d mydb mydb.dump |
Linux Master Pro Seminar の詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:pg_hba.confで接続認証を設計する方法|PostgreSQLに接続できない原因の切り分けとscram-sha-256設定
- この記事の属するカテゴリ:データーベース管理へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます