S3移行の失敗により復元に失敗しました

私たちは独自に Discourse データベースをホストしており、新しいサーバーへの移行を試みています。

両側(旧サーバーと新サーバー)は最新の Discourse に更新されています(両側で数分間隔を空けてアプリの再構築が行われました)。また、数日前に旧サーバーで新しい PostgreSQL への移行が成功裡に完了しています。これらの要因が問題の原因である可能性は低いと考えられます。

すべてのアップロードは S3 互換のオブジェクトストレージ(Digitalocean Spaces)に保存されているため、理論的には移行は簡単に行えるはずです。「投稿とカテゴリ」の復元が正しく行われれば、S3 アップロードへのリンクもそのまま機能するだろうと考えました。

しかし、それは誤りでした。新サーバーでバックアップの復元を実行すると、「投稿」部分は100%正常に完了しますが、その後 S3 部分で失敗します。

以下が私たちが遭遇したエラーです。

Reconnecting to the database...
Reloading site settings...
Disabling outgoing emails for non-staff users...
Running seed fu...
Disabling readonly mode...
Clearing category cache...
Reloading translations...
Remapping uploads...
Restoring uploads, this may take a while...
Migrating uploads to S3 for 'default'...
Uploading files to S3...
 - Listing local files
 => 3 files
 - Listing S3 files
..................................................................................................................................................... => 148892 files
 - Syncing files to S3
...
Updating the URLs in the database...
Removing old optimized images...
Flagging all posts containing lightboxes for rebake...
29368 posts were flagged for a rebake
EXCEPTION: rake posts:missing_uploads identified 2274 issues. S3 migration failed for db 'default'.
/var/www/discourse/lib/file_store/to_s3_migration.rb:132:in 'FileStore::ToS3Migration#raise_or_log'
/var/www/discourse/lib/file_store/to_s3_migration.rb:104:in 'FileStore::ToS3Migration#migration_successful?'
/var/www/discourse/lib/file_store/to_s3_migration.rb:384:in 'FileStore::ToS3Migration#migrate_to_s3'
/var/www/discourse/lib/file_store/to_s3_migration.rb:59:in 'FileStore::ToS3Migration#migrate'
/var/www/discourse/lib/file_store/s3_store.rb:372:in 'FileStore::S3Store#copy_from'
/var/www/discourse/lib/backup_restore/uploads_restorer.rb:69:in 'BackupRestore::UploadsRestorer#restore_uploads'
/var/www/discourse/lib/backup_restore/uploads_restorer.rb:49:in 'BackupRestore::UploadsRestorer#restore'
/var/www/discourse/lib/backup_restore/restorer.rb:179:in 'BackupRestore::Restorer#restore_uploads'
/var/www/discourse/lib/backup_restore/restorer.rb:72:in 'BackupRestore::Restorer#run'
script/discourse:242:in 'DiscourseCLI#restore'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/thor-1.5.0/lib/thor/command.rb:28:in 'Thor::Command#run'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/thor-1.5.0/lib/thor/invocation.rb:127:in 'Thor::Invocation#invoke_command'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/thor-1.5.0/lib/thor.rb:538:in 'Thor.dispatch'
/var/www/discourse/vendor/bundle/ruby/3.4.0/gems/thor-1.5.0/lib/thor/base.rb:585:in 'Thor::Base::ClassMethods#start'
script/discourse:396:in '<top (required)>'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli/exec.rb:61:in 'Kernel.load'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli/exec.rb:61:in 'Bundler::CLI::Exec#kernel_load'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli/exec.rb:24:in 'Bundler::CLI::Exec#run'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli.rb:504:in 'Bundler::CLI#exec'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/vendor/thor/lib/thor/command.rb:28:in 'Bundler::Thor::Command#run'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in 'Bundler::Thor::Invocation#invoke_command'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/vendor/thor/lib/thor.rb:538:in 'Bundler::Thor.dispatch'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli.rb:35:in 'Bundler::CLI.dispatch'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/vendor/thor/lib/thor/base.rb:584:in 'Bundler::Thor::Base::ClassMethods#start'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/cli.rb:29:in 'Bundler::CLI.start'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/exe/bundle:28:in 'block in <top (required)>'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/lib/bundler/friendly_errors.rb:118:in 'Bundler.with_friendly_errors'
/usr/local/lib/ruby/gems/3.4.0/gems/bundler-4.0.11/exe/bundle:20:in '<top (required)>'
/usr/local/bin/bundle:25:in 'Kernel#load'
/usr/local/bin/bundle:25:in '<main>'
Trying to rollback...
Rolling back...
Cleaning stuff up...
Dropping functions from the discourse_functions schema...
Removing tmp '/var/www/discourse/tmp/restores/default/2026-08-11-075958' directory...
Unpausing sidekiq...
Marking restore as finished...
Notifying 'system' of the end of the restore...
Finished!
[FAILED]
Restore done.

いくつか質問があります。

  • データベースに保存されている S3 環境のセットアップが変更されていないはずなのに、なぜ失敗するのでしょうか?
  • なぜクラッシュするのではなく、アップロードで発見された2274件の問題のリストを作成し、私が何らかの形で処理できるようにしてくれないのでしょうか?
  • なぜ自動的に空のデータベースにロールバックして、私を途方に暮れさせるのでしょうか?
  • 移行を成功させる、あるいは少なくともロールバックしないようにして、発見されたアップロードの問題を私が処理できるように、介入する方法はあるのでしょうか?

ご協力いただき、誠にありがとうございます。