🛠️

ナンバーナインのMySQLバージョンを8.0にアップグレードしました

2024/08/23に公開

こんにちは、ナンバーナインで開発アルバイトをしているtessoです。

ナンバーナインでは、本番環境のMySQLバージョンを5.7から8.0にアップグレードしました。
本記事では、MySQL 8.0へのアップグレードの実施内容やその体験から得た知見を紹介します。

バージョンアップの背景

デジタル配信サービス「ナンバーナイン」では、データベースとしてMySQL 5.7を採用していました。
私たちのサービスでは、Amazon RDS for MySQLを利用しており、MySQL 5.7の標準サポートは2024年2月29日で終了でした。
標準サポート以降は、延長サポートという形になります。
そのため、RDSの延長サポートには追加コストがかかり、MySQL 8.0へのアップグレードが必要という状況でした。

アップグレード方法の選定

アップグレード方法としては、以下の2つが考えられました。

1. リードレプリカを使用したアップグレード

現在のDBインスタンスに対してリードレプリカを作成し、リードレプリカに対してMySQL 8.0にアップグレードを行う方法です。
リードレプリカが正常に動作することを確認した後、リードレプリカをプライマリに昇格させることでアップグレードを完了します。
アプリ側の接続先を変更するだけでアップグレード作業を完了できるため、ダウンタイムを最小限に抑えることができます。
また、リードレプリカに対してアップグレードを行うため、問題が発生した場合でも、接続先を元のプライマリに戻すことで簡単にダウングレードが可能です。
しかし、この方法は全てのアプリケーションの接続先を変更する必要があります。
そのため、事前に接続状況を把握し、接続情報を切り替える工数が発生します。

2. Blue-Greenデプロイメント

先ほどのリードレプリカを使用したアップグレードと似ているアップグレード方法です。
この方法では、新しいバージョン(Green環境)と現在のバージョン(Blue環境)を用意し、ロードバランサーで接続先を切り替えます。
AWSでは、既存の接続先がロードバランサーに切り替わり、環境の切り替えはロードバランサが変更してくれます。
そのため、アプリケーション側の接続情報を変更する必要はありません。
こちらもリードレプリカを利用した方法と同様に、2つの環境を切り替えるだけなので、ダウンタイムが少なくダウングレードも容易です。

今回は、Blue-Greenデプロイメントを採用しました。
ダウンタイムが少ないことと、ダウングレードが容易なことなどが魅力的でした。
さらに、DBインスタンス切り替え時に接続情報を書き換える必要がないこと、AWS側のサポートも充実しておりUI上から簡単に行えたことも大きいです。

事前準備

メジャーバージョンが切り替わるため、バージョンアップを行う前に事前準備が必要です。
ナンバーナインのDBで管理している書籍のデータはもちろん、支払い情報などの重要なデータがあるため、データの不整合や巻き戻りが発生しないことを第一に行いました。

1. アップグレード内容の把握

MySQL 8.0には5.7との互換性がないため、アップグレードによって動作しないSQL文やDBの設定があります。
具体的にどのような変更があるのかを把握するために、公式ドキュメントや他のアップグレード記事を参考にしました。
他の移行記事を読み込むことで、公式ドキュメントには書かれていない注意点を把握でき、大変助かりました。

Redashがとまるらしい

ナンバーナインでは、DBのデータを可視化するためにRedashを利用しています。
新しい施策をするためにも、あると嬉しい社内ツールです。
MySQLアップグレードに関するRedash への影響を調べていると、Redash v7においてTLSv1.1が原因で動作しない事例を見つけました。
そこで、AWSにおけるMySQLのTLSサポート状況を確認したところ、MySQL 8.0ではTLSv1.1のサポートをしないことが発覚しました。
ナンバーナインではRedash v5を利用しているため、アップグレードすると動作しなくなります。
いい機会なので、Redash v10までアップグレードし、Redashを動かしているインスタンスをUbuntu 22.04にアップグレードしました。
Redashはセットアップスクリプトを変更し、OSの方はdo-release-upgradeコマンドを利用しました。
かなりバージョンが変わるので苦戦すると思いましたが、意外とすんなりいきました。
do-release-upgradeとRedashの詳しいアップグレードガイドに感謝です。

