主题:重置所有最高值耗尽所有可用的磁盘空间

在我本地的一个容器中工作时,我从一个有 20 多年活动历史的 SMF2 论坛导入了数据,却遇到了 Topic.reset_all_highest 的一个致命 bug。
导入数据后,我的数据库显示大约有 6 万个普通主题和大约 40 万个私信主题,而 Topic.reset_all_highest 中的查询会导致行数呈几何级增长,导致我的磁盘空间耗尽(最初有 120GB 可用空间)。
我目前正尝试将查询分成可管理的小块,并直接在 Postgres 中运行它们,但这显然不是最佳方案(而且我不确定它是否有效并最终得到正确的结果)。
我尝试查看是否有人遇到过类似问题,但一无所获,所以我怀疑这是否与我的设置有关——顺便说一句,我使用的是最新的 Docker 版本。

1 个赞

我最近进行了一次中等规模的导入,但它似乎无限期地卡在了 Topic.reset_all_highest 上,我不得不终止 Postgres 中的查询才能继续。我以前没有遇到过这个问题,以为可能是我的 postgres 服务器过载了(它连接了很多站点)。

我的下一步是迁移到另一个 postgres 服务器,但我还没有着手去做。

在我“拆分查询”实验的前两个部分(公共主题的 X 和 Y)顺利进行后,我尝试了 Z,结果它冻结了——也就是说,根据 postgres 活动,查询是活动的,并且 top 显示进程正在 100% 运行。
所以我又看了一下 SQL,找到了问题:两个查询都以这种方式结束

      WHERE
        topics.archetype <> 'private_message' AND
        X.topic_id = topics.id AND
        Y.topic_id = topics.id AND
          (
          topics.highest_staff_post_number <> X.highest_post_number OR
          topics.highest_post_number <> Y.highest_post_number OR
          topics.last_posted_at <> Y.last_posted_at OR
          topics.posts_count <> Y.posts_count OR
          topics.word_count <> Z.word_count
        )

(另一个当然是 ‘private_message’ 作为 archetype)
这意味着查询缺少
Z.topic_id = topics.id - 这导致了整个几何级数的增加。

将查询的 WHERE 子句更改为

      WHERE
        topics.archetype <> 'private_message' AND
        X.topic_id = topics.id AND
        Y.topic_id = topics.id AND
        Z.topic_id = topics.id AND
          (
          topics.highest_staff_post_number <> X.highest_post_number OR
          topics.highest_post_number <> Y.highest_post_number OR
          topics.last_posted_at <> Y.last_posted_at OR
          topics.posts_count <> Y.posts_count OR
          topics.word_count <> Z.word_count
        )

为我解决了问题。
我应该打开一个 PR 吗?

2 个赞

我认为应该。如果你能找到导致此问题的提交,那将更有说服力。

1 个赞

我已经为此提交了一个 PR,但有一些不幸的限制(例如,我想不到如何测试此更改)。

6 个赞

此更改看起来是正确的,正在合并。

(从测试角度来看,应该有覆盖率和一个简单的测试来验证它,我们只需要确认没有回归。)

5 个赞