Discourse 迁移服务器恢复数据失败

由于服务器到期,需要迁移到新的服务器,我先备份了discourse数据
把app.yml同步到新服务器,然后在新服务器

./launcher rebuild app

然后把备份数据上传到新服务器的/var/discourse/shared/standalone/backups/default
使用命令

./launcher enter app
discourse enable_restore
discourse restore xxxxxxxxxxxxxxxxxxxxx.tar.gz

恢复失败,我重建新的discourse后从后台进行恢复还是失败,附件是恢复日志

log.txt (124.0 KB)

我先看一下恢复日志里真正报错的位置。
Discourse 恢复日志通常前面噪音很多,关键是第一个异常和它前后的 SQL/插件信息。

日志里数据库导入阶段看起来已经走过去了,挂在 “Restoring uploads” 上传文件恢复阶段。错误来自 AWS S3 SDK:You can only specify one non-default checksum at a time. 我再把前后上下文捞出来,确认它是在还原到对象存储时触发的。

看日志,失败点很明确:数据库已经恢复成功,挂在恢复上传文件到 S3/对象存储这一步

关键报错是:

Restoring uploads, this may take a while...
EXCEPTION: You can only specify one non-default checksum at a time.
...
Aws::S3::Client#put_object
/var/www/discourse/lib/file_store/to_s3_migration.rb

而且日志里显示:

Current version: 20260505161704
Restored version: 20260505161704

所以这不是 Discourse 版本不一致导致的。

原因
新服务器的 Discourse 配了 S3 或 S3 兼容对象存储,恢复时 Discourse 想把备份里的 uploads 上传到对象存储。但新版 AWS Ruby SDK 默认会带 checksum,一些 S3 兼容服务,比如 Backblaze B2、部分 MinIO、部分兼容 S3 服务,会因为 checksum 头冲突报:

You can only specify one non-default checksum at a time

Discourse Meta 上也有同类问题,推荐加这两个环境变量;AWS 文档也说明新版 SDK 默认 checksum 行为可以通过 AWS_REQUEST_CHECKSUM_CALCULATION / AWS_RESPONSE_CHECKSUM_VALIDATION 调整。

/var/discourse/containers/app.yml 的 env: 下面加:

 AWS_REQUEST_CHECKSUM_CALCULATION: WHEN_REQUIRED
 AWS_RESPONSE_CHECKSUM_VALIDATION: WHEN_REQUIRED

然后执行:

cd /var/discourse

./launcher rebuild app

./launcher enter app

discourse enable_restore

discourse restore xxxxxxxxxxxxxxxxxxxxx.tar.gz

如果是 Cloudflare R2,要特别注意:Discourse 官方文档里目前仍把 Cloudflare R2 标为不兼容,最好换 AWS S3、DigitalOcean Spaces、Linode Object Storage、Backblaze B2、MinIO 等已知可用方案。

临时绕过方案:如果暂时不需要对象存储,可以先在 app.yml 里禁用 S3,重建后把站点恢复到本地 uploads,确认论坛起来后,再修 S3 配置并迁移 uploads。

参考:
Discourse S3 compatible storage 文档
Discourse 同类 checksum 修复讨论
AWS SDK S3 checksum 配置说明

我试下这个方法看

这个方法还是不行哦。

现在的问题是我旧服务器已经停机了,我只有app.yml和备份的数据文件里。

我们有过一个 S3 类似的问题:Discoruse 恢复踩坑记 S3

不过我们这个问题和你的问题不太一样,你的问题应该是校验码的问题,我们的问题曾经是无法恢复附件的问题。

记得在恢复之前需要有一个 启用S3上传附件 的配置,要把这个禁用,然后备份一个新的备份包,这样的恢复是通常没有问题的。

看你现在你的老服务器已经删掉了,这个办法可能没有办法再重新创建一个新的备份包。

我觉得可以另外采取个办法,就是进入打包文件,因为打包文件中的数据库文件和附件是单独存的,先用 PGSQL 的数据库恢复文件,把这个数据库先恢复了。

还有一个提示,就是在没有完全恢复到新机器之前,不要把老的服务器删掉

因为你可能还需要老的服务器帮你创建不同的备份包。

现在我把数据库恢复了,但是附件都无法恢复了,rake uploads:migrate_to_s3就报错,再研究研究。

挺复杂的。