关于“帖子未重新映射到新的S3上传URL”的误报

我正在将我们的 Discourse 实例从一个服务器迁移到另一个服务器,期间遇到了一个有趣的问题……

我们使用 S3 来存储论坛的上传文件。我们几年前就启用了这个功能,所以这并不是我们在这次迁移中引入的新东西。
在修复了其他几个问题后,我成功导入了备份。但是,它在一个与 S3 相关的步骤中失败了,错误信息如下:

正在更新数据库中的 URL...
正在删除旧的优化图像...
正在将所有包含灯箱的帖子标记为重新烘焙...
72038 个帖子被标记为重新烘焙
异常:257 个帖子未映射到新的 S3 上传 URL。数据库 'default' 的 S3 迁移失败。

经过一番排查,我将问题追溯到了这一行:

然后,我进入了 rails 控制台,并使用以下命令重现了查询:

discourse(prod)> SiteSetting.cdn_path("/uploads/#{@current_db}/original").sub(/https?:/, "")
=> "/uploads//original"
discourse(prod)> RailsMultisite::ConnectionManagement.current_db
=> "default"
discourse(prod)> cdn_path = SiteSetting.cdn_path("/uploads/default/original").sub(/https?:/, "")
=> "/uploads/default/original"
discourse(prod)> Post.where("cooked LIKE '%#{cdn_path}%'")
=> ...

然后,我查看了那些特定的帖子,它们是性能报告的一部分(截图是我运行了一个查找和替换脚本之后):

显然,这个检查检索了在 cooked 字段中包含 /uploads/default/original 的任何帖子,尽管它可能不是一个合法的资源。在这种情况下,/uploads/default/original 被用作“纯文本”,因此在迁移作业中没有被遗漏。

不确定这是否是预期的行为?
谢谢!

我见过类似已处理帖子的issue,我认为。

也许你可以只做数据库恢复,然后它会跳过那些检查。

那是我接下来会尝试的。

我通过简单地替换掉那些帖子中的文本,使其与过滤器不匹配,从而完全恢复了它。对我来说这不是问题,但提出来是为了以防有人遇到同样的问题,因为也许值得在 Discourse 中修复它。

2 个赞

是的。也许代码就不应该检查已烹饪的文章。

1 个赞

我也很确定在尝试恢复备份时遇到了同样的问题,并且我创建备份时将“包含上传”选项设置为禁用(DISABLED)。数据库单独恢复是不是还有我遗漏的地方?

我是 Discourse 的新手,所以会尝试找出解决方法,但我认为,如果对于使用 S3 存储桶(S3 buckets)作为上传存储的用户来说,备份/恢复无法正常工作,那么这似乎是更优先处理的事项。

这是我尝试恢复的日志文件。

[2025-06-22 16:02:24] /var/www/discourse/lib/file_store/to_s3_migration.rb:132:in `raise_or_log'
/var/www/discourse/lib/file_store/to_s3_migration.rb:81:in `migration_successful?'
/var/www/discourse/lib/file_store/to_s3_migration.rb:385:in `migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:59:in `migrate'
/var/www/discourse/lib/file_store/s3_store.rb:352:in `copy_from'
/var/www/discourse/lib/backup_restore/uploads_restorer.rb:69:in `restore_uploads'
/var/www/discourse/lib/backup_restore/uploads_restorer.rb:49:in `restore'
/var/www/discourse/lib/backup_restore/restorer.rb:167:in `restore_uploads'
/var/www/discourse/lib/backup_restore/restorer.rb:71:in `run'
/var/www/discourse/script/spawn_backup_restore.rb:20:in `restore'
/var/www/discourse/script/spawn_backup_restore.rb:33:in `block in 
/var/www/discourse/script/spawn_backup_restore.rb:4:in `fork'
/var/www/discourse/script/spawn_backup_restore.rb:4:in `
[2025-06-22 16:02:24] Trying to rollback...

关于我的具体情况的更新……尽管我已经切换到S3进行存储,但我的 /var/discourse/shared/standalone/uploads 中仍然有文件。一旦我删除了该 uploads 目录中的 默认 目录,然后重新创建了一个备份,它就成功地创建了一个仅数据库的备份(…sql.gz)。

出于某种原因(在我的情况下),如果该目录中有文件,它就会忽略“不在备份中包含上传文件”的设置,并照常创建它们。

如果我的情况需要更多信息或澄清,请告诉我。看起来这可能与楼主的情况略有不同。

无论如何,我都设法绕过了这个问题,现在可以成功恢复了。