我正在尋找一個基本腳本/命令來創建活動數據庫的副本(在同一臺服務器上,我們將它們命名爲mydb
和mydb_test
)。如何從生產中一步一步克隆測試數據庫?
要求
- 它即使
mydb_test
已經存在運行,並有記錄 - 它的工作即使
mydb
和mydb_test
確實有存在的連接 - 它具有清潔可能存在的數據庫如有需要
提示:
drop database
不能,如果你有現有連接
我正在尋找一個基本腳本/命令來創建活動數據庫的副本(在同一臺服務器上,我們將它們命名爲mydb
和mydb_test
)。如何從生產中一步一步克隆測試數據庫?
要求
mydb_test
已經存在運行,並有記錄mydb
和mydb_test
確實有存在的連接提示:
drop database
不能,如果你有現有連接這就是我一直在尋找,但我不得不編譯它自己: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}"
既然你不說這是在數據庫中下降對象一個問題時,我覺得跟--clean
選項運行pg_dump
會做什麼你想。您可以將pg_dump的輸出傳輸到psql中,以實現這種功能。
您是否正在尋找Hot Standby與Streaming Replication的地方?
創建現有(活的)數據庫的完整副本,最簡單和最快的方法是使用CREATE DATABASE
with a TEMPLATE
:
CREATE DATABASE mydb_test TEMPLATE mydb;
然而,有一個重要的限制侵犯了您的第二個要求:模板(源)數據庫不能有其他連接。 I quote the manual:
它可以創建額外的模板數據庫,事實上一個 可以通過指定名稱爲 模板
CREATE DATABASE
集羣中的複製任何數據庫。然而,重要的是要了解 這不是(還)作爲通用目的「COPY DATABASE
」 設施。主要限制是,在複製源數據庫時,不會有其他會話連接到源數據庫。CREATE DATABASE
如果在啓動時存在任何其他連接,將會失敗;在 複製操作期間,阻止了到源數據庫的新連接。
如果您擁有pg_terminate_backend()
的必要權限,您可以終止模板數據庫的所有會話。
要避免終止會話與從模板複製之間的重新連接,您可以使用revoke the CONNECT
privilege (and GRANT
back later)。
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
就像已經被其他答案所暗示。