復元後にアバターが消失しました。復元方法は?

ariznaf さん、おはようございます。

その結論に至る前に、すべてのインストール先を確認し、それぞれのインストールの共有フォルダに移動して、以下のコマンドを実行して結果を返信してください。

# du -sh uploads

例えば、私たちのインストールでは、以下のように実行しました。

元のインストール:

# du -sh uploads
2.5G uploads

ソケットのみのインストール(問題を修正する前):

# du -sh uploads
444K uploads

これにより、uploads フォルダを手動でコピーする必要があるという手がかりを得ることができました。問題が分かれば、解決策は簡単です。

すべての共有ディレクトリにある uploads フォルダを du -sh uploads で確認することで、何が起きているのかに関する貴重な手がかりが得られます。

もし結果が異なれば、一部のアップロードデータが欠落していることが分かり、手動で修正できます。

もしすべて同じであれば(あり得ませんが)、問題はより興味深いものになります :slight_smile:

問題は見つかりました(解決策ではありません)。
問題自体は復元処理ではなく、サーバー名の変更にあります。

私がどのように復元を行ったか説明します(もし手順が不足している場合のために)。

GitHub から Discourse の最新コピーをダウンロードしました。
docker-setup プロセスを実行しました。
アプリを実行して復元に進む前に、socket アクセスを設定するために app.yml を編集しました。
そして、ホスト名を b.domain.com に変更しました(元は a.domain.com でした)。

SSL を使用して nginx リバースプロキシを設定し、443 番ポートの HTTPS トラフィックを Discourse socket に誘導しました。
その後、ビルドし直しました(launcher rebuild app)と nginx を再起動しました(service nginx restart)。
https://b.domain.com にアクセスして Discourse の初期設定を行いました。
S3 からの復元を設定し、データベースとアップロード(サムネイルなし)の最後のバックアップから復元しました。
復元後、ログアウトされます。
その後、古いサイトからの app.yml をコピーして設定とプラグインをそのまま引き継ぐために app.yml を編集しました。
app.yml 内のホスト名を b.domain.com に変更しました。

再度ビルドし直し、nginx を再起動しました。

問題は依然として続いています:プロフィール画像(ミニチュア)が、変更したすべてのユーザーの白いプロフィール画像に置き換わってしまいました。
左上隅にあるロゴも消えています。

@Stephen 氏、force_https はオンになっていました(問題のなかった元のサーバーと同じ設定です)。オンとオフを切り替えてみましたが、効果はありませんでした。https でアクセスできるようにしたいので、オンにしたままにしています(いずれにせよ、nginx 設定で http:80 のトラフィックは https:443 に恒久的にリダイレクトされています)。

@riking 氏、sidekiq を使用して avatarmissing ジョブをトリガーしました。これは数ミリ秒で正常に完了したように見えました。もし時間がかかる処理だった場合のために、プロフィール画像が再構築されるか確認するために約 24 時間待ちました。
しかし今日も同じ問題が発生しています:プロフィール画像をアップロードした人のアバター画像も、ロゴ画像も表示されません。

その後、@Stephen 氏の提案通り、問題が名前の変更にあるかどうかを確認してみました。

app.yml と nginx のホスト名を元の a.domain.com に戻し、ビルドし直し、nginx を再起動しました。
ローカルの hosts ファイルを編集して a.domain.com を新しいサーバーの IP アドレスに指し示し、ping を試して新しい IP にアクセスしていることを確認しました。

そして、なんと!アバターとプロフィールが表示されました。

つまり、問題は復元処理そのものではなく、URL の完全なパスがどこかに保存されており、間違った場所からアクセスしようとしていることにあります。
ただし、これは奇妙です。元のサーバーは稼働しているはずなので、間違った場所(新しいサーバーではなく元のサーバー)からでも画像が見つかるはずだからです。

とにかく、問題は復元プロセスや、何らかの破損により画像を再アップロードする必要があることではありません。
問題はサーバー名の変更です。

では、Discourse フォーラムをあるドメイン/ホスト名から別のものへ移行するにはどうすればよいのでしょうか?

ホスト名を b.domain.com に再度変更しようと試みましたが、うまくいきません。

古い名前のまま使用すると動作するようですが(ただし、hosts ファイルで a.domain.com の IP を変更したにもかかわらず、まだオンラインの旧サーバーから画像やその他のデータを取得しているのではないかと思っています。旧サーバーでの新しい投稿や通知が表示されるためです)。

