Aurora MySQLのブルー/グリーンデプロイを使用してMySQLのアップデートをした流れと苦労

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型のカラムがあったんですが、そのカラムの存在がエラーを発生させていました。

以下の公式リファレンスを見ても、なぜエラーになってしまうのかは理解できていません。

エラーの特定

ピンポイントに、「ここが互換性ありませんよ」としてくれる手段が見つけられず、地道に特定作業をしていました。

  1. 検証用のDBをテストDBの内容に合わせる
  2. テーブルを半分削除し、blue/greenの作成
  3. 失敗したblue/greenの削除
  4. 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とかなりモダン風な開発環境になってきたなーと感じています(当社比)。

今後も開発環境のアップデートは放置せずに進めて行きたいと思っております!