ToS3MigrationError: アップロードがS3に移行されず、添付ファイルが破損しています。このエラーを修正するにはどうすればよいですか?

FileStore::ToS3MigrationError: アップロード 21512 件中 182 件が S3 に移行されていません。データベース ‘default’ での S3 移行に失敗しました。

その後、‘raise_or_log’、‘migration_successful?’、‘migrate_to_s3’、‘migrate’、‘block in migrate_to_s3_all_sites’ からのスタックトレースが表示されました。

タスク uploads:migrate_to_s3 を実行した際、このエラーが 2 回発生しました。ファイルの約 1% が正常に移行されなかったため、リベイク後にサイト上の添付ファイルが破損しました。これらはすべて、Discourse インスタンスを最初に作成した最初の数ヶ月頃の古いファイルのようです。

S3 バケットを調査したところ、ファイルは確かに S3 に正常にアップロードされているようですが、リベイク後に正しくリンクされていないようです。


ある理由により、移行を再実行する(次のリベイクの前に行う)ことで問題が解決したようです。migrate_to_s3 タスク中は同じエラーが発生し続けます。

ただし、再度リベイクを実行すると、添付ファイルのリンクが再び破損してしまいます。

これらはエラーではないと思いますが、リベイク中の出力を含めておきます。

/var/www/discourse/lib/file_store/base_store.rb:6: warning: already initialized constant FileStore::BaseStore::UPLOAD_PATH_REGEX
/var/www/discourse/lib/file_store/base_store.rb:6: warning: previously definition of UPLOAD_PATH_REGEX was here
/var/www/discourse/lib/file_store/base_store.rb:7: warning: already initialized constant FileStore::BaseStore::OPTIMIZED_IMAGE_PATH_REGEX
/var/www/discourse/lib/file_store/base_store.rb:7: warning: previous definition of OPTIMIZED_IMAGE_PATH_REGEX was here

rake posts:missing_uploads または PostCustomField.where(name: Post::MISSING_UPLOADS) を実行しても問題は見つかりませんでしたので、これは無関係のようです。

私の問題は、こちらのトピックに関連している可能性があります:Migrate_to_S3 Fails on Rebake - #12 by evenif

そこで得た情報に基づき、このトピックをクローズして、会話をそちらに移すかもしれません。

壊れた添付ファイルやアップロードは、投稿の生テキストでは [{ファイル名}|attachment](/uploads/default/original/2X/6/{SHA1 ハッシュ + 拡張子}) のように表示されます。これが href="/uploads/default/original/2X/6/{SHA1 ハッシュ + 拡張子}" として処理されるため、画像は表示されますが、ファイル添付は機能しなくなります。

その後、正常に動作する添付ファイルは [{ファイル名}|attachment](upload://{SHA1 を Base62 変換した値 + 拡張子}) のように表示され、href="/uploads/short-url/{SHA1 を Base62 変換した値 + 拡張子}" として処理されます。

私は問題が発生した期間のすべての投稿をスキャンし、古いアップロード URL を新しい形式に置換する小さな Ruby コードを作成しました。その際、Upload モデルの base62_sha1 関数を使用して、SHA1 ハッシュを Discourse のショート URL が期待するファイル名形式に変換しました。

これにより添付ファイルが機能するようになりました。その後、修正を確認するために再度リベイクを実行しましたが、問題なく動作しているようです。この問題の原因は Post.raw にあり、Upload には関係なかったようです。