ホスト名を変更する方法については、以下の投稿の手順に従いました。

a.domain.comb.domain.com にリマップすることで問題が解決するかと考えていました。
rake posts:rebake も実行しましたが、結果は変わりません。

アバターやロゴが失われ、投稿に挿入されていた画像も表示されなくなっています。

最後に、@neounix さんが提案された通り、shared/standalone/uploads/ の宛先を置き換えるためにアップロードデータを再度 tar 展開しましたが、結果は同じでした。

あなたのデータベースに本当に価値ある情報が含まれていますか?サーバー移行を気にせず、最初からやり直す方が簡単かもしれません。

数ヶ月前にフォーラムが始まってからのすべてのデータと投稿は?

既にお伝えした通り、サーバーを停止し、すべてのデータを新しいサーバーにコピーして再起動することで、サーバーを別のサーバーに移行することができました。

しかし、サポートからは、正しい手順は標準的なバックアップを使用してデータベースを復元することだと伝えられました。

それを実行しようとしていますが、毎回何らかの問題が発生します。

本番環境で実施する前に、プラグインや変更、アップグレードの影響をテストするためにも、テスト用のサーバーが必要です。

サーバーがクラッシュしてから復元できるかどうかを確認するのを待つことはできません。

これまでの復元テストはすべて何らかの問題に終わり、画像やその他のデータが失われた非機能状態のシステムで終わっています。

この一連の件について:

https://meta.discourse.org/t/postgresql-12-update/151236/193

「別の Discourse インスタンスでバックアップとリストアを行う」方法を試したところ、以下の問題に直面しています。Sidekiq ジョブやリベイクなど、ありとあらゆる手は尽くしましたが、この原因について何か手がかりはありませんか?私が何か見つける手がかりになるものを教えていただければ幸いです。

(一つだけ言わせてもらうと、この経験を通じて、私は「まあ、なんとなくわかるかな」というレベルから、PostgreSQL の博士、Redis の博士へと成長しました :stuck_out_tongue: Ruby とローカル開発環境に慣れれば、コミュニティに貢献できるかもしれませんね :P)

すべてのアバターが消えてしまったのでしょうか、それとも一部だけでしょうか?カスタムアバターは基本的に「アップロード」です。他のアップロードは正常に機能していますか?

Rails コンソールに入り、データベース上の機能しないアバターのレコードを確認してください。URLfilesizewidthheightextension が正しい値になっていますか?

User.find_by_username('Overgrow').user_avatar
User.find_by_username('Overgrow').uploaded_avatar

最適化されたバージョンも存在している必要があります。以下のコマンドで確認できます:

OptimizedImage.where(upload_id: upload_id).where(version: 2)

まず第一に、@Overgrow さんのご支援に心から感謝いたします。

すべてのアバターや絵文字(そしてヘッダーなどのサイト画像も)は「存在する」のに表示されていませんでした。アバター以外のものは壊れたように見え、アバターはグレーのプレースホルダーが表示されます。一部のユーザーは新しい画像をアップロードでき、それらは表示されています。

最初にコマンドを実行したところ、以下のエラーが発生しました。

FATAL:  the database system is in recovery mode

そのため……そういうことですね :eyes:(頻繁に「切断」が発生しているので、データベースに関連しているのかもしれません)。

しかし、最終的に 粘り強く 実行すると:

User.find_by_username(‘Overgrow’).user_avatar

=> #<UserAvatar:0x000055702722d200
 id: 4,
 user_id: 3,
 custom_upload_id: 20504,
 gravatar_upload_id: 12240,
 last_gravatar_download_attempt: Thu, 21 May 2020 10:16:55 UTC +00:00,
 created_at: Sat, 30 May 2019 16:33:16 UTC +00:00,
 updated_at: Thu, 21 May 2020 10:16:55 UTC +00:00>

(今日新しいものをアップロードしようとしましたが、機能しません)。

User.find_by_username(‘Overgrow’).uploaded_avatar

=> #<Upload:0x00005555cd911b58
 id: 20504,
 user_id: 3,
 original_filename: "16_2.png.jpg",
 filesize: 56220,
 width: 360,
 height: 360,
 url: "/uploads/default/original/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8.jpeg",
 created_at: Thu, 15 Aug 2019 20:02:47 UTC +00:00,
 updated_at: Thu, 15 Aug 2019 20:02:47 UTC +00:00,
 sha1: "63347a46c0ca945f53613722a73c233484d642c8",
 origin: nil,
 retain_hours: nil,
 extension: "jpeg",
 thumbnail_width: 360,
 thumbnail_height: 360,
 etag: nil,
 secure: false,
 access_control_post_id: nil,
 original_sha1: nil>

