2.7beta7升级后崩溃

大家好,

我们在 https://discourse.bokeh.org 上自托管 Discourse 实例已有数年。总体而言,它一直非常稳定,几乎无需维护,尤其是执行更新时,通常完全不会出现问题,能够完美完成。

然而,今天在进行 2.7beta7 版本更新(看似顺利完成)后,我们的站点彻底崩溃了。起初它还能勉强运行,但页面渲染异常且 JS 控制台报错;在尝试回滚后,UI 变得完全无法使用。登录到 Droplet 后,我还尝试了以下方法,但均无果:

重建

./launcher rebuild app

多次尝试均在不同阶段失败。

Discourse Doctor

./discourse-doctor

恢复

./launcher enter app
discourse restore <backup file>

此操作失败。

清空

我还尝试执行“清空”操作后再恢复:

./launcher stop app
./launcher destroy app
rm -r /var/discourse/shared/standalone/

之后,我至少成功执行了一次重建,使系统回到“全新安装”状态,例如显示“恭喜,您已成功安装 Discourse!”

因此,我再次尝试运行 discourse restore,但依然失败:

EXCEPTION: 1 posts are not remapped to new S3 upload URL. S3 migration failed for db 'default'. /var/www/discourse/lib/file_store/to_s3_migration.rb:131:in `raise_or_log' /var/www/discourse/lib/file_store/to_s3_migration.rb:86:in `migration_successful?' /var/www/discourse/lib/file_store/to_s3_migration.rb:357:in `migrate_to_s3' /var/www/discourse/lib/file_store/to_s3_migration.rb:65:in `migrate' /var/www/discourse/lib/file_store/s3_store.rb:240:in `copy_from' /var/www/discourse/lib/backup_restore/uploads_restorer.rb:62:in `restore_uploads' /var/www/discourse/lib/backup_restore/uploads_restorer.rb:44:in `restore' /var/www/discourse/lib/backup_restore/restorer.rb:62:in `run' script/discourse:145:in `restore' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/command.rb:27:in `run' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/invocation.rb:127:in `invoke_command' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor.rb:392:in `dispatch' /var/www/discourse/vendor/bundle/ruby/2.7.0/gems/thor-1.1.0/lib/thor/base.rb:485:in `start' script/discourse:286:in `' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:63:in `load' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:63:in `kernel_load' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli/exec.rb:28:in `run' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:494:in `exec' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor.rb:392:in `dispatch' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:30:in `dispatch' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/vendor/thor/lib/thor/base.rb:485:in `start' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/cli.rb:24:in `start' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/exe/bundle:49:in `block in ' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/lib/bundler/friendly_errors.rb:130:in `with_friendly_errors' /usr/local/lib/ruby/gems/2.7.0/gems/bundler-2.2.7/exe/bundle:37:in `' /usr/local/bin/bundle:23:in `load' /usr/local/bin/bundle:23:in `' Trying to rollback... Rolling back... Cleaning stuff up... Dropping functions from the discourse_functions schema... Removing tmp '/var/www/discourse/tmp/restores/default/2021-04-23-235404' directory... Marking restore as finished... Notifying 'system' of the end of the restore... Finished! [FAILED]

奇怪的是,在恢复过程中,站点似乎正在恢复正常,旧内容也开始显示。但随后失败发生,现在什么都显示不出来,账户也不见了等等。

我真的很需要任何指导或建议。我们有每日备份,可追溯至一周前(如有需要,还可从 Glacier 中恢复更早期的备份)。几天前我们删除了一个未使用的分类,这是否可能是导致问题的原因?我会尝试使用更早的备份来验证,但任何关于可靠恢复流程的指点都将不胜感激。

2 个赞

旧的备份没有帮助。在恢复过程中,情况看起来“还算正常”

直到最后时刻,随后立即跳转到以下界面:

顺便问一下,备份中是否不包含最初从邮件列表导入、但已在 Discourse 站点存在多年的帖子?此前我们有 24,000 条帖子,而不是 5,000 条。

2 个赞

是否可以在旧版本的 Discourse(例如 2.7beta6)上重新构建应用程序?

2 个赞

或者,我想是不是只有一个帖子导致了问题?

异常:1 个帖子未映射到新的 S3 上传 URL。S3 迁移在数据库 ‘default’ 上失败。

能否找到这个帖子并将其删除或移除?

2 个赞

您的图片是否在 S3 上?

2 个赞

@pfaffman 是的,我们确实在 S3 上托管了图片。

2 个赞

嗯,也许只是有一篇帖子出了问题?我想你需要先恢复数据库,修复它,然后用新数据库重新构建备份文件。但这真的很难判断。

2 个赞

是否有相关说明指导如何操作?我该如何确定哪条帖子出了问题?

编辑:或者,是否有具备相关专业知识的人员可以受聘提供服务?

2 个赞

您是否有可以恢复的fresh droplet备份或快照?

2 个赞

您是否有可以恢复的最新 Droplet 备份或快照?

遗憾的是,没有。DigitalOcean 的备份仅每周一次,而我已配置每日 Discourse 备份到 S3,保留一周的新鲜备份和一年前的归档备份。鉴于我之前多次成功升级 Discourse 的经验,我以为这样做既足够又更优(而且我之前也成功进行过测试恢复)。

2 个赞

假设是
version: 94301854938a0b36dd64666fb7a7c8406544a781,即 beta 版本提升之前的那个提交。

3 个赞

其实算是个更新。在一阵绝望中,我在“同步文件到 S3”这一步直接强制中止了恢复脚本,当时它还没抱怨那篇有问题的帖子并开始回滚。

