1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Aurora MySQL のメジャーアップグレードで学んだこと 将来のバージョンアップでも武器に

1
Posted at

はじめに 実戦で踏んだ罠まとめ

Amazon Aurora MySQL v2(MySQL 5.7互換)の標準サポートは2024年10月末で終了しており、現在は RDS Extended Support(延長サポート、有償) で延命している。

本記事では、Aurora MySQL v2 → v3(MySQL 8.0互換)への インプレースアップグレード にフォーカスして、

  • 事前準備〜当日作業の具体的なタイムライン
  • 切り戻し(ロールバック)計画
  • 実戦で踏みやすい罠とその回避策

をまとめます。

将来の v3 → v4 移行でも武器に出来るように参考にして頂けると幸いです。

本記事は「インプレース」中心の構成ですが、最後に Blue/Green Deployment との使い分け にも触れます。


1. アップグレードの2大手法

項目 インプレース(In-place) Blue/Green Deployment
概要 既存クラスターを直接アップグレード 同期された Green 環境を作って切り替え
ダウンタイム あり(数分〜数十分) 最小限(切り替え時に数十秒程度)
切り戻し スナップショットからの復元が必要 Green を破棄するだけで容易
作業難易度 低(AWSが自動処理) 中〜高(レプリ監視・切替制御が必要)
コスト 一時的に環境2面分

選択基準のざっくり目安

  • 検証環境・社内向けシステム・深夜停止OKなら インプレース
  • 24/365稼働の本番、ダウンタイムを極小化したいなら Blue/Green

2. 事前計画・事前準備(〜1ヶ月前〜数日前)

インプレースの成否は 事前準備で9割決まります

2-1. インスタンスタイプの確認と変更

Aurora v3 は古い世代のインスタンス(t2, r4 など)が サポート対象外 です。

該当する場合は、事前メンテで t3 / r6g / r7g などへ変更しておきます。

# 現行インスタンスタイプの確認
aws rds describe-db-instances \
  --db-instance-identifier your-db-instance \
  --query 'DBInstances[].DBInstanceClass'

2-2. 8.0用パラメータグループの新規作成

5.7用のパラメータグループは流用できません。新規作成して、5.7でカスタマイズしていた値を精査しながら移植します。

特に確認すべきパラメータ

  • sql_mode(後述。最重要)
  • character_set_server / collation_server
  • lower_case_table_names8.0は初期化時しか変更不可
  • default_authentication_plugin
  • time_zone
  • max_connections
  • innodb_*
  • binlog_*

2-3. 事前互換性チェック(Upgrade Checker)

AWS CLI で --dry-run 相当の事前チェックを走らせ、ログを error.log から取得します。

aws rds modify-db-cluster \
  --db-cluster-identifier your-cluster \
  --engine-version 8.0.mysql_aurora.3.07.1 \
  --allow-major-version-upgrade \
  --no-apply-immediately

実際にチェックされた結果は CloudWatch Logs のアップグレードログに出力されるので、エラー・警告は1件残らず潰します

2-4. クローン機能でリハーサル

Aurora の Clone はストレージコピーが発生しないため、本番と同じデータで瞬時に検証環境を作れます。

aws rds restore-db-cluster-to-point-in-time \
  --source-db-cluster-identifier your-cluster \
  --db-cluster-identifier your-cluster-clone \
  --restore-type copy-on-write \
  --use-latest-restorable-time

ここで 必ず実測すべきこと

  1. アップグレード完了までの所要時間(→ 当日のメンテ枠の基準)
  2. アプリからの参照・更新クエリの動作
  3. スロークエリ・実行計画の劣化有無
  4. バッチ処理の正常終了

3. 当日作業タイムライン(メンテ枠2時間想定)

時刻 フェーズ 作業内容 ポイント
01:00 アプリ停止 アプリ停止 / メンテ画面切替 DBへの書き込みを完全ゼロに
01:15 接続確認 SHOW PROCESSLIST; でセッション確認 残存セッションを切断
01:20 安全確保 手動スナップショット取得 切り戻しの命綱。完了まで待機
01:40 UG実行 コンソール or CLI でバージョン変更 パラメータグループも8.0用へ
01:40〜02:10 待機 自動処理を監視 リハーサル時間が目安
02:10 起動確認 「Available」状態 / error.log 確認 異常ログがないか精査
02:20 疎通確認 主要クエリ・主要画面の動作検証 事前作成のチェックリストを使う
02:40 サービス再開 メンテ画面解除 段階的にトラフィックを戻す
03:00 経過観察 CPU / メモリ / スロークエリ監視 直後の負荷スパイクに注意

