Cake.jp技術部の山内です。
2024/10末にMySQL8.0へのアップデートを行いました。
弊社ではAWSを使用しており、MySQL5.7のサポートが2024/10/31で切れてしまう、かつ、それ以降は追加料金が発生するという状況がありましたので、弊社でもやっと対応しました。
ということで、今回は弊社で行なったアップデート作業について書いていきます。
どのようにアップデートを行ったのか
先ほどお伝えしたように、弊社ではAWSを使用しています。そのためDBの環境として、Aurora MySQLを使用しています。
そのAurora MySQLに用意されているブルー/グリーンデプロイを使用しました。
他の手段としては、既存クラスターをそのままアップグレードする「インプレースアップグレード」、スナップショットから復元する「スナップショットリストア」などがありましたが、ダウンタイムの少なさと作業の容易さなどの観点から、ブルー/グリーンデプロイを選択しました。
本番対応までに何をしたのか、その後どのような問題があったのかについて記載していきます。
アップデート実施までの道のり
作業概要
慎重を期すためにも、いくつかのステップを踏んで行きました。
まずはローカル環境での動作確認を行いました。問題ないことが確認できたのち、テスト環境の予行練習、テスト環境のバージョンアップを行いました。
テスト環境で1週間程度運用してみて、問題がなさそうだったので、本番の予行練習、バージョンアップと進んでいきました。
一覧化すると以下になります
- ローカル環境で動作確認
- テスト環境のバージョンアップの予行練習
- テスト環境をMySQL8にバージョンアップ
- 本番環境のバージョンアップの予行練習
- 本番環境をMySQL8にバージョンアップ
ローカル環境で動作確認
作業ブランチを作成し、そちらの環境をMySQL8に変更しました。この環境で動作確認を進めました。
動作確認方法
弊社ではPHPのバージョンアップを進めており、その際に行っていた動作確認を行いました。
主に以下のようなことをしていました。
- CIでテスト実行
- 一括でCURLでHTMLを取得し、MySQL5.7環境とMySQL8.0環境に差分がないかdiffコマンドでチェック
- TestCafeで主要どころの自動E2Eテスト
- PHPバージョンアップの際に、少しずつ育てていました
- バッチの一括実行で動作確認
- 途中終了はないか、ログにエラーは出ていないかを確認
- その他気になるところは手動で動作確認
テスト環境のバージョンアップの予行練習
テスト環境のMySQLのバージョンアップを行うための予行練習をしました。念には念を。
以下手順で実施しました。
- テストDBのスナップショットを取得
- スナップショットから予行練習用DBを作成
- 予行練習用のblue/greenを作成
- 切り替え
- 切り替わりの確認
- MySQLへログインしてstatusコマンドを実施
- 動作確認実施
上記手順で問題なく切り替えができることを確認できたので、テスト環境のアップデートを実施します。
テスト環境をMySQL8にバージョンアップ
こちらは手順としては予行練習とそこまで違いはなく、既存DBを使用するため、スナップショット周りの対応が不要になります。
- blue/greenを作成
- 切り替え
- 切り替わりの確認
- MySQLへログインしてstatusコマンドを実施
- 動作確認実施
これでテスト環境が先行してMySQL8.0になりました。1週間程度使用してみて、特に問題が出なかったので次に進みました。
本番環境のバージョンアップの予行練習
基本的にはテスト環境の予行練習と同じ手順で行いました。
- テストDBのスナップショットを取得
- スナップショットから予行練習用DBを作成
- 予行練習用のblue/greenを作成
- 切り替え
- 切り替わりの確認
- MySQLへログインしてstatusコマンドを実施
- 動作確認実施
ここでも特に問題は見つからなかったので、いよいよ本番です。
本番環境をMySQL8にバージョンアップ
本番の手順はテスト環境のバージョンアップの手順に加え、少し本番環境らしい対応が追加されています。
- メンテナンスモードに移行 new!
- blue/greenを作成
- バッチの停止 new!
- 切り替え
- 切り替わりの確認
- MySQLへログインしてstatusコマンドを実施
- 動作確認実施
- バッチを再始動 new!
- メンテナンスモードの解除 new!
- 停止中に稼働するはずだったバッチの再実行 new!
ダダーッと書いていきましたが、ブルー/グリーンデプロイのおかげで、特に難しいことはなく進められました。
苦労したこと
非常に時間のかかった対応がありました。
ブルー/グリーンデプロイに失敗
エラー発生箇所
ブルー/グリーンデプロイの作成を成功させる、これに非常に苦戦しました。
blueはMySQL5.7、greenはMySQL8.0という環境で作成をしたのですが、どうやら互換性のないものが存在するらしくエラーで失敗しました(エラーメッセージを探し出せませんでした、、、)。
とあるテーブルにtinytext型のカラムがあったんですが、そのカラムの存在がエラーを発生させていました。
以下の公式リファレンスを見ても、なぜエラーになってしまうのかは理解できていません。
- 2.11.4 MySQL 8.0 での変更
- 11.3.1 文字列データ型の構文
- ここにもtinytextの記載は存在する
エラーの特定
ピンポイントに、「ここが互換性ありませんよ」としてくれる手段が見つけられず、地道に特定作業をしていました。
- 検証用のDBをテストDBの内容に合わせる
- テーブルを半分削除し、blue/greenの作成
- 失敗したblue/greenの削除
- 1に戻る
こういったサイクルをひたすら繰り返して、対象を探してました汗
最終的にカラムの特定に至るまで20回程度この作業をしていました涙
ちなみにですが、Upgrade Checker Utilityなるものが存在しますが、これでは検出されませんでした。
DMSが連携に失敗している
弊社では社員全員がDBの閲覧が可能です(個人情報などの情報は落としています)。
そのDBへの連携としてDMSを使用していますが、そこで不具合が起きていました。
エラー内容と対応
以下のエラーが出て、連携に失敗していました。
E: Error Code [10001] : Binary Logging must be enabled for MySQL server [1020418] (mysql_endpoint_capture.c:424)
結論としては、パラメータグループのbinlog_formatの設定漏れでした。
新しくMySQL8用のパラメータを作成した際にbinlog_formatをデフォルト(OFF)のままにしていたせいで、連携に失敗しました。
ですので設定をROWに変更することで無事連携に成功しました。
スッと書きましたが、この設定の反映にはインスタンスの再起動が必要なので、2日連続の深夜メンテです・・・。
さいごに
今回の対応において、サービス側では特に不具合は発見されておらず、ホッとしています。
慎重に事前準備をしたことが、サービス側での不具合なしに繋がったと思っています。
MySQL8へのバージョンアップ前は、PHPのバージョンアップも行っており、1年半かけてPHP5.7からPHP8.3まで上がりました。
PHPは8.3、MySQL8.0とかなりモダン風な開発環境になってきたなーと感じています(当社比)。
今後も開発環境のアップデートは放置せずに進めて行きたいと思っております!