DB

個人開発で使っていたデータベースを Planet Scale へ移行した話

個人開発者をする上でデータベースの選択は非常に重要だと思います。

僕は個人アプリのミューチャのデータベースとしてローカルにインストールした MySQL を使用していました。しかし、それを Planet Scale に移行することを決めました。

この記事では、なぜ移行したのか、どのように移行を行ったのか、そして移行後の利点について説明します。

なぜ Planet Scale へ移行したのか

今までミューチャはコストの関係で一つの EC2 サーバーで Unicorn と MySQL を動かして運用していました。

ミューチャは LINE リマインドツールなので、もしデータベースのデータが吹き飛んでリマインドが届かず大事な予定を忘れてしまったら、ユーザーは不信感を抱くでしょう。

このようなことを避けたいので、データベースのバックアップは必ず取っておきたいという背景がありました。

バックアップを取るのが大変

ローカルにインストールした MySQL を動かす上でバックアップを取るのが大変でした。

繰り返しになりますが、アプリケーションを稼働させ続ける上で大きなリスクがデータベースのデータが飛んでしまうことです。

これを防ぐためには、定期的にバックアップを取っておく必要があるのですが、手動でダンプするとなると、毎日はできないですし忘れてしまうことだってありえます。

また、自動化するためにスクリプトを作って cron で実行するという方法も EC2 サーバー自体がクラッシュしてしまったら終わりです。

また、cron が動かないことを考えて動いていないことを検知する仕組みがいりますし、バックアップファイルが増えてディスクを一杯にしてしまわないように古いものを削除していく仕組みも必要です。

こうした手間をすべて解決してくれる SaaS を探すことにしました。

RDS vs Planet Scale

同じくバックアップを自動でとってくれる SaaS に AWS RDS があります。RDS は AWS のサービスなので、EC2 から使うのに相性がいいですし、スケーラビリティなども自動でやってくれたりその他機能が充実しています。

ただし、RDS は料金が高く、一番安いサーバーを使っても月に 3000円ほどかかりランニングコストがかかりすぎるので候補から外しました。

それに対して、Planet Scale の料金はなんと無料です。

Planet Scale は一アカウントで動かせるデータベースが1台のみという制約がありながらも5G のストレージを無料で使うことができます。

バックアップも毎日無料で取ってくれます。(さらに細かくバックアップを取る場合は料金がかかります。)

また、ブランチという概念があり本番用に加えて開発用として追加でデータベースをつくることができます。

なので、ステージング環境のようなテスト環境用のデータベースをつくるのもなんと無料でできてしまいます。

念のため、ミューチャが現状使っているストレージを調べたのですが、300KB 以下で 5G は個人用のアプリを動かすには十分すぎる大きさでした。

mysql> SELECT table_schema,
    ->        floor(SUM(data_length + index_length) / 1024) AS ALL_KB,
    ->        floor(SUM((data_length) / 1024)) AS DATA_KB,
    ->        floor(SUM((index_length) / 1024)) AS INDEX_KB
    -> FROM information_schema.tables
    -> GROUP BY table_schema
    -> ORDER BY sum(data_length + index_length) DESC;
+--------------------+--------+---------+----------+
| TABLE_SCHEMA       | ALL_KB | DATA_KB | INDEX_KB |
+--------------------+--------+---------+----------+
| mysql              |   2672 |    2336 |      336 |
| mucha_*****        |    272 |     128 |      144 |
| sys                |     16 |      16 |        0 |
| information_schema |      0 |       0 |        0 |
| performance_schema |      0 |       0 |        0 |
+--------------------+--------+---------+----------+

また、Web 上のダッシュボードからクエリのレイテンシーや発行された SQL 文も確認することができ、ざっくりとした監視をすることもできます。

例) クエリのレイテンシー

SQL 文はもちろん詳細な中身はマスクされてますが、どういったクエリが多く発行されているのかをざっくり見ることができます。

また、CLI もあって、ターミナル上から SQL文 を実行したりバックアップを取ったりということもでき、やりたいと思ったことはほとんど何でもできるようになっています。

移行方法は?

