前段
来たる 2024年10月31日
に、Amazon Aurora for MySQL 2 (MySQL 5.7 互換)
の AWS 標準サポートが終了し、Aurora for MySQL 3 (MySQL 8.0 互換)
への強制メジャーアップグレードが行われる。
このまま放置すればほぼ確実にクリティカルな問題が発生すること請け合いなため、これに先んじてアップグレード作業を実施することが現職での自分の最後の大きな務めとなった。
事前調査
以下、まずは問題となりそうなポイントの洗い出し作業を行った!
DEFAULT COLLATION
の変更
- 概要
-
MySQL 5.7
ではデフォルト照合順序がlatin1_swedish_ci
だったが、MySQL 8.0
ではutf8mb4_0900_ai_ci
に変更となる
-
- 確認
- クエリを発行し現状確認をした上で、マイグレーションファイルなどを確認し影響範囲の見定めを行った。確認の結果、デフォルトである
latin1_swedish_ci
のまま設定している箇所は見当たらず、問題無しと判断- DB 単位
SELECT @@collation_database;
- テーブル単位
SHOW TABLE STATUS FROM データベース名;
- DB 単位
- クエリを発行し現状確認をした上で、マイグレーションファイルなどを確認し影響範囲の見定めを行った。確認の結果、デフォルトである
- 参考
-
Changes in MySQL 8.0.1 (2017-04-10, Development Milestone)/Character Set Support
The default value of the collation_server and collation_database system variables has changed from latin1_swedish_ci to utf8mb4_0900_ai_ci
-
Changes in MySQL 8.0.1 (2017-04-10, Development Milestone)/Character Set Support
クエリキャッシュ機能の削除
- 概要
- MySQL 5.7 で有効だったクエリキャッシュ機能は、8.0 において完全に削除された。当初はパフォーマンス向上目的で導入されたが、スケーラビリティ観点で問題があり廃止される運びとなった模様
- 広範囲にロックを取るため、複数セッションから同時にクエリを発行されると競合が起こり、高速化しないという問題があったとか
- MySQL 5.7 で有効だったクエリキャッシュ機能は、8.0 において完全に削除された。当初はパフォーマンス向上目的で導入されたが、スケーラビリティ観点で問題があり廃止される運びとなった模様
- 確認
- これに関しては、幸い MySQL のキャッシュヒットを主眼としたチューニングや実装は行っておらず、クエリパフォーマンスに問題のある場合は
Redis
を使用してキャッシュ化などが行われていたため、問題無しと判断- 念のため先行してステージング環境でのアップグレードを行った上で様子見。本番でもアップグレード後、経過を見ることとした
- これに関しては、幸い MySQL のキャッシュヒットを主眼としたチューニングや実装は行っておらず、クエリパフォーマンスに問題のある場合は
インスタンスクラスのサポート制限
- 概要
-
db.r4
以下のサイズのインスタンスクラスは、Aurora for MySQL 3
へのアップグレード後、使用できなくなる
-
- 確認
- 現状の各インスタンスサイズが上記サイズを上回っていることを確認
パラメータ変更
- 概要
- Aurora MySQL 設定パラメータ に変更が発生し、クラスター・インスタンスレベルのそれぞれにおいて、削除されるものや追加されるものが多数存在する
- 確認
- これも幸いと言っていいのか、ゴリゴリパラメータチューニングを行うような対応は行われておらず、ほぼデフォルト設定通りであったので、以下確認により問題無しと判断
- AWS コンソール画面上で設定しているパラメーターグループを確認し、「ソース」という項目が
Modified
となっているものはデフォルトから変更が加えられており、System default
となっているものはデフォルト通りであると確認できる
- AWS コンソール画面上で設定しているパラメーターグループを確認し、「ソース」という項目が
- これも幸いと言っていいのか、ゴリゴリパラメータチューニングを行うような対応は行われておらず、ほぼデフォルト設定通りであったので、以下確認により問題無しと判断
AUTO_INCREMENT
値に関する注意点
- 概要
-
Aurora for MySQL
のVersion 3
では各インスタンスの再起動時にテーブル毎のAUTO_INCREMENT
値を保持するが、2
では保持されない。よって、スナップショットからの復元やクラスターのクローン作成により新しいクラスターを設定する場合、各AUTO_INCREMENT
はその時点での最大列値に基づいて初期化されてしまう
-
- 確認
- 念のため現状
AUTO_INCREMENT
を使用している箇所を洗い出し。使用している場合、物理削除を許容しているかどうかを判断基準とした(最新のレコードが物理削除されている場合、そのAUTO_INCREMENT
値が失われてしまう恐れがある)。これも、現仕様でAUTO_INCREMENT
を使用・かつ物理削除を許容している箇所が見られず、問題無しと判断
- 念のため現状
SQL やデータ構造が一部非互換に
- 概要
- 一例として、以下のような構文・データ構造の変更が発生した
-
GROUP BY
句からASC
・DESC
修飾子が削除された -
GROUP BY
句を使っていて、条件的に一意に定まらないカラムをSELECT
句で指定している場合、エラーが発生するようになった - 予約語が追加された(参考:9.3 キーワードと予約語)
-
WHERE
句において、YYYY
やYYYY-MM
形式での日付指定を行った場合、エラーが発生するようになった(YYYY-MM-DD
は OK)
-
- 一例として、以下のような構文・データ構造の変更が発生した
- 確認
- 各発行クエリを順に見て、問題箇所が無いか確認を行った。コチラも幸い問題無かったが、念のため一部リファクタを加えた(
SELECT
句におけるテーブル名を明示的にするなど)
- 各発行クエリを順に見て、問題箇所が無いか確認を行った。コチラも幸い問題無かったが、念のため一部リファクタを加えた(
- 参考
その他
- 概要
- その他、無数にある項目をシラミ潰しに確認。その際には、Aurora MySQL バージョン 2 と Aurora MySQL バージョン 3 の比較 を重点的に確認した。特に注意が必要そうな箇所は、別途調査を行うという流れで確認を進めていった
- 確認
- 注意が必要な項目は上述のように一つずつ確認していったが、事前の全体チェックにおいてはチェッカーも使用した
-
util.checkForServerUpgrade() 関数
を使用(参考:8.1 アップグレードチェッカユーティリティ)
-
- 注意が必要な項目は上述のように一つずつ確認していったが、事前の全体チェックにおいてはチェッカーも使用した
実アップグレード作業
Sandbox 環境下での、Terraform による検証
- 概要
- 対象環境に関しては元は
Terraform
管理がされ切っていなかったが、関係者と相談の上で、事前に既存スナップショットからの復元によりTerraform
化 - その後、Snadbox 環境下にて、アップグレード作業のリハーサルを行った
- 対象環境に関しては元は
- 確認
- まず Snadbox 環境下にて既存と同等の環境を
terraform apply
- その状態で、
In-Place Upgrade
を実施し、検証を行った
- まず Snadbox 環境下にて既存と同等の環境を
- 注意
- ※特に詰まったのは、
terraform plan
時には現れない、terraform
内部での依存関係や実行順序だった- 例えば本ケースでは、以下の順序を経なければならない
1. 最初に、新しいパラメーターグループを作成
2. クラスター・インスタンスを順にアップグレード
3. 最後に、古いパラメーターグループを削除 - しかしこれが、設定や内部的な依存関係により、まだクラスターに紐付いている古いパラメーターグループを先に削除しようとしてコケるという実行時にしか確認できない問題などが発生して手間取った
- 例えば本ケースでは、以下の順序を経なければならない
- ※特に詰まったのは、
- ポイント
- パラメーターグループの
family
をaurora-mysql8.0
とした上で、name
を既存のものから変更(例えば末尾に-mysql8
を付与)し、lifecycle
にcreate_before_destroy = true
を設定する- この
create_before_destroy
設定があることにより、パラーメーターグループを先に削除しようとするデフォルトの挙動を変更することが可能となり、エラーを防げる
- この
- クラスターに
allow_major_version_upgrade = true
設定を追加する -
内部的な依存関係・それによる実行順序に注意する
- ※特に自分が引っ掛かった(気付けなかった)ポイントがコレで、特定 resource 内で他 resource の参照を行うと内部的に依存関係(
depends_on
)が発生する- 例えば、
resource "rds_cluster_parameter_group"
があるとして、別resource
内でlocal.rds_cluster_parameter_group
として参照させると、依存関係が発生する - このせいで当初は、実施したかったクラスター・インスタンスの
In-Place Upgrade
ではなく、Recreate
の実行計画となってしまい、中々上手くいかなかった - まずパラメーターグループの設定を一番始めに持ってきて、内部で
create_before_destroy
を指定・その上で、クラスターからそのリソース名を指定してパラメーターグループとの依存関係を発生させることで、想定通りの実行計画になるようになった!
- 例えば、
- (参考:Terraformでコードを変更していないリソースが known after apply となってしまう場合にどうすればよいか、Data Resource Dependencies(Terraform公式))
- ※特に自分が引っ掛かった(気付けなかった)ポイントがコレで、特定 resource 内で他 resource の参照を行うと内部的に依存関係(
- パラメーターグループの
ステージング・本番環境下それぞれでの、Terraform によるIn-Place Upgrade
の実施
- 概要
- Snadbox 環境下で散々試したので、あとは実行に移すのみ!
- 入念な調査や検証の甲斐もあり、コチラは実にスムーズに完了した!🎉
総括
特に最初、期限が間近に迫っており放っておくと強制アップグレードされてしまうというプレッシャーの中、やたら注意書きの分量が多い公式サイトや各種調査情報と睨めっこしながら、計画を練っている時が一番しんどかった。
当初は織り込んでいなかったが、Sandbox 環境下で実際に何度も検証を繰り返したことで、Terraform にかなり馴染めたし、内部挙動や注意点にも詳しくなった。これにより、安心して本番でも作業を行えたので、事前にしっかり検証して本当に良かった!🙌
これで思い残すことなく、退職できる!👋