切り戻し(ロールバック)計画

インプレースには「元に戻すボタン」がありません。失敗時は以下の手順:

  1. 作業前スナップショットから新クラスター(5.7)を復元
  2. Route 53 / アプリ設定でエンドポイントを切替
  3. アプリ起動・暫定復旧

Go/No-Go判断基準を必ず事前に決める

「02:30 までにアップグレードが完了しなければ、切り戻し処理を開始する」

スナップショット復元は数十分〜数時間かかります。デッドラインを設定しないと、判断が遅れて朝を迎える事故が起きます。

4. 実戦で踏みやすい罠まとめ

事前チェックをすり抜けて当日に牙を剥いてくる地雷たちです。

罠1:新・予約語の衝突

MySQL 8.0 ではウィンドウ関数導入に伴い予約語が増えています。

特に危険な単語:

  • rank
  • groups
  • window
  • system
  • role
  • lead / lag
-- 5.7では動くが、8.0では構文エラー
SELECT rank FROM user_score;

-- 8.0でも動く(バッククォートでエスケープ)
SELECT `rank` FROM user_score;

回避策: ソースコード全体と DB スキーマを grep で洗い出し、該当箇所をエスケープ or 改名。

罠2:sql_mode の厳密化

特に ONLY_FULL_GROUP_BY が牙を剥きます。

-- 5.7(デフォルト)では動くが、8.0では一発アウト
SELECT user_id, name, COUNT(*)
FROM orders
GROUP BY user_id;
-- → name が GROUP BY にも集計関数にもない!

回避策: クエリ修正が王道。間に合わない場合はパラメータグループから ONLY_FULL_GROUP_BY を一時的に外す運用回避。

罠3:デフォルト Collation 変更による JOIN 激重化

8.0 のデフォルト照合順序が utf8mb4_general_ciutf8mb4_0900_ai_ci に変更。

-- 異なる Collation の JOIN はインデックスが効かずフルスキャン
SELECT *
FROM table_a a
JOIN table_b b ON a.code = b.code
-- a.code が utf8mb4_general_ci, b.code が utf8mb4_0900_ai_ci だとアウト

症状: アップグレード直後から CPU が 100% に張り付く。

回避策

  • パラメータグループで collation_server を 5.7 時代に合わせる
  • アプリ側の接続文字列で明示的に文字コードを指定
  • 既存テーブル定義の COLLATE を統一

罠4:クエリオプティマイザの実行計画変化

コストモデルが一新されているため、5.7 では速かったクエリが 8.0 で遅くなることがあります。

確認すべきクエリパターン:

  • 複雑な JOIN(特に3テーブル以上)
  • サブクエリ(特に相関サブクエリ)
  • ORDER BY + LIMIT
  • GROUP BY を含む大量データ集計
  • インデックスヒント依存の SQL

回避策: クローン環境のロードテストでスロークエリログを必ず比較。最悪 FORCE INDEX で明示。

罠5:認証プラグインの変更

8.0 のデフォルト認証が mysql_native_passwordcaching_sha2_password に変更。

影響を受けやすい環境:

  • 古い JDBC / Connector/J
  • PHP の古い mysqlnd
  • Python PyMySQL の古いバージョン
  • Node.js mysqlmysql2 ではない方)
  • 接続プール / RDS Proxy

回避策:

  • パラメータグループで default_authentication_plugin = mysql_native_password に固定
  • またはアプリ側ドライバを最新化

罠6:コメント欄の不正バイトでアップグレード自体がクラッシュ

地味だが本当に多い罠。過去に古いツールで登録されたテーブル・カラムの COMMENT に、UTF-8 として不正なバイト(Shift_JIS の残骸など)が含まれていると、8.0 のデータディクショナリ移行処理で内部エラーになります。

-- 不正なコメントを探す
SELECT table_schema, table_name, table_comment
FROM information_schema.tables
WHERE table_comment REGEXP '[^[:print:][:space:]]';

SELECT table_schema, table_name, column_name, column_comment
FROM information_schema.columns
WHERE column_comment REGEXP '[^[:print:][:space:]]';

回避策: 事前チェックログで Invalid や文字コード関連エラーを徹底的に確認。怪しいコメントは事前にクリーンアップ。

罠7:lower_case_table_names の変更不可問題

8.0 からは クラスター初期化時にしか設定できません

5.7 のパラメータグループの値を引き継ごうとして不整合になり、アップグレードが拒否されるケースがあります。

