PostgreSQL
RubyOnRails
mastodon

世界で6番目に大きなMastodonインスタンスを移行して、DBの修復をした話

世界で6番目に大きなMastodonのインスタンスを移行した時の話

ならこういったものは書くつもりはなかったのですが

世界で6番目に大きなMastodonのインスタンスを移行した時にDB周りで色々と問題を発見したので修復するのが大変だった話

という事だったので書いた日記です。

多分割とどうでも良い話

まず、mastodon.cloudというMastodonの大規模インスタンスの移行と修復作業を行いました。
恐らくですが、Mastodonのインスタンス管理者なら割と誰でも知ってる程度には不安定なインスタンスです。
私の1人だけのインスタンスが消えたとしてもそこまで影響はないのですが大規模なインスタンスが消えるとMastodon自体の勢いも落ちていくのではないかという心配がありました。
事実、この連絡をする少し前にMastodonの大規模なインスタンスのデータが吹き飛んだということが発生していました。
私の印象としては管理者もなかなかMastodonには顔を出さないという感じだったので良い機会だと思いメールで連絡を取ってみたという感じです。
確か初めて連絡をした時が4月の21日だったと記憶しています。
それからメールで何度かやり取りしていたのですが、メールだとリアルタイム性が無く何をするのにも時間がかかるのでTwitterのダイレクトメッセージで連絡をすることにしました。Mastodonではありません、Twitterです。
それから割とスムーズに話が進み色々とお互い聞きたいことを聞いたりして移行に関して合意に至ったということで、本格的に動き始めたのが5月の24日です。

移行関係の話

理由は様々ですが、元々全てDocker環境だったのでDocker環境からnon-Docker環境に変更しました。
WebサーバーとAPサーバー、DBサーバーの移行自体は全て1時間程度で全て終わり、メディアサーバーの移行は数百GBあったので丸1日ほどかかりました。
特に難しいことはしておらず、ここに関しては普通のやり方と同じです。

割と面白いかもしれない話

色々と発覚したまずいこと

移行してから何度か試験的に起動したり停止したりしてみたのですが、なぜかPostgreSQLのみがCPUリソースをほぼ全て持っていくという状況になっており明らかにMastodonの通常の動作ではありませんでした。
そのため、PostgreSQLのチューニングなどを行なった上でもう一度起動してみたのですが特に変わらなかったためMastodonの管理画面からSidekiqのページを開き確認したところ1つ1つの処理に非常に時間がかかっていたため、同じくMastodonの管理画面から今度はPgHeroのページを開き確認したところLong running queriesが大量にあったためIndexがおかしいのではないのかと判断しました。

色々調べてみた

ポチポチWebから色々やってみたらやはり色々とおかしいようだったのでサーバーに接続して本格的に調べました。
Indexがおかしいという予想はある意味当たったというかそもそも必要なIndexが10個から15個ほど消えており、非常に遅かったという感じでした。

というかそもそも普通に運用してるだけではこんな事にならないはずなんですが何でこうなったのだろう…。

修復

サーバーも一応物理専用サーバーでそれなりに速いもののそれでもパワーが足りなかったりすることが想定されたので旧DBのdumpを吐かせてからローカルに

  • mastodon_cloud_origin (旧DBのデータを入れたDB)
  • mastodon_cloud_production (bundle exec rake db:setupをしただけの綺麗なDB)
  • mastodon_cloud_development (bundle exec rake db:setup後、Indexを除去したDB)

を用意して各テーブルごとにmastodon_cloud_originからtable指定、かつdata-onlyのdumpを吐き、mastodon_cloud_developmentにdumpを投入し、mastodon_cloud_development上で諸々SQLを叩いて、重複や、重複により削除したaccountsなどFKが張れないレコードを削除、Indexが張れそうになったら、mastodon_cloud_developmentからtable指定、かつdata-onlyのdumpを吐きdumpをmastodon_cloud_productionに投入、という作業を全テーブル分ひたすら繰り返します。

BigQueryでの作業

conversationsテーブルについては、データ量が多すぎてローカルのmastodon_cloud_developmentだと時間がかかりすぎるので、mastodon_cloud_developmentからCSVを吐きCSVをGCSに上げてGCSからBigQueryに投入し、BigQueryで重複除去諸々をしてからGCSに結果のCSVをエクスポートしてmastodon_cloud_developmentconversationsを一旦truncate、CSVをmastodon_cloud_developmentに投入してから問題なく取り込めることを確認してからmastodon_cloud_developmentからtable指定、かつdata-onlyのdumpを吐き、dumpをmastodon_cloud_productionに投入。

Auroraでの作業

statusesテーブルについても、データ量が多すぎてローカルのmastodon_cloud_developmentだと時間がかかりすぎるので、mastodon_cloud_developmentからdumpを吐き、dumpをAuroraに投入し、FKの紐付け出来ないものを除去する際JOINするため重複除去前/除去後のaccountsテーブルを名前を変えて投入してから重複除去諸々をしてAuroraからdumpを吐き、dumpをmastodon_developmentに投入してから問題なく取り込めることを確認してmastodon_cloud_developmentからtable指定、かつdata-onlyのdumpを吐き、dumpをmastodon_cloud_productionに投入。

statusesでBigQueryを使わなかったのはCSVが非互換で上手く取り込めなかったからというのが理由です。

statuses, conversations以外のテーブルはMacProのローカルで整形しました。

ちなみにテーブルを指定してdumpファイルに吐き出すには

pg_dump --data-only --table テーブル名 DB名 > ファイル名

で行う事が出来、dumpの投入は

psql DB名 < ファイル名

で行う事が出来ます。

最後に

5592件のaccountsが重複しており、13人が同じメールアドレスで複数のアカウントを登録をしており、重複したaccountsに紐付いていたstatuses3207431件、23129件のtagsが重複という状況でした。

今回の移行は予想外の出来事が連続して起こったため、移行完了まで1週間以上かかってしまいましたが、無事に移行、修復が出来て本当に良かったと思っています。
しかし、今回の移行や修復は私だけではこの短期間で全て行うということは到底出来なかった事です。
今回の修復の際にアドバイスをくれたり、雑談に付き合ってくれたMastodon開発者のEugenと修復を手伝ってくれたあんのたんの2人には本当に感謝しています。

現在では非常に安定しており、動作もかなり軽快なので是非皆さんmastodon.cloudに遊びに来てみてください。
また、あんのたんや私が運営しているnow.kibousoft.co.jpにも遊びに来てもらえると嬉しかったりします!