在迁移上传至 S3 步骤时恢复进程已取消

我在尝试恢复我们的 Staging Discourse 实例时遇到了问题。Staging 环境运行的是 v2.4.0.beta1 +36。您知道问题可能出在哪里,或者应该从哪里入手排查吗?提前感谢!

以下是日志输出的末尾部分:

[2019-07-16 20:08:12] ALTER TABLE
[2019-07-16 20:08:12] ALTER TABLE
[2019-07-16 20:08:12] ALTER TABLE
[2019-07-16 20:08:12] ALTER TABLE
[2019-07-16 20:08:12] 正在迁移数据库...
[2019-07-16 20:08:16] 正在重新连接数据库...
[2019-07-16 20:08:16] 正在重新加载站点设置...
[2019-07-16 20:08:16] 正在为非工作人员用户禁用外部邮件...
[2019-07-16 20:08:16] 正在清除表情符号缓存...
[2019-07-16 20:08:16] 正在禁用只读模式...
[2019-07-16 20:08:16] 正在清除主题缓存
[2019-07-16 20:08:22] 正在提取上传文件...
[2019-07-16 20:08:40] 正在将上传文件迁移到 S3...
[2019-07-16 20:08:46] 恢复进程已被取消!
[2019-07-16 20:08:46] 正在尝试回滚...
[2019-07-16 20:08:46] 正在回滚...
[2019-07-16 20:08:47] 正在清理内容...
[2019-07-16 20:08:47] 正在删除临时目录 '/var/www/discourse/tmp/restores/default/2019-07-16-200516'...
[2019-07-16 20:08:48] 正在取消暂停 sidekiq...
[2019-07-16 20:08:48] 正在将恢复标记为完成...

您的 S3 配置有问题吗?

在命令行中运行 discourse restore BACKUP_FILENAME 时,您是否看到更多输出?

我接下来会检查这个并汇报结果。谢谢。

以下是从命令行运行 discourse restore BACKUP_FILENAME 后的输出结果。欢迎提供任何反馈,谢谢!

正在禁用非管理员用户的出站邮件...

正在清除表情符号缓存...

正在禁用只读模式...

正在清除主题缓存

正在提取上传文件...

正在将上传文件迁移到 S3...

正在检查默认数据库是否已迁移...

9474 个上传文件中有 524 个未迁移到 S3。数据库 'default' 的 S3 迁移失败。

321 篇帖子未重新映射到新的 S3 上传 URL。数据库 'default' 的 S3 迁移失败。

正在查找 'default' 上缺失的上传文件

正在修复缺失的上传文件:

..........................................................................................................

缺失 116 个帖子上传文件。

缺失 116 个上传文件。

116 个中有 106 个是旧方案的上传文件。

83342 篇帖子中有 98 篇受到影响。

rake posts:missing_uploads 识别出 98 个问题。数据库 'default' 的 S3 迁移失败。

无需重新烘焙任何帖子

正在将上传文件迁移到 'default' 的 S3...

部分上传文件未迁移到新方案。请在 Rails 控制台中运行以下命令:

SiteSetting.migrate_to_new_scheme = true

Jobs::MigrateUploadScheme.new.execute(nil)

恢复过程已取消!

正在尝试回滚...

正在回滚...

正在清理临时数据...

正在删除临时目录 '/var/www/discourse/tmp/restores/default/2019-07-22-172918'...

正在恢复 Sidekiq...

正在将恢复标记为已完成...

正在通知 'system' 恢复已结束...

完成!

[失败]

恢复完成。

这是一个已知问题。我明天会修复它。

跟进此事,想确认修复是否已实施?谢谢!

不,问题尚未修复。但作为临时解决方案,您可以在创建备份之前暂时禁用 enable_s3_uploads 站点设置。

跟进针对此挑战的长期解决方案。谢谢!

这个问题最终解决了吗?我在尝试迁移到新服务器时也遇到了同样的问题。我打算试试这个变通方法。

这在一次相对较大的迁移中刚刚给我带来了麻烦。

我很确定我也遇到了这个问题,我认为这应该被标记为错误。
(如果情况不同,请随时将其移至新的独立主题)

恢复备份能否正常工作至关重要。


请注意,在使用管理界面并点击备份名称旁边的 <kbd>Restore</kbd> 时,失败的原因并不明显,你会看到:

...
正在将上传文件迁移到 S3...
恢复过程已取消!
...

通过命令行完成恢复会提供更详细的信息:

discourse enter app
discourse restore example-net-2020-01-02-033557-v20191219112000.tar.gz
...
正在重新连接数据库...
正在重新加载站点设置...
正在为普通用户禁用外部邮件...
正在清除表情符号缓存...
正在禁用只读模式...
正在清除主题缓存
正在解压上传文件...
正在重新映射上传文件...
正在将 '//forum-example-net.s3.dualstack.eu-west-2.amazonaws.com/' 重新映射为 '/uploads/default/'
optimized_images=3
uploads=1
正在将上传文件迁移到 S3...
正在检查默认数据库是否已迁移...
12 个上传文件中有 6 个未迁移到 S3。数据库 'default' 的 S3 迁移失败。
1 个帖子未重新映射到新的 S3 上传 URL。数据库 'default' 的 S3 迁移失败。
正在 default 中查找缺失的上传文件

0 个帖子上传文件缺失。
  请提供以下环境变量
    - DISCOURSE_S3_BUCKET
    - DISCOURSE_S3_REGION
    以及以下任一选项
    - DISCOURSE_S3_ACCESS_KEY_ID
    - DISCOURSE_S3_SECRET_ACCESS_KEY
    或
    - DISCOURSE_S3_USE_IAM_PROFILE
