如何在一个单一操作中从生产中克隆测试数据库?

sor*_*rin 11 postgresql templates database-connection postgresql-9.1

我要寻找一个基本的脚本/命令,将创建一个实时数据库的副本(让他们的名字mydbmydb_test,都在同一台服务器上).

要求

  • 它必须运行,即使mydb_test已经存在并且有记录
  • 即使mydb并且mydb_test确实存在连接,它也必须工作
  • 如有必要,它必须清理可能存在的数据库

提示:

  • drop database 如果您有现有连接,则无法使用

Erw*_*ter 6

创建一个现有的(活的)数据库的完整副本,最简单,最快速的方法是使用CREATE DATABASE一个TEMPLATE:

CREATE DATABASE mydb_test TEMPLATE mydb;
Run Code Online (Sandbox Code Playgroud)

但是,存在违反第二个要求的重要限制:模板(源)数据库无法与其建立额外的连接.我引用手册:

可以创建其他模板数据库,实际上可以通过将其名称指定为模板来复制集群中的任何数据库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
Run Code Online (Sandbox Code Playgroud)

在Postgres 9.2 之前的版本中使用procpid而不是pid:


如果你不能终止并发会话,去与管道输出的pg_dumppsql喜欢被建议通过其他的答案了.


sor*_*rin 4

这就是我一直在寻找的,但我必须自己编译它: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}"
Run Code Online (Sandbox Code Playgroud)