MySQL からの移行方法についてですが、僕は当初元のデータベースから mysqldump をして Planet Scale のデータベースへそれを適用しようと考えていました。

ただ Planet Scale の仕様上、MySQL が動いているサーバー上に SSH することができなかったので断念しました。

その代わり、Planet Scale が既存の MySQL からデータをインポートする機能を用意してくれています。

これに従って進めると、インポートすることができました。

また、インポートし終わった後も元のデータベースとレプリケートして同期を取っていて、設定を進めると今度は Planet Scale 側から元のデータベースへレプリケートするようになっていて、仮に元のデータベースへアクセスがある状態でもダウンタイムをほとんどなくして移行ができるようになっていました。

ハマりどころ

レプリケーションの設定

上述のようにインポートの後にレプリケートするようになっているので、その設定を元のデータベースにもやっておく必要がありました。

僕がやってできた設定を載せておきます。
(インポートのためだけにした設定なので、きちんと使うには不適切な可能性があるので自己責任でお願いします🙇‍♂️)

$ sudo vim /etc/my.cnf
# 下記を追記
# 各MySQLサーバを識別するためのIDの設定
server-id=1

# GTIDの有効化
gtid_mode=ON

# GTIDと併用できないSQL文を禁止する
enforce_gtid_consistency

# バイナリログの有効化
log_bin=mysql-bin

# バイナリログをコミットと同時にディスクに書込む
sync_binlog=1

$ sudo systemctl restart mysqld

権限の設定

インポートする用のユーザーを作成して、適切な権限の設定をする必要がありました。きちんと公式ドキュメントを見れば書いてあるもののかなり苦戦してしまいました。

最終的に以下の権限になるようにします。

mysql> show grants for 'user_name'@'%';
+------------------------------------------------------------------------------------------+
| Grants for user_name@%                                                                       |
+------------------------------------------------------------------------------------------+
| GRANT PROCESS, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO `user_name`@`%`               |
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, ALTER ON `_vt`.* TO `user_name`@`%`      |
| GRANT SELECT, INSERT, UPDATE, DELETE, LOCK TABLES ON `database_name`.* TO `user_name`@`%` |
+------------------------------------------------------------------------------------------+

外部キー制約を外す

Planet Scale は外部キー制約をサポートしていないので、元のデータベースで設定してある場合は外す必要があります。

外さない場合は以下のようなエラーが出て、インポートすることができませんでした。

インポートが完了したら、アプリ側のデータベース接続情報の環境変数を Planet Scale のものに変えて接続確認をしたら完了です!

自分用メモ

当初、MySQL が動いているサーバーへ入るための秘密鍵を Planet Scale 上に登録しないといけないと勘違いしていた。

Planet Scale へ移行してよかったこと

Planet Scaleに移行したことで、以下の利点を得ることができました。

  • データベースのバックアップを自動で取れるようになった
  • EC2 サーバーのメモリ負荷のほとんどを占めていた mysqld のプロセスを動かさなくて良くなり負荷が軽減した
  • スケーラビリティが向上した
    • 自動的にスケールアップされ必要に応じてスケールダウンされるため、アプリケーションの成長に合わせて必要な容量を手軽に調整できるようになった
  • 高可用性の提供の恩恵を受けられる
    • データの消失やシステムのダウンタイムを心配する必要がなくなった

上から順に僕的にうれしいポイントを挙げていきました。

さいごに

Planet Scale は個人開発で使う分には無料枠でも十分なストレージ量を使うことができ、自動バックアップを行うのも無料でできます。

かつ移行作業もスムーズに行うことができました。

この記事が役に立った方がいればぜひシェアしていただけるとうれしいです。

下が今開発しているミューチャです!
友だち登録してトーク画面のメニューからリマインドの設定ができます。よければぜひ使ってみてください。

画像に alt 属性が指定されていません。ファイル名: M_gainfriends_2dbarcodes_GW.png
ABOUT ME
sakai
三重出身の28歳。前職はメーカーで働いていて、プログラミングスクールに通って未経験からWeb業界に転職しました。Railsをメインで使っていて、AWSも少しできます。音楽を聞くこととYoutubeを見るのが好きです。最近はへきトラ劇場にハマってます