恢复过程已取消!
正在尝试回滚...
正在回滚...
正在清理...
从 discourse_functions 架构中删除函数
正在删除临时目录 '/var/www/discourse/tmp/restores/default/2020-01-06-222212'...
正在取消暂停 sidekiq...
正在标记恢复为已完成...
正在通知 'system' 恢复结束...
完成!
[FAILED]
恢复完成。

我在 uploads.rake 中“请提供以下环境变量”之前添加了一点调试代码来输出环境变量:

puts "ENV: " + ENV.inspect

ENV 中没有任何 DISCOURSE_S3_* 变量被设置。

是否有合理的理由导致它不从设置中获取这些数据?

我认为这种观点是:如果你将文件上传到 S3,那么只需进行仅包含数据库的备份,这样就不会因为缺少上传文件而导致备份失败。

完全同意,但这对你手头包含上传文件的备份并没有什么帮助。

说明一下——目前这对我来说并非关键问题,我可以注释掉出错的行并完成恢复,但其他人做不到。

同意。将所有上传迁移到 S3 是一项相当复杂的任务,并且需要 S3 CDN。

无需将其转换为 #bug。这已在我的处理范围内,我已经花费了大量时间重构恢复流程,增加了大量测试并提升了其可靠性。我还会再做几处调整,以降低恢复至 S3 时出错的概率,并在管理界面中输出更多信息。

据我所知,备份/恢复功能已经过重构,但我刚刚发现这仍然是一个问题。
在 beta11 上尝试恢复一个启用了 enable s3 uploads 的备份时,仍然失败,错误信息如下:

[2020-02-18 09:51:38] 正在恢复上传内容,这可能需要一些时间...
[2020-02-18 09:51:38] 异常:请提供以下环境变量:
  - DISCOURSE_S3_BUCKET
  - DISCOURSE_S3_REGION
  以及以下任一选项:
  - DISCOURSE_S3_ACCESS_KEY_ID
  - DISCOURSE_S3_SECRET_ACCESS_KEY
  或
  - DISCOURSE_S3_USE_IAM_PROFILE

[2020-02-18 09:51:38] /var/www/discourse/lib/file_store/to_s3_migration.rb:34:in `s3_options_from_env'

所以数据库中启用了 S3 上传,但未启用 S3 备份?

正确,这涉及上传迁移问题。

S3 访问凭据已存在于恢复的数据库中,因此无需再将其设置为环境变量。

提供环境变量同样会导致失败:

正在恢复上传内容,这可能需要一些时间...
正在检查 db8015 是否已迁移...
200 个上传内容中的 206 个尚未迁移到 S3。S3 迁移失败,数据库为 'db8015'。
5 篇帖子尚未重新映射到新的 S3 上传 URL。S3 迁移失败,数据库为 'db8015'。
没有帖子需要重新烘焙。
正在将 'db8015' 的上传内容迁移到 S3...
正在上传文件到 S3...
 - 列出本地文件
 => 21 个文件
 - 列出 S3 文件
. => 16 个文件
 - 将文件同步到 S3
.....................
正在更新数据库中的 URL...
正在删除旧的优化图片...
正在标记所有包含灯箱的帖子以进行重新烘焙...
5 篇帖子已被标记为需要重新烘焙
异常:206 个上传内容中的 183 个尚未迁移到 S3。S3 迁移失败,数据库为 'db8015'。
/var/www/discourse/lib/file_store/to_s3_migration.rb:127:in `raise_or_log'
/var/www/discourse/lib/file_store/to_s3_migration.rb:74:in `migration_successful?'
/var/www/discourse/lib/file_store/to_s3_migration.rb:350:in `migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:61:in `migrate'
/var/www/discourse/lib/file_store/s3_store.rb:203:in `copy_from'
/var/www/discourse/lib/backup_restore/uploads_restorer.rb:48:in `restore_uploads'
/var/www/discourse/lib/backup_restore/uploads_restorer.rb:30:in `restore'
/var/www/discourse/lib/backup_restore/restorer.rb:58:in `run'
script/discourse:143:in `restore'

我不清楚为什么会失败。

大多数上传内容 确实 已在 S3 上,因此“206 个上传内容中的 200 个尚未迁移到 S3”和“206 个上传内容中的 183 个尚未迁移到 S3”的说法是不正确的。本地文件数量为 21 是正确的,S3 上大约有 200 个上传内容(也可能是 206 个)。其他数字(183、16)我完全无法识别。

我也不明白为什么恢复过程试图将更多上传内容移动到 S3?它应该直接从备份中获取本地图片,并保留 S3 上的上传内容不变?还是我忽略了什么?

最终,我通过修改数据库转储中的 enable_s3_uploads 设置为 false 来绕过此问题,但这导致所有内容都被重新映射回本地。由于仍有少数图片是本地存储的,因此需要花费大量精力来区分哪些需要重新映射到 S3,哪些不需要。

以上问题均出现在 2.4.0 beta11 版本上。

不支持将本地上传与存储在 S3 上的上传混合使用。是的,我们知道,当有人从本地上传切换到 S3 但未将现有上传迁移到 S3 时,可能会出现这种情况,但这又是另一个故事了……

恢复备份时,如果系统检测到任何会影响上传 URL 的更改,总会重新映射上传。这包括在独立站和多站点之间切换、在本地上传和 S3 之间切换,以及 S3 和 CDN 设置的更改。所有上传都会根据设置(本地或 S3)恢复到正确的位置。

我们偶尔会遇到因各种原因导致自动重新映射和迁移到 S3 失败的备份。预计在 2.5 开发周期的早期,您将看到更多改进。