使用 Postgres 16 数据库(以及所有 PG>13)备份失败

由于此提交安装的是 postgresql-client-${PG_MAJOR} 而不是 postgresql-client,导致 postgres 16 数据库的备份不再工作。

这是在解决某个问题吗?操作系统提供的 psql 客户端不是一直能很好地兼容所有版本的 postgres 吗?

我曾惊讶地发现此客户端在使用 Digital Ocean 数据库上的 PG16,但我以为我知道一些 CDCK 托管现在正在使用 PG15。

有没有什么更好的方法可以获得有效的备份,而不是像这样:

run:
  - exec:
      cd: /var/www/discourse
      cmd:
        - apt-get update && apt-get remove -y postgresql-client-13 && apt-get install -y postgresql-client-16

也许我可以在环境变量中设置 PG_MAJOR?

2 个赞

是的,看起来是这样。

来自 PR

我在 Discourse 使用 pg_dump 版本 17.2 进行备份时发现了这个 bug,而这个备份无法恢复到低于 17.2 的 PostgreSQL 集群上。

看起来你陷入了两难境地 (PostgreSQL: Documentation: 18: pg_dump)

因为 pg_dump 用于将数据传输到较新版本的 PostgreSQL,所以 pg_dump 的输出可以加载到比 pg_dump 版本更新的 PostgreSQL 服务器版本中。pg_dump 也可以从比其自身版本旧的 PostgreSQL 服务器进行转储。 (目前支持回溯到 9.2 版本服务器。)但是,pg_dump 不能从比其自身主版本更新的 PostgreSQL 服务器进行转储;它会拒绝尝试,以免产生无效的转储。此外,不能保证 pg_dump 的输出可以加载到旧主版本的服务器中——即使转储是从该版本服务器进行的。将转储文件加载到旧服务器可能需要手动编辑转储文件以删除旧服务器无法识别的语法。

哎呀。我还以为我读了 PR。考虑到我是以英语为母语的人,并且拥有博士学位,你应该认为我能做得更好。 :person_shrugging:

不行。我做不到,因为这是构建基础镜像的方式。

所以,看起来我的修复已经尽力了,尽管如果我更聪明一点,我会清除 apt-get update 拉入的 apt 相关内容。

我想象其他人也会遇到这个问题,因为通常很难说服各种人类和系统你想要 PG13 而不是更新的版本。而且,似乎很久以前就有人说过 Discourse 与 PG15 兼容。

谢谢你,Richard!

1 个赞

备份会静默失败吗??

(我看到我的普通安装使用的是 13 版本,所以我认为这种情况有点特殊,但也许并不罕见。)

它们不会。所以这是很明显的,并且只应该发生在那些知道如何管理自己的 PostgreSQL 的人身上。

1 个赞

大家好,我今天遇到了这个问题。症状是大约六天以来我们一直收到备份失败的警报,关键的日志行似乎是:

[2025-06-14 03:30:20] pg_dump: error: aborting because of server version mismatch
[2025-06-14 03:30:20] pg_dump: detail: server version: 16.9; pg_dump version: 15.12 (Debian 15.12-1.pgdg120+1)

我在 Digital Ocean 的一个 Ubuntu 实例上运行 Discourse,使用的是推荐的安装指南。但我使用的是 Digital Ocean 的托管 Postgres 数据库,而不是 Postgres 容器。查看我的数据库,它运行的是 pg 16。我不认为他们最近升级了它(而且我也不期望主要版本升级是自动的),但我已经给他们的支持发了邮件进行核实。

无论如何,我的研究引导我找到了这个页面。我不确定应该在哪里放置 @pfaffman 发布的 YAML,所以我手动运行了命令,并认为应该分享给其他遇到此问题的人:

  • cd /var/discourse
  • launcher enter app
  • apt list --installed | grep postgres # 确认当前安装的版本是 15
  • apt-get update
  • apt-get remove postgresql-client-15
  • apt-get install postgresql-client-16

然后我在管理备份页面触发了一次手动备份。

这似乎暂时解决了问题,但正如 @pfaffman 所指出的,我预计下次升级 Discourse 时,它会恢复到 postgresql-client-15,备份将再次停止工作,需要上述手动干预。

除了每次升级 Discourse 时都要重复这些步骤之外,还有没有其他解决方案?

我想在这里的某个地方,我提供了将这些命令放在你的app.yml上的东西。

你可以看看postgres模板作为例子,也许。

谢谢,但我不确定我是否理解了。我得到的印象是,您在上面原始帖子中提到的 YAML 只是将我上面发布的少量命令减少到一个命令的一种方式,但您仍然必须在每次升级 Discourse 时手动运行它。我理解错了吗?