Amazon Aurora MySQL v3アップグレード対応事例

この記事は「Medley (メドレー) Advent Calendar 2024」の18日目の記事です。

https://qiita.com/advent-calendar/2024/medley 

---

株式会社メドレーの武藤です。
担当サービスにおいて、 Amazon Aurora MySQL の v3 アップグレード対応を行いました。
本記事では、Aurora MySQL v3 アップグレードの事例について紹介します。

# はじめに

Aurora MySQL v2 の 標準サポートは2024年10月31日に終了しました。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/extended-support.html 


記事を執筆している2024年12月時点では、多くのサービスやシステムが v3 にアップグレードされていることと思います。

これから v3 へのアップグレード対応を目的に読まれることは少ないかもしれませんが、汎用的な DB アップグレード対応として活かせる点もあると思いますので、目を通していただけますと幸いです。

# アップグレード対応の進め方

大まかな対応手順としては下記の流れで進めました。

1. アップグレード内容の確認と影響調査  
2. 文字セット変更  
3. DB アップグレード


# アップグレード内容の確認と影響調査

Aurora MySQL v3 は MySQL 8.0 と互換性を持ったバージョンです。アップグレード対応を始めるに当たり、MySQL 8.0 のアップグレードによる変更点とその影響を調査するところからはじめました。

MySQL 8.0 のアップグレードの内容確認は、MySQL の公式ドキュメントを参考にしました。

https://dev.mysql.com/doc/refman/8.0/ja/upgrading.html 

  
多数の項目がありますが、担当サービスに影響があった主な変更点は下記です。

* デフォルト文字セットの変更  
* 予約語の追加

## デフォルト文字セットの変更

MySQL 8.0では、デフォルトの文字セットが `latin1` から `utf8mb4` へ変更されました。それに加えて、`utf8`（ `utf8mb3` のエイリアス） が非推奨となり、将来的に削除されるとアナウンスされていました。


https://dev.mysql.com/doc/refman/8.0/ja/charset-unicode-utf8.html 


担当サービスでも、`utf8` でテキストを扱うテーブルが多数あったため、今回を機に対応することとなりました。

しかし、文字セット変更と DB アップグレードを一度に行えば、影響範囲の確認が難しくなります。  
そこで今回の対応では、文字セット変更と DB アップグレードを分けて行う計画にしました。

また、Aurora MySQL としてのアップグレード内容を AWS 公式ドキュメントを参考に確認しました。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Compare-v2-v3.html 

Aurora のパラメータグループにも変更がありましたので、そちらの修正内容を確認し、対応作業の中で修正していきました。

## 予約語の追加

MySQL 8.0 では、新たに追加された予約語がありました。

https://dev.mysql.com/doc/refman/8.0/ja/keywords.html#keywords-new-in-current-series 


担当サービスでは、`rank` がカラム名として既に使われており、これが予約語とバッティングすることがわかりました。  
こちらは、カラム名を修正することで対応しました。

# 文字セット変更

文字セットの変更は、AWS DMS を使った DB 移行による実施を検討しました。

https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/Welcome.html 

DMS によってターゲット DB とソース DB の同期状態を構築し、アプリケーションの接続先 DB の切り替えによって、文字セット変更を行います。
この方法は、切り替えのための作業時間が短く済みます。

下記が大まかな手順です。

1. ターゲット DB を構築  
   * Aurora MySQL v2  
   * 文字セットを `utf8mb4` に設定
2. ソース DB からターゲット DB にマイグレーションを設定  
    * レプリケーションタスクを「フルロード + CDC」 に設定
4. 同期完了後、アプリケーションの接続先 DB をソース DB からターゲットDBに切り替え

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226577/3dca87c9-7eb6-da64-4f93-e80d87dbcb63.png)

ソースとターゲットDBの同期状態を構築し、メンテナンス状態で切り替え作業を行いました。
アプリケーションの接続先DBを切り替えて、動作確認を終わらせたところで、メンテナンス状態を解除しました。

しかし、メンテナンス状態の解除後、システムアラートの通知が飛んできました。

# LOB 列設定の不備によるデータ欠損

アラートを調査したところ、JSON を扱う処理において JSON のデシリアライズの失敗によって例外が起きていました。
アラートの確認後、即座にメンテナンス状態へ切り替えて調査を進めました。

対象の JSON データは、ソース DB のレコードと比較すると、末尾が尻切れになっていました。
このことからデータ移行の際にデータ欠損が起きていたとわかりました。
欠損しているデータの傾向から、バイトサイズが大きいレコードのみで起きていることがわかりました。

調査の結果、今回の原因は DMS の Large Object Binary (LOB) 設定の不備であったとわかりました。


https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_Tasks.LOBSupport.html 

