@RGJ 同感です。もし誰かが、すべての画像を再構築するという無駄な作業を避ける方法を確信を持って知っているなら、ぜひとも賛成します。もし私が経験豊富な Discourse 開発者で、それを簡単にできる方法を知っていたなら、最初からそうしていたでしょう。
私の推測では、S3 からの移行は、大量の画像を抱えているユーザーにとって一般的なケースではないため、Discourse により汎用的に役立つ機能を追加する作業に比べて、その価値に見合わない時間がかかるのではないかと思っています。Google+ から MakerForums へ移行した際、約 100GB のアップロードデータがありましたが、多くのユーザーがそれらのコミュニティから MakerForums へ移行する可能性があるという考えから S3 を選択しました。しかし、結局のところ、積極的に移行したコミュニティは数個に留まり、成長が S3 への継続を正当化するほどではなかったのです。これはかなり極端な例外事例だと思われますし、画像の再処理は一度きりのコストです。
最後に、このトピックを立ち上げてくださったことに心から感謝します。そうしていなければ、投稿以外のアップロードを見逃していた可能性が非常に高かったからです。
…
@RGJ 削除して再作成する方法が良くないことは明らかにおっしゃる通りです。私は raise "Error: upload url #{url} changed to #{new_upload.short_url}, should be unchanged." if url != new_upload.short_url というチェックを追加しました。これにより、破損したソースの問題を少なくとも報告できるようになりました。今日の Digital Ocean Spaces の障害により、破損したデータが送信され、多くのアップロードでこのエラーがトリガーされました。正確な数はわかりません。しかし、古いアップロードをすでに削除していたため、現在いくつかのページが破損してしまっています。また、どのページが破損しているかを示すログを含むスクロールバックを失うまでそれに気づかず、バックアップから手動で修正することもできません。
したがって、私の作業は少なくともいくつかのエラーを報告する点で旧方式よりも改善されていますが、ファイルをダウンロードし、ダウンロードしたファイルの SHA1 を確認してからローカルファイルに書き込む方がはるかに良いでしょう。当面の間、私の PR を修正して、未処理のエラーが発生した場合にマイグレーションを停止するように変更し、データ損失を少なくとも制限するようにしました。
私の作業は、状況を悪化させることなく改善する「パレート改善」であるため、マージされるべきだと考えていますが、正しい方法で行う方がはるかに良いはずです。それは、lib/file_store/from_s3_migration.rb を lib/file_store/to_s3_migration.rb と並行して作成することだと考えられますが、私はその能力が不足しています。
私の PR がまだレビューされていないため、さらに多くの機能を追加しました。uploads:report_missing_uploads タスクを追加し、raw 内の upload://... のインスタンスで、アップロードオブジェクトが存在しないものを検索するようにしました。少なくとも私の場合、バックアップがあるため、バックアップを調べて孤立したファイルを見つけ、サイトを復元し、その後該当する投稿を再焼成して失われた画像を復元できます。バックアップ内で検索すべき 678 個のファイルを見つけましたが、そのうち 10 個を除くすべてを既に発見しました。テストを作成してよかったと思います。残りの投稿を再焼成するフェーズに入る前に、これを処理する必要があります。
…
共有アップロードを持つ投稿の再焼成と、投稿以外のアップロードを含めない状態で、マイグレーションの最初のフェーズを完了しました。別のリモートバックアップを完了した後、これらの機能もテストし、PR に追加する予定です。
…
現在、マイグレーションの次のフェーズ、つまり再焼成と投稿以外のアップロードの移行のテストを開始しました。最初の教訓は、共有アップロードを持つ投稿の再焼成を次のステップとして行うと、引用された投稿内の投稿以外のアップロード(アバターなど)のために失敗するため、投稿の再焼成は最後のステップにする必要があるということです。
次の発見:外部キー制約に感謝します!投稿以外のアップロードを移行している際、一般的に投稿以外のアップロードを移行する前に、少なくともプロフィールを移行する必要があることに気づきました。
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: update or delete on table "uploads" violates foreign key constraint "fk_rails_1d362f2e97" on table "user_profiles"
プロフィールの移行は複雑でした。プロフィールに添付された 2 つのアップロードを移行する必要がありましたが、場合によっては同じ画像を両方に使用していたため、この作業を 3 つの段階で行う必要がありました。私のサイト上のすべてのプロフィールを S3 URL で正常に移行しました。
投稿およびプロフィール以外のすべてのアップロードを移行しました。@RGJ 氏、私が公開したブランチを試してみたい場合は、最新の私の作業が含まれています。これに含まれるすべての機能は、既に完了したサイト移行で使用されています。
…
@cvx 氏、レビューの機会がいつになるかはわかりませんが、私の PR がなければ、migrate_from_s3 には確実に サイレントなデータ破壊バグ が満載です。私が行ったことは完璧ではありませんが、実際に遭遇した多くのバグから保護してくれます。
現時点で私が行う予定だった作業はすべて完了しました。私のサイトを移行してしまったため、要求された変更を効果的に評価することもできなくなりました。もしこの PR が却下されるなら、既存のマイグレーションを削除することを強く推奨します。なぜなら、それはユーザーのデータを サイレントに破壊する からです。
PR に関しては、現在のバージョンでは CI でテスト失敗が発生することがあります。
7867 examples, 0 failures, 11 pending, 1 error occurred outside of examples
##[error]Process completed with exit code 1.
これはローカルでは再現していません(今のところ)、また CI ログには CI で何が間違っているかを示す情報もありません。そのため、隠れた情報を発見するために CI 出力をいじることに時間を無駄にするつもりはありません。
最後に一点:マイグレーション完了後、いくつかのユーザーのプロフィール画像が移行中に失われ、手動で復元していることがわかりました。これを成功させるには追加のコードが必要だったと思われますが、それが遅すぎるまで気づかなかったため、これを検証するテストケースを持っていません。したがって、これは特定の構成で問題を引き起こす可能性のある残存バグですが、私はもはやその追加の修正を書く立場にはありません。