2012-04-11 65 views
9

我正在尋找一個基本腳本/命令來創建活動數據庫的副本(在同一臺服務器上,我們將它們命名爲mydbmydb_test)。如何從生產中一步一步克隆測試數據庫?

要求

  • 它即使mydb_test已經存在運行,並有記錄
  • 它的工作即使mydbmydb_test確實有存在的連接
  • 它具有清潔可能存在的數據庫如有需要

提示:

  • drop database不能,如果你有現有連接

回答

2

這就是我一直在尋找,但我不得不編譯它自己: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}" 
2

既然你不說這是在數據庫中下降對象一個問題時,我覺得跟--clean選項運行pg_dump會做什麼你想。您可以將pg_dump的輸出傳輸到psql中,以實現這種功能。

5

創建現有(活的)數據庫的完整副本,最簡單和最快的方法是使用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就像已經被其他答案所暗示。

相關問題