回避策: 8.0 用パラメータグループは「現行と同じ値」を明示的に設定。値が異なる場合は 新規クラスター作成 + データ移行 が必要。

罠8:Aurora v3 はメモリを多く食う

内部構造の変更により、何もしなくても v2 比で数 GB 多くメモリを消費します。

症状: db.t3.mediumdb.r5.large で限界運用していた環境で、アップグレード直後に OOM Killer で DB が落ちる。

回避策: アップグレードと同時に 1 サイズ上のインスタンスへスケールアップを強く推奨。

罠9:ストアド・ビュー・トリガー・イベントの破損

アプリ SQL の検証だけでは見落とすポイント。

-- 確認用クエリ
SHOW PROCEDURE STATUS WHERE Db = 'your_db';
SHOW FUNCTION STATUS WHERE Db = 'your_db';
SHOW TRIGGERS FROM your_db;
SHOW EVENTS FROM your_db;
SHOW FULL TABLES WHERE Table_type = 'VIEW';

回避策: クローン環境ですべての DB オブジェクトを一度実行してみる。INVALID 状態や実行時エラーがないか確認。

罠10:バイナリログ・レプリケーション関連

binlog のフォーマットや GTID 関連の挙動が変わっており、外部システムへのレプリやデータ連携基盤(DMS, Kafka Connect など)が止まることがあります。

回避策: binlog を消費している下流システムをすべて棚卸しし、互換性を確認。

罠11:パスワード有効期限

default_password_lifetime のデフォルト値挙動が変わっており、運用しているうちに突然アプリ用ユーザーのパスワードが期限切れになるケースがあります。

-- パスワード無期限化(運用上必要なら)
ALTER USER 'app_user'@'%' PASSWORD EXPIRE NEVER;

5. チェックリスト

## 事前準備
- [ ] インスタンスタイプが v3 サポート対象か確認
- [ ] 8.0用パラメータグループ作成
- [ ] sql_mode の差分精査(ONLY_FULL_GROUP_BY)
- [ ] character_set / collation の整合確認
- [ ] lower_case_table_names の値確認
- [ ] default_authentication_plugin の方針決定
- [ ] 事前互換性チェック実行 + ログ精査
- [ ] 予約語 grep(rank, groups, window, system, role)
- [ ] スキーマ COMMENT の不正バイト確認
- [ ] ストアド・View・Trigger・Event 棚卸し
- [ ] アプリ側 DBドライバのバージョン確認
- [ ] RDS Proxy / 接続プール経由の疎通確認
- [ ] binlog 下流システムの互換性確認
- [ ] クローン環境でアップグレードリハーサル
- [ ] 所要時間の実測
- [ ] スロークエリ比較・EXPLAIN 比較
- [ ] バッチ処理の通し検証
- [ ] 切り戻し手順書の作成
- [ ] Go/No-Go判断時刻の合意

## 当日作業
- [ ] アプリ停止 / メンテ画面表示
- [ ] 接続セッション 0 確認
- [ ] 手動スナップショット取得(完了確認)
- [ ] アップグレード実行
- [ ] error.log 監視
- [ ] Available 状態確認
- [ ] 主要クエリ動作確認
- [ ] 主要画面の動作確認
- [ ] メンテ画面解除
- [ ] CPU / メモリ / スロークエリ監視(最低1時間)

## 切り戻し(必要時)
- [ ] スナップショットから 5.7 クラスター復元開始
- [ ] DNS / 接続先切替
- [ ] アプリ起動
- [ ] 関係者へ報告

6. まとめ

Aurora MySQL のメジャーアップグレードは、「エンジンを上げるだけ」ではありません

  • SQL 互換性
  • パラメータ
  • 認証方式
  • 実行計画
  • 文字コード / Collation
  • アプリ接続ドライバ
  • メモリ使用量
  • DB オブジェクト
  • 下流システム連携

これらが まとめて変わる のが本質的な難しさです。

延長サポートのコストを考えると早期移行のメリットは大きいですが、焦って一発本番アップグレードを敢行するのは絶対NG。クローン環境でのリハーサルを最低2回は実施し、想定外を想定内に変える地道な作業が、結局は最短ルートです。

仕組みで解決する」という観点で言えば、社内に Aurora アップグレード手順書テンプレートを残し、次回以降は誰でも再現できる状態にしておくことも大切です。チェックリストとリハーサル手順をパッケージ化しておくと、将来の v3 → v4 移行でも武器になります。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?