OptimizedImage.where(upload_id: 20504).where(version: 2)

=> [#<OptimizedImage:0x000056366a01c1a0
  id: 95962,
  sha1: "5a32b5cc3e6f5c58d88a3c92a23076980a8ce840",
  extension: ".jpeg",
  width: 200,
  height: 200,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg",
  filesize: 28916,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a0741e8
  id: 95942,
  sha1: "ee353c9e23511b471e1a59c1f71a2ded3e366b1e",
  extension: ".jpeg",
  width: 20,
  height: 20,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_20x20.jpeg",
  filesize: 1270,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a074120
  id: 95943,
  sha1: "944fa9fc542a79a5c50394c75022bf84ace297e5",
  extension: ".jpeg",
  width: 30,
  height: 30,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_30x30.jpeg",
  filesize: 1952,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a074058
  id: 95944,
  sha1: "983490e58bed58c971ffa44e440b02ce3ea72bba",
  extension: ".jpeg",
  width: 40,
  height: 40,
  upload_id: 20504,
  url: "/uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_40x40.jpeg",
  filesize: 2695,
  etag: nil,
  version: 2>,
 #<OptimizedImage:0x000056366a07bf60

つまり、どうやら 画像は存在しているようですが、表示されません。グレーのデフォルトアバターのプレースホルダーしか表示されません。

データベースレコードレベルではすべて問題なさそうです。調査はそれより上のレベルに進めてください。

あなたが挙げたアップロードの URL を手動でたどった場合、どのような結果になりますか?

Discourse の URL の後に /uploads/default/optimized/3X/6/3/63347a46c0ca945f53613722a73c233484d642c8_2_200x200.jpeg(例えば)を追加すると、404 エラー(見つかりません)が表示されます。

つまり、これらは存在しないのでしょうか?(希望を込めて聞いています :P)

/uploads/default/optimized だけでなく、/uploads/default/original からのファイル URL も確認してください。

404 エラーが表示される場合、ファイルシステム上の /var/discourse/shared/standalone 内の uploads フォルダを確認し、実際の古いファイルがどこにあるか(存在する場合)を調べてください。見つけたら、動作する新規アップロードファイルの場所と比較してみてください。

また、バックアップから手動で復元することも可能です。

ご説明いただき、ありがとうございます。

実際に確認したところ、リストに含まれているパスの一部が存在しないことがわかりました。

奇妙なことに、新しいファイルをアップロードしようとする人がいるのですが、それらの新しいファイルも動作しません。あなたが教えてくださったコマンドで確認すると、存在しないパスが表示されてしまいます。Discourse はこれをどのように「マッピング」しているのでしょうか?一つ理解できるのは、ファイルが欠落していること(バックアップで引き継がれるはずでしたが)ですが、新しいアップロードが「幻影」のようなパスに送られる理由が、私にはよくわかりません。

uploads フォルダ内の tombstone フォルダを確認してください。不足しているファイルの一部がそこにありますか?

uploads 内に私が確認できたのは default フォルダだけです… tombstone フォルダは非推奨のファイル用などでしょうか?

追加情報ですが、ユーザーが既に持っている画像を再アップロードしようとした場合(ファイル名を変更しても、クエリ結果から推測するにハッシュ値に基づいているようです)、画像は読み込まれず、空の状態になります。保存するとグレーのプレースホルダーが表示されます。

どうやら、画像を何らかの方法で変更すれば(Photoshop で別形式で保存するだけでも)、再アップロードできるようです。

それは通常の動作です。重複する画像を避けるため、データファイルのハッシュ値がデータベースに保存されます。

compose エディタから画像をアップロードするとどうなりますか?アップロードは完了しますか?プレビューペインに表示されますか?

メッセージに画像を含めて送信すると、プレビューパネルに表示され、正常にアップロードされます。これは通常の動作です。

では、その画像が表示されなくなるのはどの時点でしょうか?

表示されている画像の URL を確認し、ファイルシステム上で追跡してください。

動作しない画像の URL を確認してください(ブラウザの開発者ツールを使用)。違いは何ですか?

もしかすると、異なるドメインを指している可能性があります。

最初のメッセージでは、特にユーザーのプロフィールを通じたアバターについて言及していました。2 番目はエディターに関するものです。

通常のメッセージでは、画像をドラッグ&ドロップするか、「画像をアップロード」ボタンを押せば、通常通りシームレスに機能します。

要約すると:

  • アバターが表示されず、プレースホルダーのみが表示されます。
  • カスタム絵文字も表示されません。
  • サイトの画像(ロゴなど)も表示されていませんでした。
  • 投稿作成画面で画像をアップロードする場合は正常に動作します。
  • インシデント前に使用していた同じアバターをアップロードしようとすると、動作しません。挙動は以下の通りです:アップロードは行われますが、デフォルトの文字、Gravatar、またはアップロードを選択するボックスには空白の四角が表示されます。選択を確定してページが再読み込みされると、グレーのプレースホルダーが表示されます。

また:

  • トムストーンフォルダーがありません。
  • 古い画像は、私が提供したクエリで示されたような存在しないディレクトリにあります。

ドメインの問題を確認してみます。参考までに、情報を調べている際に以下を試みました:

  • Sidekiq から CreateMissingAvatars ジョブをトリガー → 成功せず。
  • すべての投稿を再構築(これは少し無理やりかもしれませんが) → 成功せず。
  • このスレッド を参考に、メインサイトがオフラインの間にバックアップからの復元をテストするために異なるドメイン(実際にはサブドメイン)を使用したため、一部の URL が間違っている可能性があると推測し、以下を実行しました:discourse remap talk.foo.com talk.bar.com → 成功せず。

@Iceman

これは主に参考情報(FYI)であり、もしかすると情報過多(TMI)かもしれませんが、3 つのコンテナ(2 つの Web アプリケーションと 1 つのデータコンテナ)を同時に実行する際に発生する興味深い現象や、それがユーザーアバターにどのように影響するかについて、少しだけ洞察を得る助けになるかもしれません。

Redis / Sidekiq のジョブスケジューラが並列で動作しているが、ユーザー側の Web では「アクティブなのは 1 つだけ」という状況は、非常に興味深く(私にとっては非常にクールです)。

この短い議論と実例が興味深いと思えることを願っています。Discourse のジョブスケジューラ、画像最適化、そしてアバターについて、当社の設定に基づいたわずかな洞察が得られるかもしれません。

私は Discourse が Redis / Sidekiq を使用してバックグラウンドジョブをスケジューリングする方法を非常に気に入っており、これは Discourse のソフトウェアアーキテクチャの主要な強みと利点の一つだと考えています。

注:これらの概念は、バックアップとリストアのプロセスのさまざまな段階や、他の時間依存のプロセスにも、微妙な形で適用されます。したがって、Sidekiq がどのように、そしてなぜバックグラウンドでジョブをスケジューリングするのかを理解しておくことは重要です。

@neounix さん、情報ありがとうございます。これは非常に役立ちます。「Rails を学んで Discourse のサポートにつなげたい」という視点から、Discourse の「内部」をより深く理解する上で特に役立ちます。ただ、ご自身のインストール環境を修正しながら学ぼうとすると、学習曲線が非常に急峻で、正直言って大変です :stuck_out_tongue:

現在は Redis/Sidekiq に焦点を当てて、一部の埋め込みが機能していない理由を理解しようとしています。これは「Bake」と関連しているのではないかと考えていますが、デバッグの段階ではまだ確信が持てず、断定はできません(いずれにせよ、進歩を期待しています)。

今回の件については、@Overgrow さんのおかげで以下のことが分かりました:

  • 実際、バックアッププロセスはファイルをバックアップにコピーしましたが、Discourse インストールには復元されませんでした。他の 3 つの問題の状況や修正状況に基づき、別のインストール環境で別のバックアップを復元してバックアッププロセスを再テストする必要があるかもしれません。これは全員に共通する問題かもしれませんが、現時点では分かりません。

  • そのため、奇妙な動作が発生していました。

  • 最終的にバックアップを開き、欠落していたファイルをインストールに注入しました。その結果、Rebake を行わなくてもすべてが復元されました。

ただし、他の問題は残っています。Data コンテナを再構築できない問題(これについては全く見当もつきません)と、Sidekiq とイベントに焦点を当てるべき 2 つの問題です。これらはその方法で解決できる可能性があります。具体的には、一部の Onebox(特に YouTube)が機能しない問題と、実際には編集が行われていないにもかかわらず、一部のユーザーに対して「偽の」編集に関する通知が再帰的に発生する問題です。新しいインストールにはイベントに何らかの問題があるのではないかと考え、その原因を突き止めようとしています :man_shrugging: