Postgresql – 配置为Upstart作业问题

我需要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系统有关。 我认为它提到的文件应该存在,因此可以访问它,但它不是出于某种原因。 别人偶然发现了这个,或者有可能解决这个问题?

我有同样的愿望以这种方式配置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

更改开始停止以获得反向行为。 当然一切都在启动时启动,并在停止时通过pg_ctlcluster关闭,因此没有数据丢失。 我必须通过bum禁用init.d脚本。

我确信这些可以通过更好的方式进行清理或完成。 例如pg_agent脚本 – 我永远无法弄清楚为什么使用脚本或exec无法捕获正确的PID。 最终我自己放弃并管理了pid文件,但它仍然是一个谜。 这可能是我非常软的shell脚本编写技巧。

另请注意,如果使用pg_ctlcluster手动关闭群集,即使关联的版本/群集不是,这些Upstart作业仍将显示为正在运行。 没什么大不了的,因为您可以使用pg_ctlclusterinitctl重新启动它们,但出于这个原因,我建议使用initctl来控制群集,如果您部署这些作业。

无论如何,这些对我来说都很有效。

错误意味着Postgres无法将其锁定文件创建到/var/run/postgresql目录中。 预期脚本应该创建它,并且它将所有权设置为postgres。 对我来说,看起来这个脚本根本没有运行。 所以检查start postgres的输出(作为超级用户),存在和权限ls -l /var/run/postgresql

仅供参考: exec在Upstart作业中很有用,因此运行shell脚本的script部分不会留下额外的PID。 在shell会话中,它会在执行程序退出时退出shell。