PostgreSQLのダンプ取得とテスト環境へのリストア作業を、毎回調べ直してしまうので、自分用の作業メモとしてまとめておきます。
本記事では、本番データをダンプして、テスト環境に反映するまでの流れを扱います。会社名・サーバー名・DB名などはすべてダミーに置き換えています。
この記事で使うダミー環境
この記事では、以下のような架空の環境を想定します。実際の会社名・サーバー名・DB名などは使わず、すべてダミーの情報で記載しています。
本番DBサーバー: prod-db.example.com
テストDBサーバー: test-db.example.com
SSH接続ユーザー: sample_user
DB名: sample_app_db
DBユーザー: postgres
ダンプファイル名: sample_app_db_20260528.dump
バックアップ用ダンプファイル名: sample_app_db_test_before_restore_20260528.dump
実際に作業するときは、自分の環境に合わせて、サーバー名・DB名・ユーザー名・ファイル名を読み替えます。
prod-db.example.com → 本番DBサーバー
test-db.example.com → テストDBサーバー
sample_user → SSH接続ユーザー
postgres → DBユーザー
sample_app_db → 対象DB名
sample_app_db_20260528.dump → 作成するダンプファイル名
sample_app_db_test_before_restore_20260528.dump → テストDBのバックアップ用ダンプファイル名
全体の流れ
作業の流れは、ざっくり以下のようになります。
1. 本番DBサーバーにSSH接続する
2. pg_dumpで本番DBのダンプを取得する
3. ダンプファイルをローカルPCにダウンロードする
4. ダンプファイルをテストDBサーバーにアップロードする
5. テストDBの現状バックアップを取る
6. pg_restoreでテストDBに反映する
7. 反映結果を確認する
PostgreSQLの場合、基本的には以下のように覚えておくと分かりやすいです。
ダンプを取得する: pg_dump
ダンプを復元する: pg_restore
つまり、「取るときは pg_dump、流すときは pg_restore 」です。
手順
本番DBサーバーにSSH接続する
まず、本番DBサーバーにSSH接続します。
書式は以下です。
ssh [SSH接続ユーザー]@[本番DBサーバー]
今回のダミー環境では、以下になります。
ssh sample_user@prod-db.example.com
以降のダンプ取得コマンドは、本番DBサーバーにログインした状態で実行します。
pg_dumpでダンプを取得する
本番DBサーバー上で、pg_dump を使ってDBのダンプファイルを作成します。
書式は以下です。
pg_dump -U [DBユーザー] -d [DB名] -Fc -f /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
pg_dump -U postgres -d sample_app_db -Fc -f /tmp/sample_app_db_20260528.dump
それぞれの意味は以下です。
pg_dump
PostgreSQLのDBをダンプするコマンド
-U [DBユーザー]
DBに接続するユーザー
-d [DB名]
ダンプ対象のDB名
-Fc
カスタム形式でダンプを作成する指定
-f /tmp/[ダンプファイル名]
出力先ファイル
今回は、ダンプファイルを一時的に /tmp 配下へ作成しています。
-Fc はカスタム形式の指定です。この形式で作っておくと、あとで pg_restore を使って復元できます。
ダンプファイルを確認する
ダンプファイルが作成されたか確認します。
書式は以下です。
ls -lh /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
ls -lh /tmp/sample_app_db_20260528.dump
以下のようにファイルサイズが表示されればOKです。
-rw-r--r-- 1 sample_user sample_user 120M May 28 10:00 /tmp/sample_app_db_20260528.dump
確認できたら、本番DBサーバーから抜けます。
exit
ローカルPCにダウンロードする
次に、本番DBサーバー上に作成したダンプファイルを、ローカルPCにダウンロードします。
このコマンドは、本番DBサーバー上ではなく、ローカルPC側で実行します。
書式は以下です。
scp [SSH接続ユーザー]@[本番DBサーバー]:/tmp/[ダンプファイル名] .
今回のダミー環境では、以下になります。
scp sample_user@prod-db.example.com:/tmp/sample_app_db_20260528.dump .
末尾の . は、「今いるディレクトリに保存する」という意味です。
ダウンロードできたか確認します。
書式は以下です。
ls -lh [ダンプファイル名]
今回のダミー環境では、以下になります。
ls -lh sample_app_db_20260528.dump
テストDBサーバーにアップロードする
ローカルPCにダウンロードしたダンプファイルを、今度はテストDBサーバーへアップロードします。
このコマンドも、ローカルPC側で実行します。
書式は以下です。
scp [ダンプファイル名] [SSH接続ユーザー]@[テストDBサーバー]:/tmp/
今回のダミー環境では、以下になります。
scp sample_app_db_20260528.dump sample_user@test-db.example.com:/tmp/
アップロード後、テストDBサーバーにSSH接続します。
書式は以下です。
ssh [SSH接続ユーザー]@[テストDBサーバー]
今回のダミー環境では、以下になります。
ssh sample_user@test-db.example.com
テストDBサーバー上で、ファイルが存在するか確認します。
書式は以下です。
ls -lh /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
ls -lh /tmp/sample_app_db_20260528.dump
テストDBのバックアップを取る
テストDBに本番ダンプを流す前に、念のため現在のテストDBのバックアップを取っておきます。
書式は以下です。
pg_dump -U [DBユーザー] -d [DB名] -Fc -f /tmp/[バックアップ用ダンプファイル名]
今回のダミー環境では、以下になります。
pg_dump -U postgres -d sample_app_db -Fc -f /tmp/sample_app_db_test_before_restore_20260528.dump
確認します。
書式は以下です。
ls -lh /tmp/[バックアップ用ダンプファイル名]
今回のダミー環境では、以下になります。
ls -lh /tmp/sample_app_db_test_before_restore_20260528.dump
これは保険です。リストアに失敗した場合や、作業前のテスト環境に戻したい場合に使えます。
pg_restoreでテストDBに反映する
いよいよ、ダンプファイルをテストDBに反映します。
反映先のDBがすでに存在している場合は、以下のように実行します。
書式は以下です。
pg_restore -U [DBユーザー] -d [DB名] --clean --if-exists /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
pg_restore -U postgres -d sample_app_db --clean --if-exists /tmp/sample_app_db_20260528.dump
それぞれの意味は以下です。
pg_restore
PostgreSQLのダンプを復元するコマンド
-U [DBユーザー]
DBに接続するユーザー
-d [DB名]
反映先のDB名
--clean
既存のDBオブジェクトを削除してから復元する
--if-exists
削除対象が存在する場合だけ削除する
/tmp/[ダンプファイル名]
復元に使うダンプファイル
--clean を付けると、既存のテーブルなどを削除してから復元します。そのため、実行先が本当にテスト環境かどうかを必ず確認します。
本番環境で誤って実行すると危険なので、DB作業では「今どのサーバーにいるか」を毎回確認した方が安全です。
反映先のDBが存在しない場合
反映先のDBがまだ存在しない場合、pg_restore の前にDBを作成します。
書式は以下です。
createdb -U [DBユーザー] -T template0 [DB名]
今回のダミー環境では、以下になります。
createdb -U postgres -T template0 sample_app_db
DBを作成したあと、改めて pg_restore を実行します。
書式は以下です。
pg_restore -U [DBユーザー] -d [DB名] --clean --if-exists /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
pg_restore -U postgres -d sample_app_db --clean --if-exists /tmp/sample_app_db_20260528.dump
つまり、DBが無い場合の流れは以下です。
書式は以下です。
createdb -U [DBユーザー] -T template0 [DB名]
pg_restore -U [DBユーザー] -d [DB名] --clean --if-exists /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
createdb -U postgres -T template0 sample_app_db
pg_restore -U postgres -d sample_app_db --clean --if-exists /tmp/sample_app_db_20260528.dump
pg_restore は、基本的に「既に存在するDBの中に復元する」コマンドとして使います。そのため、DB自体が無い場合は、先に createdb で空のDBを用意しておきます。
反映結果を確認する
リストアが終わったら、テストDBに接続して確認します。
書式は以下です。
psql -U [DBユーザー] -d [DB名]
今回のダミー環境では、以下になります。
psql -U postgres -d sample_app_db
テーブル一覧を確認します。
\dt
適当なテーブルの件数も確認します。ここでは例として、ダミーの users テーブルを確認します。
書式は以下です。
SELECT COUNT(*) FROM [確認用テーブル名];
今回のダミー環境では、以下になります。
SELECT COUNT(*) FROM users;
確認が終わったら、psqlから抜けます。
\q
よく使うオプションの意味
今回使ったコマンドの中で、よく出てくるオプションを整理しておきます。
pg_dumpで使ったオプション
書式は以下です。
pg_dump -U [DBユーザー] -d [DB名] -Fc -f /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
pg_dump -U postgres -d sample_app_db -Fc -f /tmp/sample_app_db_20260528.dump
-U [DBユーザー]
DBに接続するユーザーを指定します。
-d [DB名]
ダンプを取得するDB名を指定します。
-Fc
カスタム形式でダンプを取得します。
この形式で取得した場合、復元には pg_restore を使います。
-f /tmp/[ダンプファイル名]
ダンプファイルの出力先を指定します。
pg_restoreで使ったオプション
書式は以下です。
pg_restore -U [DBユーザー] -d [DB名] --clean --if-exists /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
pg_restore -U postgres -d sample_app_db --clean --if-exists /tmp/sample_app_db_20260528.dump
-U [DBユーザー]
DBに接続するユーザーを指定します。
-d [DB名]
復元先のDB名を指定します。
--clean
既存のテーブルなどを削除してから復元します。
--if-exists
削除対象が存在する場合だけ削除します。
存在しないオブジェクトを削除しようとしてエラーになるのを防ぎやすくなります。
特に注意したいのは --clean です。既存のテーブルなどを削除してから復元するため、実行先を間違えると危険です。
実行前には、必ず「今どのサーバーにいるか」「どのDBに対して実行しているか」を確認します。
うまくいかないとき
作業中によくありそうなエラーや確認ポイントをまとめます。
DBが存在しないと言われる場合
以下のようなエラーが出る場合、復元先のDBがまだ存在していない可能性があります。
database "sample_app_db" does not exist
その場合は、先にDBを作成します。
書式は以下です。
createdb -U [DBユーザー] -T template0 [DB名]
今回のダミー環境では、以下になります。
createdb -U postgres -T template0 sample_app_db
その後、もう一度 pg_restore を実行します。
書式は以下です。
pg_restore -U [DBユーザー] -d [DB名] --clean --if-exists /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
pg_restore -U postgres -d sample_app_db --clean --if-exists /tmp/sample_app_db_20260528.dump
権限エラーが出る場合
DBユーザーに権限がない場合、復元時にエラーになることがあります。
permission denied
must be owner of table sample_table
この場合は、以下を確認します。
接続しているDBユーザーは正しいか
復元先DBの所有者は正しいか
テーブルやスキーマの権限に問題がないか
postgresユーザーで実行する必要があるか
テスト環境であれば、DBの所有者や実行ユーザーを確認してから、再実行します。
ダンプファイルが見つからない場合
以下のようなエラーが出る場合、指定したパスにダンプファイルが存在していない可能性があります。
No such file or directory
まずはファイルが存在するか確認します。
書式は以下です。
ls -lh /tmp/[ダンプファイル名]
今回のダミー環境では、以下になります。
ls -lh /tmp/sample_app_db_20260528.dump
ローカルPCからテストDBサーバーへアップロードできているかも確認します。
書式は以下です。
scp [ダンプファイル名] [SSH接続ユーザー]@[テストDBサーバー]:/tmp/
今回のダミー環境では、以下になります。
scp sample_app_db_20260528.dump sample_user@test-db.example.com:/tmp/
psqlに入れるか確認する
復元前に、そもそも対象DBへ接続できるか確認しておくと安心です。
書式は以下です。
psql -U [DBユーザー] -d [DB名]
今回のダミー環境では、以下になります。
psql -U postgres -d sample_app_db
接続できたら、以下で抜けます。
\q
まとめ
PostgreSQLのダンプ取得とテスト環境への反映は、流れだけ見るとシンプルです。
pg_dumpでダンプを取得する
scpでダンプファイルを移動する
createdbで必要ならDBを作成する
pg_restoreでテストDBに反映する
psqlで反映結果を確認する
特に覚えておきたいのは、以下の2つです。
ダンプを取得する: pg_dump
ダンプを復元する: pg_restore
ただし、DB作業は影響が大きいので、実行前には必ず以下を確認します。
今どのサーバーにいるか
対象DB名は正しいか
本番環境ではなくテスト環境か
反映前のバックアップを取ったか
コマンドに実環境の情報が残っていないか
毎回調べ直していた作業でも、一度手順としてまとめておくと、次回からかなり楽になります。DB作業は、慣れより確認を大事にしたいところです。