![Postgresql - 配置为 Upstart 作业问题](https://linux22.com/image/828182/Postgresql%20-%20%E9%85%8D%E7%BD%AE%E4%B8%BA%20Upstart%20%E4%BD%9C%E4%B8%9A%E9%97%AE%E9%A2%98.png)
我需要将 Postgresql 配置为使用 Upstart 系统启动,因为我使用 Upstarts 事件来启动另一个依赖于 pgsql 运行的应用程序。这是我使用的教程/脚本:
http://bradleyayers.blogspot.com/2011/10/upstart-job-for-postgresql-91-on-ubuntu.html
当我重新启动服务器 ( shutdown -r now
) 时,postgresql 没有运行(通过“top”命令看不到作业)。然后我尝试手动运行以下命令:
root@server:~# exec su -c "/usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main -c config_file=/etc/postgresql/9.1/main/postgresql.conf" postgres
我的 ssh 会话只是断开连接,没有返回任何内容。如果我重新连接并再次检查正在运行的作业,pgsql 仍然没有运行。所以我尝试运行没有“exec”的命令,以下是响应:
root@server:~# su -c "/usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main -c config_file=/etc/postgresql/9.1/main/postgresql.conf" postgres
2012-12-03 19:31:36 MSK FATAL: could not create lock file "/var/run/postgresql/.s.PGSQL.5432.lock": No such file or directory
我认为问题与 postgresql 本身有关,而不是 upstart 系统。我认为它提到的文件应该存在,因此可以访问,但由于某种原因它不存在。是否有其他人偶然发现这个问题,或者有潜在的解决方案?
答案1
我也有同样的愿望,希望以这种方式配置 pg。对我来说,我想要多个集群,每个集群都有自己独立的调度程序 (pgagent)。当我关闭单个集群时,pgagent 将自动停止,但当我启动集群时,我希望 pgagent 也为该集群自动启动。如果我在启动集群时忘记启动调度程序,那我就有麻烦了。
我搜索了一番,但始终找不到在 Upstart 下运行 PostgreSQL 的好方法。大多数解决方案都明确启动了 postmaster,而不是使用 pg_wrapper 命令。按照 Upstart 的工作方式,这似乎很危险,在极少数情况下可能会导致数据丢失。
因此,我继续前进,尝试创建自己的 Upstart 脚本来完成这项工作。我发现很难捕获集群及其 pgagent 实例的正确 PID。但最终,我意识到使用 PostgreSQL,您实际上并不关心 PID。您关心的是版本和集群。一旦我意识到这一点,一切都结合在一起,我创建了以下三个脚本:
第一个我称之为 pg_versions.conf。
description "PostgreSQL Version Controller"
author "Brian Myers"
start on runlevel [2345]
stop on runlevel [016]
env DEFAULT_VERSIONS="9.3"
pre-start script
if [ -z $VERSIONS ]; then
VERSIONS=$DEFAULT_VERSIONS
fi
for version in $VERSIONS
do
for cluster in $(pg_lsclusters -h | grep $version | cut -d" " -f 2)
do
if [ `tail -1 /etc/postgresql/$version/$cluster/start.conf` = "auto" ]; then
start pg_cluster version=$version cluster=$cluster
fi
done
done
end script
post-stop script
if [ -z $VERSIONS ]; then
VERSIONS=$DEFAULT_VERSIONS
fi
for version in $VERSIONS
do
for cluster in $(pg_lsclusters -h | grep $version | cut -d" " -f 2)
do
stop pg_cluster version=$version cluster=$cluster
done
done
end script
接下来是 pg_cluster.conf。
description "PostgreSQL Cluster Controller"
author "Brian Myers"
instance $version-$cluster
pre-start script
if [ `pg_lsclusters -h | grep $version | grep $cluster | cut -d" " -f 4` = "down" ]; then
pg_ctlcluster $version $cluster start || :
start pg_agent version=$version cluster=$cluster || :
fi
end script
post-stop script
if [ -e "/var/run/postgresql/pgagent-$version-$cluster.pid" ]; then
stop pg_agent version=$version cluster=$cluster
fi
if [ `pg_lsclusters -h | grep $version | grep $cluster | cut -d" " -f 4` = "online" ]; then
pg_ctlcluster $version $cluster stop
fi
end script
最后是 pg_agent.conf。
description "PgAgent Controller"
author "Brian Myers"
instance ${version}-${cluster}
setuid postgres
pre-start script
PORT=`pg_lsclusters -h | grep $version | grep $cluster | cut -d" " -f 3`
if [ -z `psql -c "select schema_name FROM information_schema.schemata WHERE schema_name = 'pgagent';" -d postgres -p $PORT | grep pgagent` ]; then
stop ; exit 0
fi
PGAGENTDIR=`which pgagent`
PGAGENTOPTIONS="host=/var/run/postgresql dbname=postgres user=postgres port=$PORT"
start-stop-daemon --start --oknodo --name "pga$version$cluster" --exec $PGAGENTDIR -- $PGAGENTOPTIONS
pgrep -f "$PGAGENTDIR.+$PORT" > /var/run/postgresql/pgagent-$version-$cluster.pid
end script
post-stop script
start-stop-daemon --stop --oknodo --pidfile /var/run/postgresql/pgagent-$version-$cluster.pid
if [ -w /var/run/postgresql/pgagent-$version-$cluster.pid ]; then
rm -f /var/run/postgresql/pgagent-$version-$cluster.pid
fi
end script
如果您想要的不仅仅是 9.3 版本,只需将版本添加到env DEFAULT_VERSIONS="9.3"
以空格分隔的行中。
有了这些,我可以:
启动所有尚未运行的集群:
sudo initctl start pg_versions
启动尚未运行的特定版本的所有集群:
sudo initctl start pg_versions version=9.3
启动特定集群,自动启动该集群的 pgagent,但前提是该集群启用了 pgagent:
sudo initctl start pg_cluster version=9.3 cluster=main
如果集群启用了 pgagent,则启动集群的 pgagent:
sudo initctl start pg_agent version=9.3 cluster=main
将 start 改为 stop 可获得相反的行为。当然,所有程序都会在启动时启动,并在 stop 时通过 关机pg_ctlcluster
,因此不会丢失数据。我确实必须通过 bum 禁用 init.d 脚本。
我确信这些问题可以得到解决,或者以更好的方式解决。例如,pg_agent 脚本——我一直搞不明白为什么使用 script 或 exec 无法捕获正确的 PID。最后我放弃了,自己管理了 pid 文件,但这仍然是个谜。这可能是因为我的 shell 脚本编写技能太差了。
还请注意,如果您手动关闭集群,pg_ctlcluster
这些 Upstart 作业仍将显示为正在运行,即使相关版本/集群未运行。这没什么大不了的,因为您只需使用 或 重新启动它们即可pg_ctlcluster
,initctl
但出于这个原因,如果您部署这些作业,我建议使用initctl
来控制您的集群。
无论如何,这些对我来说都很有效。
答案2
错误意味着 Postgres 无法在/var/run/postgresql
目录中创建其锁定文件。预脚本应该创建它,并且它将所有权设置为 postgres。对我来说,这个脚本看起来根本就没有运行。因此,请检查start postgres
(作为超级用户)、存在和权限的输出ls -l /var/run/postgresql
。
仅供参考:exec
在 Upstart 作业中很有用,因此script
运行 shell 脚本的部分不会留下额外的 PID。在 shell 会话中,当执行的程序退出时,它会使您的 shell 退出。