今回の DMS の LOB 列設定では、デフォルトの 32KB が指定されていました。該当レコードは、バイトサイズが32KBを超えていたため、欠損してしまいました。

下記は今回発生したデータ欠損の条件です。

* longtext 型のカラム  
* LOB 列設定を超えるバイトサイズ（32KB以上）

不具合の対応は、リストアップした欠損データを正しいデータに更新することで対応しました。

# DBアップグレード

トラブルはありましたが、文字セット変更を完了し、いよいよアップグレード対応を進めました。  
DB アップグレードは、RDS の「ブルー/グリーンデプロイ」で進めていきました。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/blue-green-deployments-overview.html 

DB アップグレードでは、切り替え時に不具合が起きないよう対策を検討しました。  
検討の結果、下記3点の課題が出てきました。

* レプリケーションのデータ整合性検証  
* Aurora MySQL v3のパフォーマンス  
* 切り替え作業時の切り戻し方法

## レプリケーションのデータ整合性検証

文字セット変更では、LOB 列設定の不備によってデータ欠損が起きてしまいました。  
そのためデータ整合性について、慎重に確認を進めていきました。

今回はブルー/グリーンデプロイを利用するため、レプリケーションで差分が起きる可能性は低いと考えましたが、万が一に備えて事前に整合性の検証することにしました。

下記の手順でデータ整合性の検証を行いました。

1. ブルー/グリーンデプロイ構築 
1. ブルーとグリーンのそれぞれの DB からスナップショットを取得  
1. スナップショットから検証用 DB を構築  
1. 検証用DBに対して、データの整合性検証を行うスクリプトを実行

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226577/58460943-3a66-2d40-9a5d-d39653ad80cb.png)

この方法では、検証用 DB に対してスクリプトを実行するため、本番に影響なく実施できました。

## Aurora MySQL v3のパフォーマンス

事例調査から、 Aurora MySQL v3 ではパフォーマンス劣化の懸念がありました。  
そのため、事前にパフォーマンス検証を行いました。

パフォーマンス検証は、ブルーとグリーンDBに対し、 Route 53 の加重ルーティングによって同程度のトラフィックを流すことで行いました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226577/b50bfce2-bdd6-ad91-3664-49e4a39e5b63.png)

Performance Insights や各種メトリクスの数値比較によって検証を行いました。

## 切り替え後の切り戻し方法

ブルー/グリーンデプロイでは、切り戻し後の旧ブルー DB はリードオンリーとなります。
そのため、ブルー/グリーンデプロイの機能だけでは切り戻しができません。  
そこで、独自に切り戻し方法を確立しておく必要がありました。

DBアップグレードの対応も、メンテナンス状態で行うことを想定していました。  
メンテナンス状態を前提に、下記の流れで切り戻し先DBを構築しました。

1. メンテナンスのため無風状態となる  
2. ブルー/グリーンの切り替えを実施  
3. 旧ブルーからスナップショットを作成  
4. 旧ブルーのスナップショットから切り戻し先 DB を用意  
5. 新ブルー（旧グリーン）から切り戻し先 DB に DMS を設定し、レプリケーション

この手順では、スナップショットの復元に30分ほど時間がかかります。  
その分メンテナンス時間が伸びてしまうことが懸念でしたが、簡単に切り戻せない状況よりコストが低いと考え、こちらを採用しました。

### LOB 列設定の調整

この方法では再び DMS を利用します。  
文字セット変更で起きた LOB 列設定の失敗を活かし、サイズ調整を行いました。

LOB 列設定には、3種類のモードがあります。

https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_Tasks.LOBSupport.html 

> 制限LOB付きモードでは、フルLOBモードよりも大きなパフォーマンスを得ることができます。可能な限り制限付きLOBモードを使用することをお勧めします。

ドキュメントによると制限付き LOB モードが推奨されています。データサイズを気にしないで済むフル LOB モードよりパフォーマンスがよいようです。
そして、事前に最大データサイズを確認し、適切な設定を行いました。

以上の対策の末、DB アップグレードの切り替え本番は無事故で完了できました！

# まとめ
Aurora MySQL v3アップグレードの大まかな流れや発生した問題について説明しました。

文字セット変更とDBアップグレードを分けて進めたりと、事故に気をつけながら進めたつもりでしたが、思わぬところでトラブルにハマってしまいました。
この事例がなにかの参考になれば幸いです！

次回は、[@shin_taro](https://zenn.dev/shin_taro) さんの記事です！お楽しみに！

# 最後に

メドレーでは各種エンジニアを絶賛募集中です！
どうぞお気軽にお問い合わせください！

[https://www.medley.jp/jobs/](https://www.medley.jp/jobs/)