Aurora MySQL 2 の EOS に備えて DB のバージョンアップテストを行う

こんにちは。

本投稿では、Aurora MySQL 2 の EOS と Aurora MySQL 3 へのバージョンアップについての情報を提供するとともに、SQL テストツールを使って、バージョンアップテストを効率化する方法を紹介します。

## はじめに

いよいよ Amazon Aurora MySQL 2 の EOS ( end of support、サポート終了 ) が2024年10月にやってきます！※余談ですが、EOL ( end of life ) と言う場合もあります。

移行 ( バージョンアップ ) の準備は進んでいますか？

また、Aurora MySQL 同様、現在 Amazon RDS for MySQL 5.7 を利用している場合も、同様の、2023年10月にEOSを迎えます。RDS for MySQL 8 へバージョンアップされる方もいられると思いますし、これを機に Aurora へ移行されるケースもあるかもしれません。

参考）
* [Amazon Aurora バージョン - Amazon Aurora メジャーバージョンが利用可能な期間](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.VersionPolicy.html#Aurora.VersionPolicy.MajorVersionLifetime)
* [Amazon RDS での MySQL のバージョン - Amazon RDS でサポートされている MySQL のメジャーバージョン](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/MySQL.Concepts.VersionMgmt.html)

## バージョンアップの際に重要となるテスト

EOS タイミングへ向けて、バージョン切り替えを計画し、テストなどを行っていくと思います。

さて、どのようにテストしますか？

おそらく多くの方が実施されている、バージョンアップしたテスト環境を用意し、アプリケーションを接続して一通り確認するアプリケーションテスト。多くの対象 DB があったり、時間的な制約があったりすると、テストもかなり大変であろうことは容易に想像できます。

ここに SQL テストを利用することで、効率的にテストのカバレッジを上げるツールが本投稿で紹介する『Insight SQL Testing』です。

本投稿では、Aurora MySQL 2 または RDS for MySQL 5.7 から、Aurora MySQL 3 または RDS for MySQL 8 への移行 ( バージョンアップ ) において、Insight SQL Testing を使って SQL アセスメントを行い、移行時のリスクを低減する方法をご紹介します。Aurora MySQL 2 から Aurora MySQL 3 へのバージョンアップを想定して手順を紹介しますが、RDS for MySQL 5.7 から RDS for MySQL 8 へのバージョンアップでも同様の手順となります。

## MySQL 5.7 から 8 へバージョンアップする際の互換性のない変更

さて、MySQL 8 ではどんな変更が入っているでしょう？

MySQL 5.7 (Aurora MySQL 2) から MySQL 8 (Aurora MySQL 3) へバージョンアップ際に問題になりそうな、いくつかの互換性のない変更をご紹介します。また、特にSQLに関する互換性のない変更は、既存アプリケーションからの MySQL 利用に大きな影響を与える可能性があります。

* 予約語の追加
* `GROUP BY` 句のソートの挙動変更
  * 8.0.12 までは `GROUP BY` の使用により暗黙的なソートが行われていましたが、8.0.13 以降は行われなくなりました。

特に後者の変更について注目すべきは、MySQL 8 の途中のマイナーバージョンから変更になっていることと、SQL 実行がエラーにはならないため、挙動の変更に気づきづらいことでしょうか？

参考）
* [MySQL 8.0 での変更](https://dev.mysql.com/doc/refman/8.0/ja/upgrading-from-previous-series.html)
* [MySQL 8.0 での変更 - SQL の変更](https://dev.mysql.com/doc/refman/8.0/ja/upgrading-from-previous-series.html#upgrade-sql-changes)

## SQL テストによるバージョンアップテスト

バージョンアップの確認を目的とした SQL テストでは、あらかじめ何らかの手段で用意した SQL が、バージョンアップ前とバージョンアップ後で同じ挙動をするかを確認します。

1. SQL の用意
1. テスト用データベースの用意
1. 用意した SQL をテスト用データベースに対して実行
1. 実行結果の集計・評価

SQL テストで必要となる「SQL の用意 ～ SQL のテスト ～ 結果の評価」の流れを手作業で行うのには膨大な労力を要します。ここで使用する Insight SQL Testing を使うと、この一連の作業を簡単に行うことができます。

### SQL の用意について

Insight SQL Testing を用いた Aurora MySQL のバージョンアップテストでは、テスト対象の SQL を複数の手段で用意可能です。

* Aurora MySQL の general.log を事前に AWS コンソールなどから取得する
* Insight SQL Testing から RDS API 経由で Aurora MySQL の general.log を取得する

なお、SQL の情報については事前にログへ出力するように設定しておきます。本投稿では、後者の RDS API 経由で Aurora MySQL の general.log を取得する方法について紹介します。

## 事前準備

### Aurora MySQL 2 で SQL 情報をログへ出力する

現行稼働環境の Aurora MySQL では SQL の情報を出力するよう、クエリーログの出力を有効にします。Aurora MySQL の場合、クラスターパラメータグループで以下のような設定を行います。

* `general_log` を `on`に設定します。
* `log_output` を `FILE` に設定します。

参考）
* [Insight SQL Testing マニュアル - RDS for MySQL、Amazon Aurora(MySQL互換エディション)](https://support.insight-tec.com/product/idt/latest/manual/#_rds_for_mysqlamazon_auroramysql%E4%BA%92%E6%8F%9B%E3%82%A8%E3%83%87%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3)

### Insight SQL Testing の起動

Insight SQL Testing のマネージャーである IDT Manager を起動します。IDT Manager は AWS Marketplace で提供しているため、通常の EC2 を起動する流れで簡単に IDT Manager を起動することができます。

RDS API 経由で Aurora MySQL の general.log を取得するためには、Insight SQL Testing の EC2 に必要なロールが設定されている必要があります。

参考）
* [Insight SQL Testing マニュアル - IDT Managerの構築と設定(EC2の場合)](https://support.insight-tec.com/product/idt/latest/manual/#_idt_manager%E3%81%AE%E6%A7%8B%E7%AF%89%E3%81%A8%E8%A8%AD%E5%AE%9Aec2%E3%81%AE%E5%A0%B4%E5%90%88)
* [Insight SQL Testing マニュアル - 必要なIAM設定について](https://support.insight-tec.com/product/idt/latest/manual/#_%E5%BF%85%E8%A6%81%E3%81%AAiam%E8%A8%AD%E5%AE%9A%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)の「Amazon RDSからログを取得しての評価SQLセットの作成を行う場合」の部分

### テスト用の Aurora MySQL クラスターの用意

使用する Aurora MySQL クラスターとして以下のものを使用します。

* 旧バージョンの現行稼働環境 (ソースDB、Amazon Aurora MySQL 2、SQL取得元のAurora Cluster)
* 旧バージョンのテスト環境 (テスト用ソースDB、Amazon Aurora MySQL 2)
* 新バージョンのテスト環境 (ターゲットDB、Amazon Aurora MySQL 3)

![test_configuration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/c604d569-db6a-7384-5a81-53f9e8d3cc71.png)

「旧バージョンのテスト環境」「新バージョンのテスト環境」については、取り込んだ SQL をテスト実行する DB となり、データなどは揃えておく必要があります。スナップショットなどから起動してください。

## Insight SQL Testing によるアセスメント

Insight SQL Testing によるアセスメントは以下の流れで行います。
* テスト用の Aurora MySQL クラスターの登録
* 評価 SQL セットの作成 (テスト SQL の登録)
* アセスメントの実行

### テスト用の Aurora MySQL クラスターの登録

* テスト用の Aurora MySQL クラスターをターゲット DB として登録します。 \
![create_target_db.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/0af1695b-48fd-8320-46e6-d574f95bfb0b.png)
* 旧バージョン、新バージョンの双方を登録します。 \
![created_target_dbs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/3e7268cc-c4c2-04cc-7019-e60bb6f2dcd9.png)

参考）
* [Insight SQL Testing マニュアル - ターゲットDBの追加](https://support.insight-tec.com/product/idt/latest/manual/#_%E3%82%BF%E3%83%BC%E3%82%B2%E3%83%83%E3%83%88db%E3%81%AE%E8%BF%BD%E5%8A%A0)

### 評価 SQL セットの作成

* 評価 SQL セットの「新規作成」を選択し、「Amazon RDS から SQL を取得する」を選択します。 \
![create_sql_set2_from_rdsapi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/dc22c10f-6ae3-b144-d221-4e4c651d09be.png)
* リージョン、クラスター ID、データベース名を入力し、処理を開始します。作成が終了すると評価 SQL セット一覧へ表示されます。 \
![created_sql_set.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/e687c8d4-763b-2830-5a60-e2d110749e91.png)

### アセスメントの実行

評価 SQL セットが作成できたら、アセスメント (SQL テスト) を実行します。

* アセスメントの「新規作成」で、「2DB モード」を有効にします。
* 作成した評価 SQL セットを選択します。
* ターゲット DB には移行先 (Aurora MySQL 3 向けに作成したターゲット DB) を設定し、テスト用ソース DB には、現行バージョン (Aurora MySQL 2 向けに作成したターゲット DB) を設定します。
* 実行タイプには「実行」を選択し、ユーザーパスワードを入力したら、「新規作成」をクリックします。細かい比較オプションについてはマニュアルを確認してください。 \
![assessment_new_exec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/de289c68-62d1-4a4f-e965-a8f135690467.png)
* SQL 数が多い場合のアセスメントの進行状況は一覧画面で確認できます。

参考）
* [Insight SQL Testing マニュアル - アセスメントの新規作成（Insight DT 3.5以降）](https://support.insight-tec.com/product/idt/latest/manual/#_%E3%82%A2%E3%82%BB%E3%82%B9%E3%83%A1%E3%83%B3%E3%83%88%E3%81%AE%E6%96%B0%E8%A6%8F%E4%BD%9C%E6%88%90insight_dt_3_5%E4%BB%A5%E9%99%8D)

### アセスメント結果の確認

アセスメントが終了したら、アセスメント結果を確認してみましょう。
アセスメント結果としてまず最初に、サマリー情報を確認できます。 \
![assessment_summary_exec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/ed3919ba-ac98-160a-b2e7-fa95e7f32308.png)

サマリー画面ではエラーになった SQL の数や、エラーにはならなかったものの、クエリー実行結果が異なるものとなった SQL の数などを確認できます。
サマリー画面から詳細をたどっていくと、個別の SQL についての挙動の違いを確認することができます。確認してみると、以下の SQL が結果が異なる SQL として検出されています。

```sql
select max(ename) from emp group by ename;
```
![assessment_sql_detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/8f15263a-d9e1-0c3a-eeec-2b102c2412d1.png) \
![assessment_sql_detail_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3480312/439b35b8-6b0c-01b4-dafd-e2a94cd42bb6.png)

実際に取得された結果セットを確認すると、結果の順序が異なってることがわかります。Aurora MySQL 2 での実行結果 ( 左側のペイン ) は、結果が ename でソートされています。これがまさに「`GROUP BY` 句のソートの挙動変更」に該当するものです。

## おわりに

本投稿では、来年に迫ってきている Aurora MySQL 2 の EOS に伴うバージョンアップ確認作業について、Insight SQL Testing による SQL テストを活用する方法を紹介しました。

## 更新情報
* 2024/4/1: Insight Database Testingの製品名がInsight SQL Testingへ変更になったのでそれにあわせて更新しました