ライブデータベースのコピーを作成する基本的なスクリプト/コマンドを探しています(同じサーバー上でmydb
との名前を付けてください)。mydb_test
要件
mydb_test
がすでに存在し、レコードがある場合でも実行する必要があります- 既存の接続があっても機能する必要が
mydb
ありますmydb_test
- 必要に応じて、潜在的に存在するデータベースを消去する必要があります
ヒント:
drop database
既存の接続がある場合は使用できません
ライブデータベースのコピーを作成する基本的なスクリプト/コマンドを探しています(同じサーバー上でmydb
との名前を付けてください)。mydb_test
要件
mydb_test
がすでに存在し、レコードがある場合でも実行する必要がありますmydb
ありますmydb_test
ヒント:
drop database
既存の接続がある場合は使用できません既存の (ライブ) データベースの完全なコピーを作成する最も簡単で最速の方法は、次のように使用CREATE DATABASE
することTEMPLATE
です。
CREATE DATABASE mydb_test TEMPLATE mydb;
ただし、2 番目の要件に違反する重要な制限があります。テンプレート (ソース) データベースに追加の接続を設定することはできません。マニュアルを引用します:
追加のテンプレート データベースを作成することは可能であり、実際には、その名前を のテンプレートとして指定することで、クラスター内の任意のデータベースをコピーできます
CREATE DATABASE
。ただし、これは (まだ) 汎用的な機能として意図されたものではないことを理解することが重要COPY DATABASE
です。主な制限は、コピー中はソース データベースに他のセッションを接続できないことです。CREATE DATABASE
起動時に他の接続が存在すると失敗します。コピー操作中は、ソース データベースへの新しい接続が妨げられます。
で必要な権限を持っている場合は、テンプレート データベースへのすべてのセッションを終了できますpg_terminate_backend()
。
再接続を一時的に禁止するには、特権を取り消しますCONNECT
(GRANT
後で元に戻します)。
REVOKE CONNECT ON DATABASE mydb FROM PUBLIC;
-- while connected to another DB - like the default maintenance DB "postgres"
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = 'mydb' -- name of prospective template db
AND pid <> pg_backend_pid(); -- don't kill your own session
CREATE DATABASE mydb_test TEMPLATE mydb;
GRANT CONNECT ON DATABASE mydb TO PUBLIC; -- only if they had it before
Postgres 9.2より前のバージョンでは、次procpid
の代わりに使用しpid
ます。
関連している:
同時セッションを終了する余裕がない場合は、すでに他の回答で提案されているように、の出力pg_dump
をパイプしてください。psql
それは私が探していたものですが、自分でコンパイルする必要がありました:P
同じユーザーを保持し、スクリプト内に配置する必要がない方法を知っていればいいのにと思います。
#!/bin/bash
DB_SRC=conf
DB_DST=conf_test
DB_OWNER=confuser
T="$(date +%s)"
psql -c "select pg_terminate_backend(procpid) from pg_stat_activity where datname='$DB_DST';" || { echo "disconnect users failed"; exit 1; }
psql -c "drop database if exists $DB_DST;" || { echo "drop failed"; exit 1; }
psql -c "create database $DB_DST owner confuser;" || { echo "create failed"; exit 1; }
pg_dump $DB_SRC|psql $DB_DST || { echo "dump/restore failed"; exit 1; }
T="$(($(date +%s)-T))"
echo "Time in seconds: ${T}"
データベースにオブジェクトをドロップするのが問題だとは言わなかったのでpg_dump
、この--clean
オプションを指定して実行すると、希望どおりの結果が得られると思います。この種のことのために、pg_dumpの出力をpsqlにパイプすることができます。
ここで、ストリーミング レプリケーションを使用したホット スタンバイを検討していますか?