Rails
PostgreSQL
mastodon

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


移行関係の話

理由は様々ですが、元々は全てDocker環境でしたがnon-Docker環境に変更しました。

WebとSidekiq、DBの移行自体は全て1時間程度で終わり、メディアサーバーの移行は数百GBあったので丸1日ほどかかりました。


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

移行完了後に何度か試験的に起動、停止を繰り返してみました。すると何故かPostgreSQLのみがCPUリソースをほぼ全て持っていくという状況になっており、明らかに通常の動作ではありませんでした。

そのため、PostgreSQLのチューニングなどを行なった上でもう一度起動してみました。しかし特に何も変わらなかったためSidekiqのダッシュボードページを開き確認したところ1つ1つの処理に非常に時間がかかっていたため、PgHeroのページを開き確認したところLong running queriesが大量にありました。そこで、Indexがおかしいのではないのかと判断しました。


色々調べてみた

サーバーに接続して本格的に調べてみたところ、Indexがおかしいという予想はある意味当たっており、必要なIndexが10個から15個ほど消えていました。


修復

一応今回用意したサーバーもEPYCを積んでいるそれなりに速いものでしたがパワーが足りず、処理に数週間かかる計算になってしまったので旧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_cloud_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が重複、重複したaccountsに紐付いていたstatuses3207431件、23129件のtagsが重複、13人が同じメールアドレスで複数のアカウントを登録という状況でした。

今回の移行は想定外の出来事が連続して起こったため、移行完了まで1週間ほどかかってしまいましたが無事に移行、修復が出来て本当に良かったと思っています。

しかし、今回の移行や修復は私だけでこの短期間に全て行うということは絶対に出来なかったことです。

今回の修復の際にアドバイスをくれたMastodon開発者のEugenと修復を手伝ってくれたあんのたんの2人には本当に感謝しています。