我正在寻找一个基本脚本/命令来创建活动数据库的副本(在同一台服务器上,我们将它们命名为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
就像已经被其他答案所暗示。