如何等待PostgreSQL可启动/可恢复?


8

我正在运行自定义Linux发行版的虚拟机上测试将PostgreSQL 8.2.1升级到9.2。升级过程如下:

  1. 启动pg服务
  2. 清理所有数据库(不确定是否需要这样做)
  3. 备份 pg_dumpall
  4. 停止pg服务
  5. 移出存储数据的目录(/var/pg;这是一个简单的单服务器设置)
  6. 安装PostgreSQL 9.2
  7. initdb
  8. 启动服务器
  9. 恢复转储的数据
  10. reindexdb 所有数据库
  11. 重新创建referential_constraints视图
  12. 清理所有数据库(此升级后需要AFAIK)

此过程在一台主机上正常运行,可以毫无问题地进行备份和还原。在另一台具有不同数据库的机器上,从1到7的点可以正常工作,但是除非添加sleep 1after initdb,否则服务器将无法启动,即使那样,由于“数据库系统正在启动”,因此无法还原转储的数据。除了这些可怕的骇客之外,有什么标准的方法可以解决此问题:

  1. sleep在进行任何一项操作之前要花一些时间,
  2. 循环播放,直到它起作用或达到足够的超时,或者
  3. 循环直到它接受一个琐碎的查询或达到超时。

编辑:“ 解决方案 ”根本没有用。如何确定数据库已准备好运行还原?


只是一个想法:您可以测试initdb退出状态吗?我想设置完成后就可以了。
dezso 2012年

@dezso Nope initdb是同步运行的,因此启动服务器时initdb已成功完成。
l0b0 2012年

然后,我没有比循环测试内容是否就绪的简单测试更好的主意了。
dezso 2012年

2)不需要。10)也不需要,因为还原转储将重新创建所有索引。
a_horse_with_no_name 2012年

Answers:


5

initdb在完成之前不会返回,因此在它与服务器启动之间应该不需要任何暂停。PostgreSQL中有一些错误,尽管它没有先将所有内容刷新到磁盘上就完成了。我现在不知道还有什么,但是错误的本质是您并不总是了解它们。

如果使用pg_ctl命令启动数据库,请使用“ -w”参数等待启动完成后再返回。它没有做任何花哨的事情,它只是“准备好了吗?” 为您循环。

请注意,如果服务器崩溃后需要重播许多数据,然后服务器才能启动,则在pg_ctl等待中由“ -t”设置的超时可能太低。

在对pg_dump进行源数据库之前,没有理由对源数据库进行VACUUM。尽管可能会加快转储的速度,但真空本身所需的时间将比该改进所需的时间更长。


12.步骤是必需的吗?我希望表是连续的(或者在pg_restore -j{morethan1} 之后几乎是连续的)。
dezso 2012年

我们正在运行postmaster启动守护程序,它似乎没有这种选择。
l0b0 2012年

2

工作中损坏的解决方案是修改init脚本以反复检查相关端口是否正在使用。如果一分钟后未出现,则认为启动失败。伪代码:

start() {
    pg start
    checks=0
    while checks < 30:
        return true if the port is in use
        sleep 2
        checks++
    return false
}

编辑:事实证明这不够。恢复步骤:

PGOPTIONS='--client-min-messages=warning' psql \
    --no-psqlrc \
    --variable=ON_ERROR_STOP=1 \
    --quiet \
    --log-file="$restore_log" \
    --single-transaction \
    --username postgres \
    --file="$sql_backup"

错误信息:

psql: FATAL:  the database system is starting up
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.