こんにちは。
最近、2021年(だったと思います)にサーバーにインストールされ、主に他の誰かが更新していた基本的なDiscourse Dockerイメージインスタンスの最後の管理者兼メンテナーになりました。当初から、ソフト削除された投稿からのアップロードが孤立して削除されないという問題が発生しており、不要なファイルが積み重なってストレージ容量を無駄にしているため、数日間この問題のトラブルシューティングを試みています。S3は使用しておらず、実際に保持したいアップロードには十分なストレージがあります。
公式のDiscourse Dockerインストールガイドに従って、アップロードを含む完全なDiscourseバックアップファイルを別のステージングサーバーに移行し、app.ymlを再構築してから、コマンドラインからバックアップを復元しました。どちらのインストールも同様に正常に実行されており、他に明らかな問題はありませんが、アップロードの問題は残っています。
ログから関連するエラーを見つけることができず、Sidekiqはスケジュールどおりにクリーンアップジョブを実行しています。ステージングバージョンで rake db:migrate を実行し、何度も再構築し、投稿を完全に削除して設定を確認しました。Railsコンソールから直接投稿を完全に削除し、クリーンアップジョブを手動で実行しようとしたところ、一時的に墓石ディレクトリがわずかに大きくなり、もともとファイルがいくつかあったため、状況によってはメカニズムが機能していたはずですよね?わずかなサイズの増加から判断すると、ほとんどの不要なファイルはまだ孤立していると検出されていません。
現在関連する管理者パネルの設定を以下に示します。テストのために猶予期間を効果的にスキップするために、最後のものを0に設定できますか?
アップロードのクリーンアップ = true
孤立したアップロードのクリーンアップ猶予期間(時間) = 1
削除されたアップロードのパージ猶予期間(日) = 1
効率的にトラブルシューティングするにはどうすればよいですか? コマンドラインには慣れていますが、データベースのスキルは初歩的なので、現時点で何を探しているのかわからないまま、すべての可能なサーバー設定の詳細を確認することを避けるために、いくつかヒントをいただけると幸いです。
似たようなケースについて、このフォーラムを必死に検索して読んできましたが、ケースは少なく、それらのスレッドは行き止まりか、単一ファイルの План Б ソリューションで終わっており、このユースケースには直接適していません。
必要に応じて詳細をお知らせください。この問題を完全に解決するために最善を尽くしています。
「いいね!」 3
こんにちは、@Uphill4721 さん、ようこそ:slight_smile:
もし私の記憶が正しければ、これらのトピックに関連情報があると思います。
「いいね!」 1
迅速なご対応ありがとうございます!
これらのトピックや、それらにリンクされているいくつかのトピックは、この問題を解決しようとしている間にかなり馴染み深いものになりましたが、残念ながらこの問題に対する決定的な解決策は提供されていません。
昨日、ステージングサーバーで、9日以上前に削除されたトピックや投稿用に変更された次のコマンドを実行しました。
その後、墓石ディレクトリのコンテンツサイズがわずかに増加したことに気づき、猶予期間のため状況を引き続き監視しています。テスト中に待機時間を回避するために、関連する設定をゼロ時間/日に変更できるかどうか疑問に思っています。
以前、元のサーバーで最新の投稿リビジョンからアップロードを削除しようとしましたが、ファイルは猶予期間後も利用可能でした。
この時点で、参照されていないトピック、その投稿、およびアップロードを1つでも完全に削除するための、動作する手動ソリューションを見つけられることを個人的に喜んでいますが、これは他のDiscourseを実行している人々にとって大きな問題となる可能性があります。管理パネルのクリーンアップ設定が説明どおりに効果的であると想定していますが、そうでないことに気づかず、実際には削除されると予想されていた機密性の高いアップロードがファイルシステムに残ってしまう可能性があります。私たちの問題は幸いにも無駄になったストレージのみを考慮していますが、他の人にとってはもっと悪い可能性があります。
2ヶ月前にも同様の言及があります。
それで、これが私たちの設定ミスなのか、それとも実際のバグなのかを判断するためのヒントはありますか?それ以外はDiscourseに非常に満足しており、これを解決し、他の人を助けることに非常に意欲的です。
「いいね!」 1
これは純粋に推測ですが、投稿、post_upload、uploadモデルを簡単に確認すると、次のような方法で孤立したアップロード(データベースオブジェクト)があるかどうかを確認できる可能性があります。
Upload.find_by_sql("select * from uploads where id in (select upload_id from post_uploads where post_id not in (select id from posts))")
これはテストしていないため、孤立したアップロードを正しく見つけられるか、エラーなしで実行できるかはわかりません。もしそれがそのまま機能せず、他の誰かが機能させることができる可能性がある場合、また単に興味のある他の人のために、意図を説明します。
Upload.find_by_sql() は、提供されたSQLクエリに一致するUploadオブジェクトのコレクションを返します。
(select id from posts) は、既存のすべての投稿のIDを取得します。
(select upload_id from post_uploads where post_id not in () は、対応する投稿が存在しないpost_uploadsのすべてのIDを取得します。
select * from uploads where id in () は、それらのpost_uploads IDに一致するすべてのアップロードを取得します。
ただし、これは調査の可能性のある経路の1つにすぎません。残念ながら、アップロードシステムについてはあまり詳しくないので、それ以外に貢献できることはあまりありません。上記は明らかにすべての状況を考慮しているわけではないことを付け加えることくらいです。編集された投稿(削除されたのではなく)が明白な例です。
また、ユーザーアップロードのような、考慮されていない他の種類のアップロードもあります。これは、プロフィール写真のアップロードなどのものだと推測されます。
プラグインもアップロードを作成して保持することができます。たとえばプラグインが削除された場合にどうなるかはわかりません。プラグインデータはプラグインが削除された後もデータベースに残ると考えられるため、その場合、そのプラグインによって作成されたアップロードが削除されることはない可能性があります。
「いいね!」 4
返信ありがとうございます!
クエリは機能しますが、アップロードとその詳細は2つしか表示されません。孤児の基準に一致するアップロードは数百または数千件あるはずです。そのほとんどは、通常の投稿を作成する際にユーザーが元々アップロードした画像ファイルです。
現在、公式プラグインのみを使用しています。
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/docker_manager.git
- git clone https://github.com/discourse/discourse-chat-integration.git
- git clone https://github.com/discourse/discourse-prometheus.git
- git clone https://github.com/discourse/discourse-bbcode-color
- git clone https://github.com/discourse/discourse-data-explorer
元のインストールからしばらくして、アップロードプロセスに関する何らかのオーバーホールがあったようですが、これが私たちの状況に関連している可能性はありますか?A new era for file uploads in Discourse
ステージングサーバーでは猶予期間はすでに過ぎているはずですが、アップロードディレクトリのサイズに影響はなく、テストファイルはまだ利用可能です。次に何を調べるべきでしょうか?これは、ファイルシステムの権限に問題があることが原因である可能性はありますか?確認する簡単な方法はありますか?具体的なターゲットのアイデアが尽きてきました。他のすべては順調に動作しており、これが現在抱えている唯一の問題です。
類似のトピックを調べて、一致する可能性のある未解決のケースを収集しています。これは、ユーザーがアップロードしたファイルが孤立して削除されるべきときに永久に削除されないために、法的な問題さえ引き起こす可能性のある状況の良い例です。
2016年からの同様の状況の別の例です。
このような状況は、管理者が削除されると考えていても、サーバーから永久に削除されない可能性のある不正なコンテンツのアップロードに対して、悪用や標的攻撃の大きな機会を生み出します。もちろん、ファイルシステムから個々のファイルを直接手動で削除することは可能ですが、特に自動パージプロセスを示すGUI設定があり、モデレーターがサーバーに直接アクセスできない場合が多いことを考えると、このような基本的なニーズのためにユーザーがそのルートを取ることを強制されるべきではないと思います。また、削除されたトピックに散在する大量のファイルを手動で削除することは現実的ではありません。
これは実際のバグレポートの根拠として十分でしょうか? まだ私たちの設定ミスである可能性を排除していませんが、エラーメッセージの欠如と、すべてが正常に機能しているように見えることに困惑しています。トラブルシューティングとテストに多くの時間を費やし、その過程でDiscourseとそのコンポーネントに関する知識を深めてきました。そのため、ガイダンスがあれば、この奇妙な動作を引き起こしているエッジケースの詳細を特定するのに役立つ可能性があると思います。この時点で@zogstripさんにpingしても大丈夫でしょうか?
一時的な解決策として、すべてのアップロードを手動で墓石ディレクトリに移動し、アップロード回復方法を使用して、孤立していないファイルのみを正しいディレクトリに復元することは可能ですか?今日これを試みましたが、rake uploads:recover_from_tombstone はファイルを復元しませんでした。これは、アップロードのデータベースエントリに関するより大きな問題を示している可能性がありますか?
groove6j
(kilometrs)
7
こんにちは。私も同じか似たような問題に直面していますが、ファイルが削除されない理由がわかりません。他にこの問題を抱えている人はいますか?
SQLクエリを実行したところ、「スタック」しているアップロード参照はすべて下書きのようですが、私や他のユーザーの下書きを確認しましたが、ありません。下書きテーブルは空です。
孤児クリーニングは有効になっており、設定は可能な限り迅速に孤児を削除するように設定されています。
SQLクエリを添付しました。
SELECT
uploads.original_filename,
ROUND(uploads.filesize / 1000000.0, 2) AS size_in_mb,
uploads.extension,
uploads.created_at,
uploads.url,
upload_references.upload_id,
upload_references.target_id,
upload_references.target_type,
upload_references.created_at,
upload_references.updated_at
FROM upload_references
JOIN uploads ON uploads.id = upload_references.upload_id
ORDER BY uploads.filesize DESC
LIMIT 250
sql.csv (46.1 KB)
これは、フォーラムをインストールしてから発生しています。カスタムテーマやプラグインがインストールされていなかったときでもです。
最初にアップロードしたファイルである古いフォーラムロゴを数回アップロードしましたが、それも下書きとして参照されており、アップロードフォルダに残っています。
理論的には、すべてのアップロード参照をフィルタリングし、target_typeで下書きをフィルタリングしてから、データベースから削除できます…そして、sidekiqタスクにクリーンアップを処理させることができます(合っていますか?)
しかし、自己ホスト型のインスタンスを使用しており、Discourseにはかなり慣れていないため、ここで質問する方が良いでしょう…
それは回避策になりますが、それでも質問があります-なぜこれが起こっているのですか?
誰かが提案を持っていることを願っています。ディスク容量が指数関数的に増加しています:smile:
「いいね!」 1
はい、私たちもこの問題を抱えています。
なんとか解決したいのですが、私たちのフォーラムでは多くのアップロードがあり、そのうちごく一部しか長期保存する必要がないため、多くのディスク容量が無駄になっています。トラブルシューティングの提案をいただけると幸いです。
これが実用的であれば、一時的な解決策として興味があります。
groove6j
(kilometrs)
9
フォーラムを2週間前にインストールしましたが、最初からこの問題が発生しています。バグのようです。
同じSQLクエリを実行して、たくさんの「下書き」参照がスタックしていないか確認していただけますか?数十個あるのに、下書きテーブルには実際のドラフトが2、3個しかないように見えます。編集後に削除されないバグのようで(下書きではなくなり、例えば投稿が編集されるたびにデータベースに参照が残る)、これは簡単に見つけられます。
データベースから参照エントリを削除する方法と、まず1つのファイルの参照を削除してから、クリーンアップタスクが機能するかどうかを確認する方法を理解する必要があります。
これがどれほど安全かはわかりませんが、これらの無数の下書きエントリは私には間違っているように思えます。
スタッフ/開発者にログを提供できますが、私はDiscourseに慣れておらず、どのログファイルが役立つかわかりません。
編集:
データベース構造を理解しようとしていますが、重要なDBリレーションを見逃したくないので、これらのアップロードエントリを問題なく削除できますか?また、draft_sequencesが具体的に何であるかも理解できません。
しかし、テストするには、本番フォーラムをローカルVMに複製する必要があります…
もう一つの関連トピックですが、このトピックに気づかず投稿してしまいました。
画像を自動的に削除する唯一の方法は、削除する前に手動で投稿から編集して削除することだと思います。しかし、それが機能するかどうかは完全にはわかりません。アップロードの削除に関しては、あなたと同じ設定を使用していますが(S3互換ストレージを使用)、その画像を含む唯一の投稿(同じ画像が複数の投稿に含まれる可能性があり、おそらくアバターやユーザーバナーも同様です)が削除された場合、画像が決して削除されないことも確認できます。
これは、RGJ氏が提供した、画像が追加の投稿で使用されているかどうかを検索するためのソリューションです。
これが自動的に行われると非常に便利だと思います。特に、Discourseは多くの投稿が同じ画像を使用する場合に重複ファイルを防ぐなど、画像をスマートに処理するためです。一方で、多く使用されている個々の画像を削除するのは非常に手間がかかります。
以前、誰かが複数のアカウントで緊急に削除する必要のあるコンテンツをスパム送信してきたことがあり、すべてを完全に削除すること(元のファイル、最適化されたファイル、CDNキャッシュ、投稿、アバター、ユーザーバナーなど)を確認するのが非常にストレスでした。
これは非常に役立つと思うので、機能提案を作成しました。これが実装され、削除された投稿に含まれるコンテンツを自動的にパージできるようになれば、すべてのケースがカバーされ、SSHアクセスなしで処理できると思います。
「いいね!」 1