如何在不运行PostgreSQL服务器的情况下初始化PostgreSQL数据库

时间:2016-10-14 10:22:13

标签: database postgresql initialization reliability

在初始化脚本中,我想初始化PostgreSQL目录,但在此阶段不需要(也不想要)正在运行的PostgreSQL服务器。

如果我只是创建群集(作为用户postgres),这将是一个明智的选择:

initdb -D ...

但是,我还需要创建PostgreSQL角色,创建数据库并添加一些扩展(也作为用户postgres):

createuser someuser
createdb -O someuser somedb
echo 'CREATE EXTENSION xyz;' | psql somedb

后面的命令需要运行PostgreSQL服务器。所以整件事情变得非常混乱:

initdb -D ...

# Start PostgreSQL server in background
... &

# Wait in a loop until PostgreSQL server is up and running
while ! psql -f /dev/null template1; do
    sleep 0.5
done

createuser someuser
createdb -O someuser somedb
echo 'CREATE EXTENSION xyz;' | psql somedb

# Kill PostgreSQL server
kill ...

# Wait until the process is really killed
sleep 2

特别是等待PostgreSQL服务器的部分永远不会100%可靠。我尝试了很多变种,每次变换大约有20次失败。此外,在简单的shell脚本中杀死该进程可能不是100%可靠,更不用说确保它已正确停止。

我认为这是涉及引导服务器或准备VM映像的所有用例中出现的标准问题。因此人们可以预期,在2016年,应该有一些现有的,可行的工具。所以我的问题是:

  • 是否有更简单,更可靠的方法来实现这一目标?
  • 例如,有没有办法在某种特殊模式下运行PostgreSQL服务器,只需启动,执行某些SQL命令,并在最后一条SQL命令完成后立即退出?
  • 作为一个粗略的想法,内部PostgreSQL测试套件中有什么东西可以用于此目的吗?

1 个答案:

答案 0 :(得分:7)

您正在寻找single-user mode

如果您像这样启动PostgreSQL,那么您就是以超级用户身份连接的会话,它等待标准输入上的SQL语句。一旦断开连接(使用文件结束),服务器进程就会停止。

所以你可以这样做(使用bash):

postgres --single -D /usr/local/pgsql/data postgres <<-"EOF"
CREATE USER ...;
CREATE DATABASE somedb ...;
EOF

postgres --single -D /usr/local/pgsql/data somedb <<-"EOF"
CREATE EXTENSION ...;
EOF