2. ローカル環境でのテスト

ナンバーナインのシステムはDockerを用いてローカル環境でも構築できるようにしています。
とりあえず、ローカル環境からテストということで、DBのコンテナをMySQL 8.0に変更し、アプリケーションの動作を確認しました。
既存のテストの実行や、実際にアプリケーションを動作させることで、いくつかの問題を発見できました。

1. foreign_keyの設定

MySQL 8.0.16より、FOREIGN_KEY {index_name}は無視されるようになりました。
それまでは、ALTER TABLE {table_name} ADD FOREIGN KEY `{index_name} ({column_name})` のように設定していたため、外部キーの名前が無視されていました。
そこで、ALTER TABLE {table_name} ADD CONSTRAINT `{index_name}` FOREIGN KEY ({column_name}) と変更しました。

2. local_infileの設定

MySQL 8.0より、local_infileがデフォルトで0になりました。
そのため、LOAD DATA LOCAL INFILEを使用できなくなっています。
ナンバーナインでは、sqlcを導入しています。
sqlcでバルクインサートを行うと、内部ではLOAD DATA LOCAL INFILEを使用しているため、エラーが発生しました。
そこで、local_infileを1に変更しました。
別途、RDS側でも設定が必要なので注意です。

3. アップグレードチェッカーの実行

MySQL Shell ユーティリティを利用することで、MySQLメジャーバージョンのアップグレードの準備ができているかを確認できます。
ナンバーナインでは、そこまでMySQLの設定を大幅に変更していなかったためか、特にアップグレードチェッカーに検知される問題はありませんでした。

4. 開発環境でBlue-Greenデプロイメントのテスト

ローカル環境でのテストが終わった後、開発環境でBlue-Greenデプロイメントを行いました。
Blue-Greenデプロイを試すことで、実際のダウンタイムやダウングレードの時間、手順などの確認しました。
開発環境でのテストを通して以下の知見を得られました。

  • 環境の構築に30分ほど必要
  • ダウンタイムはほとんどない
  • ダウングレードには30分ほど必要
  • Blue環境への書き込みはGreen環境に共有される

アップグレード作業

以上の事前準備を踏まえて、実際に作業をします。

1. Blue-Green環境の構築

AWSコンソールからBlue-Greenデプロイ環境を構築します。
DBのパラメータグループを変更する必要がありますが、コンソールのボタンを押していくだけで簡単に作成ができます。

2. 各環境の調査

Green環境が正しく作成されているかをDBクライアントを手元から接続して確認します。
ついでに、クエリを流してバージョンやレプリカ設定が正しく行われているかを確認します。

3. 経過観察

Blue環境への書き込みは、Green環境へも共有されます。
1週間ほど、2つの環境を共存させて、エラーが発生しないかを監視しました。
特に問題は発生しませんでした。

4. 環境の切り替え

Blue環境からGreen環境への切り替えを行います。
こちらもコンソールからボタンを押すだけで完了しました。
切り替えてから数時間はログを観察していましたが、こちらも問題は発生しませんでした。
よかったね。

5. Blue環境を削除

環境切り替えから1週間ほど、ダウングレードを行うためにBlue環境も残したままにしていました。
環境を切り替えてからも問題が発生しなかったため、Blue環境を削除しました。
これで、MySQL 8.0へのアップグレード作業は完了です!

おわり

今回は、MySQLのバージョンアップについてまとめました。

バージョンアップのタスクを渡されたときは、重要なデータをいくつも扱うため、とても緊張しました。
絶対にデータの巻き戻りや不整合が起きないことを目標に、いつもより気を引き締めて入念に事前調査とテストを行いました。
そのおかげもあって、ナンバーナインのシステムを止めることもなく、巻き戻りや不整合なども起こすことなくバージョンアップができました。
大きな問題が起きなくてよかった。

参考記事

今回の移行作業にあたり、以下の記事を参考にしました。

ナンバーナイン開発室

Discussion