恢复失败,缺少 chat_mention 函数

我正尝试从最近的服务器恢复到今天构建的服务器。它以这个错误失败。我在 Discourse 代码或插件代码中都没有看到这个错误。

我不知道接下来该做什么。

                                                                                                                           [20/9694]
ERROR:  function discourse_functions.raise_chat_mention_notifications_old_notification_id_readonly() does not exist
EXCEPTION: psql failed: ERROR:  function discourse_functions.raise_chat_mention_notifications_old_notification_id_readonly() does not exist
/var/www/discourse/lib/backup_restore/database_restorer.rb:92:in `restore_dump'
/var/www/discourse/lib/backup_restore/database_restorer.rb:26:in `restore'
/var/www/discourse/lib/backup_restore/restorer.rb:51:in `run'
script/discourse:157:in `restore'
/var/www/discourse/vendor/bundle/ruby/3.
4 个赞

我在新的标准安装和业务托管站点上都看到了这个错误。

2 个赞

我已经发出了内部信号,我们将在未来几天内进行处理。

4 个赞

在尝试在新安装上恢复时,我也遇到了同样的错误,因为我试图将我的 discourse 迁移到另一台服务器。没有找到解决方案。

1 个赞

哦哦,其实我刚找到一个解决方案。

我很幸运,旧服务器还在运行。所以我重建了启动器应用程序,使旧服务器与新安装的版本完全相同。然后通过命令行进行了另一次备份。在新安装上恢复此备份时,一切顺利。你应该试试这个。@pfaffman

2 个赞

这可以一站式解决我的问题。谢谢!

很高兴能帮到您!

1 个赞

哎呀,我也遇到了同样的问题。我正尝试从生产系统恢复到沙盒/开发环境。我也仔细检查了所有安装的插件,它们是相同的。
还有哪个插件使用了这个?我现在就去检查源代码……

好的,这是我所做的:

  1. 确保 /var/discourse/shared 文件夹为空,或者将其移动到新位置以备恢复。
  2. 使用 ./launcher bootstrap <app> 初始化一个新的 discourse 实例。
  3. 再次尝试恢复,但仍然在相同的错误消息处失败。
  4. 然后,当我转储我好的 discourse 实例时,我找到了创建该函数的实际命令。它是:
CREATE FUNCTION discourse_functions.raise_chat_mention_notifications_old_notification_id_readonly() RETURNS trigger
    LANGUAGE plpgsql
    AS $$
  BEGIN
    RAISE EXCEPTION 'Discourse: old_notification_id in chat_mention_notifications is readonly';
  END
$$;


ALTER FUNCTION discourse_functions.raise_chat_mention_notifications_old_notification_id_readonly() OWNER TO discourse;

然后重试恢复,一切顺利!

现在,我有一个失败时的日志,并且认为之后可以回去查看它,但是日志会在每次备份/恢复功能时重置。

增强功能:最好有一个备份/恢复历史记录。也许有一个,但我不知道在哪里。

免责声明:我不是 Discourse 的支持人员,所以我不会深入介绍如何进入 psql 命令行提示符来运行上述命令。 : :slight_smile:

问题在于,一个日期戳较早的迁移后来被提交到了 tests-passed(@nbianca FYI),而版本备份中的版本元数据并未检测到这一点。我曾在此处提到过这一点。

这就是解决方案。因此,您需要从实例服务器获取提交哈希,并使用该提交构建新实例,或者将现有实例更新到最新版本,这将运行该迁移,然后进行新的备份。

2 个赞

您是说,永久的(当前?)解决方案是仅恢复到创建备份的同一个提交(或实际迁移)吗?

或者,如果两个版本都超出了错误提交的范围,我们是否会没问题?

是的,但有时你将无法更新源实例。在这种情况下,你需要将目标放在与源相同的提交上。因此,这是常规情况的一个例外,在常规情况下,你总可以在恢复期间进行隐式前向迁移。

1 个赞

我今天将对此进行测试,但我目前的假设是,只要目标站点完全更新,恢复就可以正常工作。

看起来问题在于,恢复开始时的版本检查未能检测到源数据库的数据库架构实际上比目标数据库更新。

是的,我相信是真的。

正确,发生这种情况是因为迁移没有记录提交时的时戳,而是记录了生成迁移时的时戳。大多数时候这并不重要,但在这种情况下,这两个时刻之间有 7 周的时间间隔。

1 个赞

是的,这是一个不幸的极端情况。我们可以尝试在未来避免它,或者想出一个向后兼容的解决方案来防止它再次发生。但是,我认为在这种情况下我们无能为力。覆水难收。无论我们做什么,它总是需要网站所有者将其目标网站升级到最新版本。

1 个赞

没错,这是这类技术普遍存在的问题,这是 Ruby on Rails 以及 PHP Laravel 等其他 AR 实现的通用问题。而且正如你所说,这种情况并不经常发生,一旦你意识到发生了什么,在恢复过程中很容易解决。

2 个赞

有时您根本不想这样做。

所以听起来,如果我升级我正在处理的两个源站点,我就没事了。

再次感谢您,Richard!

1 个赞

所以,在我的场景中,我的恢复环境比备份的保险版本新了几个版本。这不应该能工作吗?

你备份的那份有多久了?

那是我正要研究的事情!稍等一下。我希望我们保留了以前备份的日志,或者我们有吗?

由于这是我们要恢复的沙盒,我再次启动了它。这是从生产环境恢复到沙盒:

这是恢复日志中的数字:

[2024-10-21 19:49:59]   当前版本:20241018031851
[2024-10-21 19:49:59]   恢复版本:20241011054348