MastodonからFedibirdに移行する

Mastodon 3.1.2からFedibirdに乗り換えた。(on FreeBSD 13.2-RELEASE)
久しぶりに地獄を味わった気がする。

とりあえずメモを残しておく。きっと、もっとエレガントな方法があるはずだが、それでも記録は記録なのだ。

  • Rubyは2.xである必要あり。3.xでもナントナクは動くけど、時々 **dict の扱い違いが原因のエラーが出るので危険。
  • ruby27はpkgがあるけど、ruby-gemsはpkgがないのでソースコードから ./configure && make install が必要。
  • idn-ruby gemはinclude pathの都合があるので、 bundle install の前に gem install が必要。
  • db:migrateは気合と根性が必要。かもしれない。
  • tootctl cache clearしないとあるはずのデータ(列)が見えなかったりして大混乱する。

追記は末尾にて。

ruby 2.7

https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.7.tar.gz から拾ってきて、 ./configure && make install すればいいだけ。

idn-ruby

$ pkg install libidn2
$ gem install idn-ruby -v 0.1.2 -- --with-idn-dir=/usr/local

db:migrate

ここが一番しんどかったところ。rake db:migrate してもいろいろコケる。
ここはruby 3.xでやっていたのが悪かったかもしれないが、今となっては確かめる気にもならない。
あと、mastodon側も以前migrateが失敗して誤魔化したことがあるので、一部はソレかもしれない。

ざっくり以下の2手順。

  • db:migrateを気合で通す
  • 余分なテーブルと列を葬る

db:migrateを気合いで通す

PG::DuplicateColumn: ERROR:  column "list_id" of relation "keyword_subscribes" already exists
/home/mastodon/db/migrate/20191025190919_add_list_to_keyword_subscribes.rb:5:in `change'

PG::DuplicateColumn: ERROR:  column "list_id" of relation "account_subscribes" already exists
/home/mastodon/db/migrate/20191026110416_add_list_to_account_subscribes.rb:5:in `change'

PG::DuplicateColumn: ERROR:  column "list_id" of relation "follow_tags" already exists
/home/mastodon/db/migrate/20191026110502_add_list_to_follow_tags.rb:5:in `change'

このへんは既に存在する列の追加なので無視。scriptを空にしてスルーさせる。

NameError: uninitialized constant AddIndexURLToStatuses
Did you mean?  AddIndexUrlToStatuses

これは……なんだろうね?動けばよろしいの精神で直す。

db/migrate/20200312020757_add_index_url_to_statuses.rb:
- class AddIndexUrlToStatuses < ActiveRecord::Migration[5.2]
+ class AddIndexURLToStatuses < ActiveRecord::Migration[5.2]

db/migrate/20200827204602_add_inbox_url_to_conversations.rb:
- class AddInboxUrlToConversations < ActiveRecord::Migration[5.2]
+ class AddInboxURLToConversations < ActiveRecord::Migration[5.2]
No such column: custom_filters.whole_word
/home/mastodon/db/migrate/20230106051103_change_default_of_whole_wotd_in_custom_filter.rb:3:in `change'

これはウチの環境が悪いであろうもの。手動で直す。

(echo 'require("./db/migrate/20180707154237_add_whole_word_to_custom_filter.rb")'; echo "AddWholeWordToCustomFilter.new.change" ) | RAILS_ENV=production bundle exec rails runner -
== 20230221031206 AddWidthHeightToCustomEmoji: migrated (0.0017s) =============

rake aborted!
NameError: uninitialized constant CreateNodeInfo

そんなバカな?これも動けばいいので直す。

db/migrate/20230310214919_create_nodeinfo.rb

- class CreateNode < ActiveRecord::Migration[6.1]
+ class CreateNodeInfo < ActiveRecord::Migration[6.1]

記録してあるのはこのへんまで。これで rake db:migrate は成功するが、まだまだおかしい。

余分なテーブルと列を葬る

db/schema.rb の通りにすればいいんだけど、手動でこれをやるのは困難。特にindexとか。

まずは差分をチェックする。
今のデータベースからschema.rbを作って、diffで見ていく。

$ mv db/schema.rb db/schema.rb.fedibird
$ RAILS_ENV=production bundle exec rake db:schema:dump
$ mv db/schema.rb db/schema.rb.old
$ sdiff --width=240 db/schema.rb.old db/schema.rb.fedibird
$ cp db/schema.rb.fedibird db/schema.rb

fedibird側で追加されているものはdefaultに期待してスルー。
逆にfedibird側でないデータはrestore時にコケるので、1つずつDROP TABLEまたはDROP COLUMNしていく。

余計なものがなくなったら、SQL形式でdumpを作る。

$ pg_dump --data -U mastodon mastodon > /でかいよ/mastodon-db-data-only.sql

ここでDBを完全に消して(別途DROP DATABASE)、db:setupで作り直す。先の手順でdb/schema.rbを戻し忘れていると悲しいので注意。

$ RAILS_ENV=production bundle exec rake db:setup

初期用のデータが入るので消す。ただし、schema_migrationは必要なのでとっておく。

$ pg_dump --data --schema=schema_migrations -U mastodon mastodon > /これは大きくない/schema-migrations.sql
$ cat << EOM | psql -U mastodon mastodon
TRUNCATE accounts CASCADE;
TRUNCATE ar_internal_metadata CASCADE;
TRUNCATE oauth_applications CASCADE;
TRUNCATE schema_migrations;
EOM

まっさらチェック。

$ pg_dump -U mastodon --data --insert mastodon | grep INSERT

データを復元する。ここで、循環参照のあるforeign keyを復元させるため、一時的にmastodonユーザにsuperuser権限が必要。終わったら権限は戻しておく。

$ (echo "set session_replication_role = replica;"; cat /でかいね/mastodon-db-data-only.sql) | psql -U mastodon mastodon

schema_migrationsを上書きする。

$ echo "TRUNCATE schema_migrations;" | psql -U mastodon mastodon
$ psql -U mastodon mastodon < /これは大きくない/schema-migrations.sql

途中、何度か時間や手間のかかる処理があるので、適宜バックアップと取らないと辛いことになる。(なった)

追記分

db:migrate関連の失敗で、過去分のmedia_attachments.shortcodeがNULLになっていた。
これがあると、プロフィールのページが開けなかったりする。
対応するのは 20170105224407_add_shortcode_to_media_attachments.rb
SQLを直接実行して解決した。

UPDATE media_attachments SET shortcode = id WHERE shortcode IS NULL AND remote_url = '';