Rake:rebake 出现错误导致崩溃:PG::ConnectionBad: PQsocket

我将一个包含 200,000 帖子的论坛迁移到了新服务器。为了避免停机,将在线站点设置为只读模式。

我在一个不同的子域上恢复了备份,这样用户就不会看到安装屏幕或恢复过程中可能出现的任何问题——类似于 dev.example.com

恢复完成后,我将 DNS 指向了新服务器,并更改了 app.yml 文件中的域名为正常的 forum.example.com

然后,所有基础帖子中的表情符号都指向了 dev.example.com 服务器,所以我运行了 rake:rebake

它大约能处理 1,000-2,000 帖子,然后因数据库连接错误而崩溃。

以下是几个摘录:

/usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.4/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch'
/usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.4/lib/bundler/cli.rb:34:in `dispatch'
/usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.4/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start'
/usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.4/lib/bundler/cli.rb:28:in `start'
/usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.4/exe/bundle:45:in `block in <top (required)>'
/usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.4/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
/usr/local/lib/ruby/gems/3.2.0/gems/bundler-2.4.4/exe/bundle:33:in `<top (required)>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'
     1999 / 200968 (  1.0%)
Failed to rebake (topic_id: 78730, post_id: 210607)
PG::ConnectionBad: PQsocket() can't get socket descriptor
/var/www/discourse/lib/tasks/posts.rake:108:in `rebake_posts_all_sites'
/var/www/discourse/lib/tasks/posts.rake:7:in `block in <main>'
/usr/local/bin/bundle:25:in `load'
/usr/local/bin/bundle:25:in `<main>'

Caused by:
PG::ConnectionBad: PQsocket() can't get socket descriptor

目前,我通过将 dev.example.com 域重定向到 forum.example.com 域来加载图片,但这只是一个临时解决方案。

有人知道如何解决这个错误以便我能重新烘焙所有帖子吗?是不是数据库负载过大?

1 个赞

首先,请参阅 更改 Discourse 的域名或重命名(另一种解决方案是备份然后使用新主机名恢复)。

我猜是你的数据库连接数耗尽了,但这并不是我预期的错误。

这是标准安装还是你正在使用其他 PG 服务器?

1 个赞

谢谢链接。这是 DigitalOcean 实例(“Premium AMD”,4GB RAM,2 vCPUs)上的标准 Docker 安装。

我遵循了您提到的链接中的说明。我在设置中发现了一些错误的 URL,所以我修复了它们,然后为了安全起见,重新构建了论坛。

然后我运行了类似这样的命令:

discourse remap dev.example.com forum.example.com

该命令崩溃并出现类似这样的错误:

Error: ERROR:  duplicate key value violates unique constraint "unique_post_links"
DETAIL:  Key (topic_id, post_id, url)=(78821, 207117, https://forum.example.com/t/the-slug/78946/7) already exists.

所以我暂时删除了一个链接到提到的 URL(https://forum.example.com/t/the-slug/78946/7)的帖子,再次运行该命令,它没有崩溃就成功了。

然后我再次运行了 rake posts:rebake

它在几个帖子中失败,如下所示,但继续进行(我手动重建了这些帖子的 HTML):

Rebaking post markdown for 'default'
     2273 / 200996 (  1.1%)
Failed to rebake (topic_id: 66586, post_id: 210353)
JavaScript was terminated (either by timeout or explicitly)

最后,在接近 11,000 个帖子时,它因类似这样的错误而崩溃:

/usr/local/bin/bundle:25:in `<main>'
    10996 / 200996 (  5.5%)
Failed to rebake (topic_id: 76678, post_id: 200988)
PG::ConnectionBad: PQsocket() can't get socket descriptor
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:69:in `exec_params'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/rack-mini-profiler-3.0.0/lib/patches/db/pg.rb:69:in `exec_params'
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.4.1/lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `block (2 levels) in exec_no_cache'

整个服务器似乎离线了,因为 Uptime Robot 提醒我网站已宕机。

您认为服务器不够强大,无法运行该命令吗? :thinking:

它通常在 80% 以上的 RAM 上运行,而在命令运行时会达到 100%。也许它只是内存不足了。

如果您有本地磁盘,可以添加交换空间,这样可以避免内存耗尽(无论这是否是当前问题的根源)。free 命令告诉您什么?在 dmesg 的输出中是否看到 oommemory

1 个赞

目前它显示:

              total        used        free      shared  buff/cache   available
Mem:           3.8Gi       2.1Gi       160Mi       1.0Gi       1.6Gi       488Mi
Swap:             0B          0B          0B

我没有看到 oom,但 memory 这个词在关于预留和释放内存的几个地方出现。

服务器创建时分配了 4GB RAM,因此 Discourse 没有自动创建交换文件。你认为有必要添加吗?

如果磁盘空间足够,肯定值得添加大约 2G 的交换空间。

另一件要做的事情是监控大型作业运行时的情况。我将使用 vmstat 5 5 并可能将其记录到文件中。您希望不看到 si 或 so 列中出现较大的值,并且不希望 swpd 列接近您的交换空间大小。

也许可以看看这篇帖子:

(看起来数据库系统可能正在耗尽某种资源,但我对此一无所知。)

1 个赞

好的,我稍后会尝试那些方法。我现在有 50GB 的可用空间。

我添加了一个 2GB 的交换文件,这似乎解决了问题。重新烘焙只完成了 20%,但至今没有出现任何错误,RAM 使用率也刚过 100%。

非常感谢你们两位的帮助。

2 个赞

好的!仅供记录:

  • 即使在任务运行期间,如果 vmstat 或 free(或 top)显示交换空间正在耗尽,您也可以添加更多交换空间。
  • 如果您小心操作,可以对实例进行可逆的临时升级以增加内存,这会花费一点钱,但只需要几个小时。重要的是不要升级到更大磁盘的实例,因为那是不可逆的。(更多的内存应该能让任务全速运行,而适度的内存和大量的交换空间可能会导致性能下降,任务将花费更长的时间才能完成。)
2 个赞

我考虑过,但我必须关闭服务器,而且用户在我迁移服务器时已经经历过一次恼人的“只读”期和停机时间了。:sweat:

我昨晚没能完成,因为我得去睡觉了,但现在它又在运行了。到目前为止有 30% 的进度,没有任何错误。

1 个赞

请密切关注 vmstat 或类似工具的运行情况——这是一个耗时很长的任务,您不希望不得不重新启动它。为了安全起见,我可能会再增加 2G 的交换空间。

1 个赞

好的,我偶尔会用 vmstat 检查。我把它放在一个 tmux 会话中运行,这样我就可以分离它并合上笔记本电脑一段时间。该命令可能运行了 8-9 小时,但一切都已成功完成。

2 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.