网站实际上已经恢复上线,并且可以在安全模式下访问。我禁用了那个“复制粘贴”主题组件中的代码块功能,它显然与最新的 beta 版本完全不相容。之后,即使不在安全模式下,网站似乎也基本恢复了正常。不过:

  • 有什么建议的操作可以确保系统尽可能“清理”干净吗?例如重新上传资源到 S3 并“重新烘焙”?哪里能找到最好、最新的相关说明?

编辑:据我所知,一切已恢复正常。旧帖子中的图片也能从 S3/CDN 正确加载。那么我的问题是,如果我们正在将图片上传到 S3,是否应该取消勾选这个选项?

在计划备份中包含上传的文件。禁用此项将仅备份数据库。

我原本以为勾选它能提供额外的冗余保障,但看来这似乎是恢复过程中所有问题的根源?

2 个赞

上次我迁移到其他托管提供商时,在恢复过程中也遇到了 S3 的问题。因此我询问了相关情况,得到的答复是肯定的:如果你将图片存储在 S3 上,则需要在备份时排除上传文件,仅备份数据库。不过,我不确定这是否适用于你的情况。如果你打算尝试,请先创建一个快照。

你可以在此查看更多详情:Restore a backup from the command line - #28

我刚刚尝试过,一切顺利,没有任何问题。:slightly_smiling_face:

2 个赞

我可以帮忙。周一可以,若有危险津贴则更早。

您可以访问 Contact Us - Literate Computing 查看我们 S3 服务页面底部的电子邮件地址。

2 个赞

@pfaffman 谢谢!网站现在似乎已经完全恢复正常了,但如果您方便的话,我很乐意请您快速检查一下以确认无误。无论如何,我已经记下了您的商业联系方式,以备将来发生紧急情况时使用。:slight_smile:

以下是此次事件的回顾,或许对其他人也有帮助:


摘要

在一次(成功的)升级后,一个不兼容的非官方主题组件插件导致网站界面损坏。当时并未意识到这一点,因此启动了备份恢复流程,但由于配置不够理想,恢复过程遇到了问题。

详情

  1. 启动并成功完成了向 2.7beta7 的升级。
  2. 然而,升级后网站界面严重受损:帖子正文完全缺失,顶部导航栏(包括用户/登录选项)也完全消失,JS 控制台报告了错误。
    1. 后来发现,原因是第三方主题组件(用于复制粘贴代码块)不兼容,但当时并未意识到这一点。
    2. 当时也不知道可以进入安全模式。如果早知道这一点,本可以避免后续的一些问题。
  3. 通过直接导航访问了 \\admin,并尝试回滚。这导致用户立即被登出,且由于界面损坏,似乎无法重新登录。
  4. 登录到 DigitalOcean Droplet,尝试使用来自 S3 的最新备份 tarball 进行手动恢复。
  5. 许多恢复尝试在最终步骤附近失败,即在上传 S3 资源之后,原因是某一篇帖子存在错误。
    1. 显然,这是因为尝试重新上传资源到 S3 的恢复过程可能不稳定(Meta 上有多起相关报告)。
    2. 然而,实际上并不需要备份上传的资源,因为它们已经存储在 S3 上了!
  6. 在多次恢复尝试中的某一次,为了从“干净的状态”重新开始,网站被清空,导致随后的恢复失败后的回滚操作将网站回退到了空状态。
  7. 最终,在一场孤注一掷的尝试中,我运行了恢复脚本,并在 S3 上传阶段(就在失败和回滚发生之前)强制中止了脚本。
  8. 网站重新上线,但出现了之前的界面问题。不过,此时已知并启用了安全模式,禁用插件和主题后,网站功能恢复正常。
  9. 移除了所有非官方插件和主题(包括“复制粘贴”组件),之后网站功能恢复正常。
  10. 验证了之前上传的图片仍然可以正常加载,且来自 S3 CDN。

我怀疑最后的上传和“重新烘焙”步骤其实是不必要的,因为资源已经存在于 S3 上,帖子也不需要更新为使用新的 URL。

我不确定脚本被中止后是否遗漏了任何剩余的恢复步骤,但到目前为止,尚未有人发现网站当前状态存在任何问题。

经验教训 / 后续行动

  • 未来诊断问题时,应首先启用安全模式。
  • 关闭备份中包含上传资源的设置(建议 Discourse 对此情况发出警告)。
  • 移除所有非官方插件和主题组件。
  • 建议启用内置的新代码块复制功能。
  • 启用 DigitalOcean 的每周镜像备份,作为恢复的后备方案。
6 个赞

是主题组件还是插件?能否通知作者?

3 个赞

@merefield 这似乎是已知的,我正是因此才了解到这一可能性。

https://meta.discourse.org/t/copy-option-for-code-blocks-in-discourse/60961

4 个赞

如果让我对恢复过程提一个建议,那就是提供一些选项以增强其鲁棒性。例如,如果阻碍成功恢复的唯一问题是一条损坏的帖子,当被问及“是否删除该损坏的帖子?”时,我会毫不犹豫地猛按 Y 键。

3 个赞

这将在下一个 2.8 测试版中实现。遗憾的是,它尚未准备好用于即将到来的 2.7 版本。

很抱歉我之前没有看到您的求助。这里给所有遇到 S3 存储上传导致恢复失败的用户提供一个提示:从备份中提取 dump.sql.gz 文件并重命名该文件。例如,如果原始备份文件名为 discourse-2020-10-09-133921-v20201007124955.tar.gz,则生成的文件应命名为 discourse-2020-10-09-133921-v20201007124955.sql.gz。恢复该文件应该可以正常工作。

7 个赞