この記事は「Medley (メドレー) Advent Calendar 2024」の18日目の記事です。
株式会社メドレーの武藤です。
担当サービスにおいて、 Amazon Aurora MySQL の v3 アップグレード対応を行いました。
本記事では、Aurora MySQL v3 アップグレードの事例について紹介します。
はじめに
Aurora MySQL v2 の 標準サポートは2024年10月31日に終了しました。
記事を執筆している2024年12月時点では、多くのサービスやシステムが v3 にアップグレードされていることと思います。
これから v3 へのアップグレード対応を目的に読まれることは少ないかもしれませんが、汎用的な DB アップグレード対応として活かせる点もあると思いますので、目を通していただけますと幸いです。
アップグレード対応の進め方
大まかな対応手順としては下記の流れで進めました。
- アップグレード内容の確認と影響調査
- 文字セット変更
- DB アップグレード
アップグレード内容の確認と影響調査
Aurora MySQL v3 は MySQL 8.0 と互換性を持ったバージョンです。アップグレード対応を始めるに当たり、MySQL 8.0 のアップグレードによる変更点とその影響を調査するところからはじめました。
MySQL 8.0 のアップグレードの内容確認は、MySQL の公式ドキュメントを参考にしました。
多数の項目がありますが、担当サービスに影響があった主な変更点は下記です。
- デフォルト文字セットの変更
- 予約語の追加
デフォルト文字セットの変更
MySQL 8.0では、デフォルトの文字セットが latin1
から utf8mb4
へ変更されました。それに加えて、utf8
( utf8mb3
のエイリアス) が非推奨となり、将来的に削除されるとアナウンスされていました。
担当サービスでも、utf8
でテキストを扱うテーブルが多数あったため、今回を機に対応することとなりました。
しかし、文字セット変更と DB アップグレードを一度に行えば、影響範囲の確認が難しくなります。
そこで今回の対応では、文字セット変更と DB アップグレードを分けて行う計画にしました。
また、Aurora MySQL としてのアップグレード内容を AWS 公式ドキュメントを参考に確認しました。
Aurora のパラメータグループにも変更がありましたので、そちらの修正内容を確認し、対応作業の中で修正していきました。
予約語の追加
MySQL 8.0 では、新たに追加された予約語がありました。
担当サービスでは、rank
がカラム名として既に使われており、これが予約語とバッティングすることがわかりました。
こちらは、カラム名を修正することで対応しました。
文字セット変更
文字セットの変更は、AWS DMS を使った DB 移行による実施を検討しました。
DMS によってターゲット DB とソース DB の同期状態を構築し、アプリケーションの接続先 DB の切り替えによって、文字セット変更を行います。
この方法は、切り替えのための作業時間が短く済みます。
下記が大まかな手順です。
- ターゲット DB を構築
- Aurora MySQL v2
- 文字セットを
utf8mb4
に設定
- ソース DB からターゲット DB にマイグレーションを設定
- レプリケーションタスクを「フルロード + CDC」 に設定
- 同期完了後、アプリケーションの接続先 DB をソース DB からターゲットDBに切り替え
ソースとターゲットDBの同期状態を構築し、メンテナンス状態で切り替え作業を行いました。
アプリケーションの接続先DBを切り替えて、動作確認を終わらせたところで、メンテナンス状態を解除しました。
しかし、メンテナンス状態の解除後、システムアラートの通知が飛んできました。
LOB 列設定の不備によるデータ欠損
アラートを調査したところ、JSON を扱う処理において JSON のデシリアライズの失敗によって例外が起きていました。
アラートの確認後、即座にメンテナンス状態へ切り替えて調査を進めました。
対象の JSON データは、ソース DB のレコードと比較すると、末尾が尻切れになっていました。
このことからデータ移行の際にデータ欠損が起きていたとわかりました。
欠損しているデータの傾向から、バイトサイズが大きいレコードのみで起きていることがわかりました。
調査の結果、今回の原因は DMS の Large Object Binary (LOB) 設定の不備であったとわかりました。
今回の DMS の LOB 列設定では、デフォルトの 32KB が指定されていました。該当レコードは、バイトサイズが32KBを超えていたため、欠損してしまいました。
下記は今回発生したデータ欠損の条件です。
- longtext 型のカラム
- LOB 列設定を超えるバイトサイズ(32KB以上)
不具合の対応は、リストアップした欠損データを正しいデータに更新することで対応しました。
DBアップグレード
トラブルはありましたが、文字セット変更を完了し、いよいよアップグレード対応を進めました。
DB アップグレードは、RDS の「ブルー/グリーンデプロイ」で進めていきました。
DB アップグレードでは、切り替え時に不具合が起きないよう対策を検討しました。
検討の結果、下記3点の課題が出てきました。
- レプリケーションのデータ整合性検証
- Aurora MySQL v3のパフォーマンス
- 切り替え作業時の切り戻し方法
レプリケーションのデータ整合性検証
文字セット変更では、LOB 列設定の不備によってデータ欠損が起きてしまいました。
そのためデータ整合性について、慎重に確認を進めていきました。
今回はブルー/グリーンデプロイを利用するため、レプリケーションで差分が起きる可能性は低いと考えましたが、万が一に備えて事前に整合性の検証することにしました。
下記の手順でデータ整合性の検証を行いました。
- ブルー/グリーンデプロイ構築
- ブルーとグリーンのそれぞれの DB からスナップショットを取得
- スナップショットから検証用 DB を構築
- 検証用DBに対して、データの整合性検証を行うスクリプトを実行
この方法では、検証用 DB に対してスクリプトを実行するため、本番に影響なく実施できました。
Aurora MySQL v3のパフォーマンス
事例調査から、 Aurora MySQL v3 ではパフォーマンス劣化の懸念がありました。
そのため、事前にパフォーマンス検証を行いました。
パフォーマンス検証は、ブルーとグリーンDBに対し、 Route 53 の加重ルーティングによって同程度のトラフィックを流すことで行いました。
Performance Insights や各種メトリクスの数値比較によって検証を行いました。
切り替え後の切り戻し方法
ブルー/グリーンデプロイでは、切り戻し後の旧ブルー DB はリードオンリーとなります。
そのため、ブルー/グリーンデプロイの機能だけでは切り戻しができません。
そこで、独自に切り戻し方法を確立しておく必要がありました。
DBアップグレードの対応も、メンテナンス状態で行うことを想定していました。
メンテナンス状態を前提に、下記の流れで切り戻し先DBを構築しました。
- メンテナンスのため無風状態となる
- ブルー/グリーンの切り替えを実施
- 旧ブルーからスナップショットを作成
- 旧ブルーのスナップショットから切り戻し先 DB を用意
- 新ブルー(旧グリーン)から切り戻し先 DB に DMS を設定し、レプリケーション
この手順では、スナップショットの復元に30分ほど時間がかかります。
その分メンテナンス時間が伸びてしまうことが懸念でしたが、簡単に切り戻せない状況よりコストが低いと考え、こちらを採用しました。
LOB 列設定の調整
この方法では再び DMS を利用します。
文字セット変更で起きた LOB 列設定の失敗を活かし、サイズ調整を行いました。
LOB 列設定には、3種類のモードがあります。
制限LOB付きモードでは、フルLOBモードよりも大きなパフォーマンスを得ることができます。可能な限り制限付きLOBモードを使用することをお勧めします。
ドキュメントによると制限付き LOB モードが推奨されています。データサイズを気にしないで済むフル LOB モードよりパフォーマンスがよいようです。
そして、事前に最大データサイズを確認し、適切な設定を行いました。
以上の対策の末、DB アップグレードの切り替え本番は無事故で完了できました!
まとめ
Aurora MySQL v3アップグレードの大まかな流れや発生した問題について説明しました。
文字セット変更とDBアップグレードを分けて進めたりと、事故に気をつけながら進めたつもりでしたが、思わぬところでトラブルにハマってしまいました。
この事例がなにかの参考になれば幸いです!
次回は、@shin_taro さんの記事です!お楽しみに!
最後に
メドレーでは各種エンジニアを絶賛募集中です!
どうぞお気軽にお問い合わせください!