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

How to initialize a PostgreSQL database without running the PostgreSQL server

在初始化脚本中,我想初始化一个 PostgreSQL 目录,但不需要(也不想要)运行ning PostgreSQL 服务器位于这个阶段。

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

initdb -D ...

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

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

后面的命令需要 运行ning 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 运行 秒中有 1 次失败。此外,在简单的 shell 脚本中终止该进程可能不是 100% 可靠的,更不用说确保它已正确停止。

我相信这是所有涉及引导服务器或准备 VM 映像的用例中都会出现的标准问题。所以人们会期望在 2016 年,应该有一些现有的、可靠的工具。所以我的问题是:

您正在寻找 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