Amazon Aurora MySQL5.7のサポート期限が迫ってきたのでMySQL8に移行した話
こんにちは、アルダグラムのSREエンジニアの okenak です
弊社のサービスのDBにAmazon Auroraを利用していますが、MySQL5.7の標準サポートが2024年10月31日までであるため、MySQL8の移行を実施しました。(サポート期限について)
今回は移行に伴い調査したことや対応手順、実際に起きた問題について紹介したいと思います。
Aurora MySQL8のアップグレード内容の調査
MySQL5.7からMySQL8の移行だったので、公式ガイドを見て機能差分の調査を行いました
MySQL :: MySQL 8.0 リファレンスマニュアル :: 2.11 MySQL のアップグレード
Amazon Aurora MySQL DB クラスターのメジャーバージョンのアップグレード - Amazon Aurora
ドキュメントを一通り読んだところ気になったポイントは以下の部分でした
- GROUP BYの暗黙ソートがされなくなる変更
- 上記に依存した処理がある場合は挙動が変わるので
- distinct使用時、selectリストにない項目でORDER BY すると怒られるようになった
- 使ってる箇所があれば修正が必要
- パフォーマンス影響がないかどうかの調査
- オプティマイザの実行に影響が出るようになっている
- ソートの挙動が変わったのでsort buffer sizeのエラーが出ないか
- 予約語にrankが追加
- 弊社サービスのテーブル名やカラム名でrankを使ってる箇所はなかった
- インスタンスタイプにdb.t3.smallが利用不可
- 最小単位がdb.t3.mediumになるため開発環境などで使ってるAuroraの料金が上がる
- sql_modeからNO_AUTO_CREATE_USERの削除
- 弊社サービスでは指定してる箇所はなかった
Aurora MySQLのどのバージョンを選択するか検討
2023年4月現在は最新の3.0.6.0がリリースされていますが、以下は当時調査時点での内容です
(3.05.0と3.05.1共に現在は廃止されており、3.05.2しか選べないようになってる模様です)
Aurora version | MySQL version | トピック情報 | リリースノート |
---|---|---|---|
3.05.1 | 8.0.32 | ・当時のAurora最新版(security fix版) ・機能面やmysqlのバグの状況は3.05.0と同じ |
リンク |
3.05.0 | 8.0.32 | ・再起動時間が最大65%短縮 ・UNION ALLの日本語検索のバグがある ・ALGORITHM=INSTANTの制限が一部解禁 |
リンク |
3.04.1 | 8.0.28 | ・長期サポートの対応(LTS) | リンク |
- LTSが提供されているAurora 3.04.1(MySQL8.0.28)を採択することに決定
- 3.0.5.0と3.0.5.1はメリットもあるが運用コストが高いのと不具合もあるため採用を見送る
- メリット
- Auroraの再起動時間が短縮するアップデートがありメンテ等の時間が短くなりそう
- オンラインDDLで大量レコードのテーブルのALTER TABLEがし易くなる
- デメリット
- 潜在的なバグの多さの懸念、サポートが短いため定期的にアップデートが必要になる
- UNION ALLの日本語検索のバグがある
- メリット
- 参考記事
本番環境の移行プロセス
- ローカル環境を先にアップデートして影響範囲の洗い出しと修正を実施
- Docker環境をMySQL8に移行してローカルで動作確認を行って検知された箇所を修正
- Rspecのテストコードで検知された箇所の修正
- MySQL8アップデート検証環境を構築して網羅的なQAを実施
- QAチームの協力を元に全体テストを実施して機能デグレがないかどうかチェック
- MagicPodを使ったE2Eテストを実施して基本動作シナリオで検知された箇所の修正
- 本番環境をメンテナンスモードに切り替えアップデートを実施
- 移行方法としては過去にDB暗号化の手順と同じやり方で、既存DBのスナップショット取得からのAuroraクラスターを新規作成して、DNSの向き先を切り替えで対応しました。
本番環境の切り替え方式については、Aurora Blue/Green deployment なども検討してみましたが、問題が発生した時の切り戻しが複雑な点や、IaCツールとの相性が悪いことから採用を見送りました。
MySQL8で挙動が変わり修正が必要だった箇所
あまり多くはなかったですが軽微なところで並び順や空文字比較の箇所に影響が出ました
-
暗黙的なソートが発生している箇所で並び順に影響が出る問題
-
GROUP BY未使用箇所でもORDER BYの最適化の影響か挙動が変わるケースがありました
-
対応としてはソート順でorder byを明示することで解決しています
order('companies.id asc'). order('users_belong_to_companies.role asc'). + order('users.id asc') end
-
-
日付型に対して空文字で比較指定をしてる箇所がエラーになる問題
-
MySQL5.7でもWarningだったのですがMySQL8からはエラーが吐かれるようになり発覚
-
対応としてはフィールドの型が日付型の場合は判定条件を変えるようにしました
- return query.concat( - [ - "#{table}.#{field} IS NULL", - "#{table}.#{field} = ''", - "#{table}.#{field} #{direction}", - "#{DEFAULT_TABLE}.id #{direction}", - ], - ).join(', ') + # MySQL8から日付型の空文字比較でエラーになるためOrderByの条件を変更する + if DATE_FIELDS.include?(field) + return query.concat( + [ + "#{table}.#{field} IS NULL", + "#{table}.#{field} #{direction}", + "#{DEFAULT_TABLE}.id #{direction}", + ], + ).join(', ') + else + return query.concat( + [ + "#{table}.#{field} IS NULL", + "#{table}.#{field} = ''", + "#{table}.#{field} #{direction}", + "#{DEFAULT_TABLE}.id #{direction}", + ], + ).join(', ') + end
-
総括
QAメンバーによる高精度の総合テスト、MagicPodを使用したE2Eの自動デグレードチェック、そして開発メンバーが日々努力しているユニットテストの向上のおかげで、大きな障害もなく最小限の工数でMySQL 8へのアップグレードを無事成功させることができました!
今回の成果は、開発チームが一丸となって取り組んだ結果だと考えています。
もし本記事が誰かのお役に立てると幸いです。
もっと、アルダグラムのエンジニア組織を知りたい人は、下記の情報をチェック!
株式会社アルダグラムのTech Blogです。 世界中のノンデスクワーク業界における現場の生産性アップを実現する現場DXサービス「KANNA」を開発しています。 採用情報はこちら: herp.careers/v1/aldagram0508/
Discussion