在初始化脚本中,我想初始化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年,应该有一些现有的,可行的工具。所以我的问题是:
答案 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