every Tech Blog

株式会社エブリーのTech Blogです。

【実践】RDS for MySQL 8.4アップグレード Blue/Green Deploymentsを添えて

【実践】RDS for MySQL 8.4アップグレード Blue/Green Deploymentsを添えて
【実践】RDS for MySQL 8.4アップグレード Blue/Green Deploymentsを添えて

この記事は every Tech Blog Advent Calendar 2025 の 5 日目の記事です。

 こんにちは、開発本部 開発2部 RetailHUB NetSuperグループに所属するホーク🦅アイ👁️です。

背景

 昨年に引き続きMySQL8.4についての記事を書くことにしました。続編という位置づけで実際に私の所属チームで運用しているAmazon RDS for MySQL 8.0が2026年7月31日には標準サポート終了予定になってしまうので今年のうちに8.4にアップグレードをすることになったというのが背景です。

tech.every.tv

 とはいえ、どうせアップグレードするならただin-place upgradeするより新しい試みをしてみたいと思い、公式DOCを拝読していたらAmazonのサービス機能のひとつとしてフルマネージドなBlue/Green Deployments(2022年12月GA)というものが存在していることに気がついたのでこれを使って簡単low downtimeでアップグレードしたい!となりました。

 以降、前半部分で8.0と8.4の違いについて説明します。後半部分で実践して起きた問題点なども踏まえながら話させていただきます。

バージョン8.0と8.4の変更点と対応について

 RDS for MySQL 8.0から8.4へのアップグレードにおいて、DBパラメータの設定について確認すべき重要な変更点があります。デフォルトのパラメータ設定のままでも基本的には動作しますが、以下の点を理解し、必要に応じて調整することを推奨します。

1. パラメータグループの作成

 メジャーバージョンアップグレードを行う際は、既存のカスタムパラメータグループが新しいバージョンと互換性がない場合があります。MySQL 8.4用の新しいパラメータグループを事前に作成し、アップグレード時に適用することが推奨されます。デフォルトのパラメータグループを使用している場合でも、アップグレード前に8.4用のパラメータグループに切り替えることで、アップグレード時のエラーを防ぐことができます。

参考: Amazon RDS for MySQL のメジャーバージョンアップグレードの概要

2. デフォルト値が変更されたパラメータ

 MySQL 8.4では、以下のパラメータのデフォルト値が変更されています。これらの変更が既存のアプリケーションのパフォーマンスや動作に影響を与える可能性があるため、事前に確認することが重要です。

innodb_purge_threads

  • 新デフォルト値: LEAST({DBInstanceVCPU/2},4)
  • 影響: InnoDBの履歴リストの長さが大きくなりすぎないように自動調整されます。高負荷環境では、この設定により purge スレッド数が適切に調整されます。

group_replication_exit_state_action

  • 新デフォルト値: OFFLINE_MODE
  • 影響: Group Replicationを使用している場合に影響します。通常のRDS for MySQLでは直接的な影響はありません。

binlog_format

  • 新デフォルト値: ROW
  • 影響: バイナリログのフォーマットがROW形式になります。レプリケーションを使用している場合、データの一貫性が向上しますが、ログサイズが増加する可能性があります。

innodb_change_buffering

  • 新デフォルト値: none
  • 旧デフォルト値: all
  • 影響: チェンジバッファリングが無効化されます。これにより、セカンダリインデックスへの挿入・更新操作のパフォーマンスに影響を与える可能性があります。

innodb_buffer_pool_instances

  • 新デフォルト値: innodb_buffer_pool_sizeとCPU数に基づいて動的に計算
  • 旧デフォルト値: 8(または innodb_buffer_pool_size < 1 GiBの場合は1
  • 影響: バッファプールインスタンス数が自動的に最適化されます。

参考: MySQL 8.4 What Is New - InnoDB system variable default value changes

3. アップグレード前に必須の対応事項

 以下の変更は、アップグレード前に対応しないとアップグレードが失敗する可能性があります。

FLOAT/DOUBLE列でのAUTO_INCREMENTの廃止

 MySQL 8.4では、FLOATまたはDOUBLE型の列にAUTO_INCREMENTを使用することができなくなりました。この組み合わせを使用しているテーブルが存在する場合、アップグレード前に必ず修正する必要があります。そうしないとアップグレードが失敗します。

対応方法:

-- 既存のAUTO_INCREMENTを使用しているFLOAT/DOUBLE列を確認
SELECT TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, DATA_TYPE 
FROM INFORMATION_SCHEMA.COLUMNS 
WHERE EXTRA LIKE '%auto_increment%' 
  AND DATA_TYPE IN ('float', 'double');

-- 該当する列をINTやBIGINTに変更
ALTER TABLE table_name MODIFY column_name BIGINT AUTO_INCREMENT;

パーティショニングキーでのインデックスプレフィックスの禁止

 MySQL 8.4では、パーティショニングキーにインデックスプレフィックス(例: KEY (column_name(10)))を持つ列を使用できなくなりました。該当するテーブルがある場合は、アップグレード前にパーティショニング定義を変更する必要があります。

参考: MySQL 8.4 What Is New - Features Removed

4. 認証プラグインに関する重要な変更

 MySQL 8.0では既に caching_sha2_passwordがデフォルトの認証プラグインとなっていますが、MySQL 8.4では mysql_native_passwordプラグインが無効化されています。これにより、以下の点を確認する必要があります:

  • 明示的に mysql_native_passwordを使用しているユーザーアカウントがある場合、アップグレード後に接続できなくなる
  • 既存のユーザーアカウントの認証方式を事前に確認し、必要に応じて caching_sha2_passwordに変更する
  • アプリケーションが caching_sha2_password認証方式に対応していることを確認する

参考: MySQL 8.4 What Is New - Native password authentication

5. TLSバージョンのサポート変更

 MySQL 8.4では、TLS 1.2およびTLS 1.3のみがサポートされています。古いTLSバージョン(TLS 1.0、TLS 1.1)を使用しているクライアントは接続できなくなります。アップグレード前に、以下を確認してください:

  • アプリケーションおよびクライアントがTLS 1.2以上に対応しているか
  • SSL/TLS接続設定を使用している場合、接続が正常に行えるかテストする

参考: MySQL 8.4 What Is New - TLS protocol support

6. 廃止された機能とユーティリティ

 MySQL 8.4では、以下の機能とユーティリティが廃止されています。

memcachedインターフェース

 memcachedインターフェースのサポートが廃止されています。この機能を使用している場合は、代替手段への移行が必要です。

削除されたユーティリティ

以下のユーティリティがMySQL 8.4で削除されました:

  • mysql_upgrade: MySQL 8.0.16で非推奨となり、8.4で削除されました。アップグレード処理は自動的に実行されます
  • mysqlpump: MySQL 8.0.34で非推奨となり、8.4で削除されました。代わりにmysqldumpまたはMySQL Shellのダンプユーティリティを使用してください
  • mysql_ssl_rsa_setup: MySQL 8.0.34で非推奨となり、8.4で削除されました。MySQLサーバが起動時に自動的にSSL/RSA証明書を生成します

その他の削除された機能

  • INFORMATION_SCHEMA.TABLESPACESテーブル
  • DROP TABLESPACEALTER TABLESPACEENGINE
  • LOCK TABLES ... WRITELOW_PRIORITY

参考: MySQL 8.4 What Is New - Features Removed

7. アップグレード前の事前チェック

 Amazon RDSは、アップグレード前に自動的に事前チェックを実行し、非互換性を検出します。事前チェックで問題が検出された場合、アップグレードは自動的にキャンセルされ、PrePatchCompatibility.logに詳細が記録されます。このログを確認し、必要な修正を行ってから再度アップグレードを試みることができます。

参考: Amazon RDS for MySQL のメジャーバージョンアップグレードの概要

8. 推奨される対応手順

 安全にアップグレードを実施するため、以下の手順を推奨します:

  1. 破壊的変更の事前確認: FLOAT/DOUBLE列でのAUTO_INCREMENT使用状況、パーティショニングキーでのインデックスプレフィックス使用状況を確認し、該当する場合は事前に修正
  2. テスト環境での検証: 本番環境でのアップグレード前に、テスト環境で同様のアップグレードを実施し、アプリケーションの動作を確認
  3. パラメータグループの作成: MySQL 8.4用の新しいパラメータグループを作成し、必要な設定を反映
  4. スナップショットの取得: アップグレード前に最新のスナップショットを取得
  5. 接続設定の確認: TLS 1.2以上のサポート、認証プラグインの対応を確認
  6. パフォーマンスモニタリング: アップグレード後、CloudWatch メトリクスやスロークエリログを監視し、パフォーマンスの変化を確認(特にinnodb_change_bufferingのデフォルト値変更の影響を確認)

変更点のまとめ

 RDS for MySQL 8.0から8.4へのアップグレードにおいて、デフォルトのDBパラメータ設定のままでも基本的には動作しますが、以下の点に特に注意が必要です:

必須対応事項: - FLOAT/DOUBLE列でのAUTO_INCREMENT使用の確認と修正(アップグレード失敗の原因になる) - パーティショニングキーでのインデックスプレフィックスの確認と修正

接続に影響する変更: - mysql_native_passwordの無効化(既存ユーザーの認証方式確認が必要) - TLS 1.0/1.1のサポート終了(TLS 1.2以上への対応が必須)

パフォーマンスに影響する可能性のある変更: - innodb_change_bufferingのデフォルト値がnoneに変更 - その他複数のInnoDBパラメータのデフォルト値変更

 事前にテスト環境で検証を行い、特に必須対応事項については本番環境のアップグレード前に必ず対応してください。

【実践1】ローカル開発環境でテスト

目的

 8.0から8.4への仕様変更に伴うアプリケーションサーバの既存実装の改修要否を知ること

手順

 目的を達成するためにローカルPCのDocker上にmysqlコンテナを起動させてアプリケーションコンテナからAPIの動作確認をしました。

1. 8.0のDBバックアップと8.4へのリストア

  # on MySQL 8.0
  $ mysqldump --single-transaction --skip-lock-tables -p -h127.0.0.1 -P3306 -uappuser -B app_test > app_test_dump20251201.sql
  
  # on MySQL 8.4
  $ mysql -p -h127.0.0.1 -P3308 -uappuser < app_test_dump20251201.sql

2. ユーザの作成&権限付与

 ローカル環境は、今回8.4用の動作検証を新しく行うために完全新規の接続ユーザを作成したので、CREATE USER文と権限付与を行いました。元々ローンチしたときはMySQL5.7で運用していたので現在のMySQL8.0既存ユーザの認証プラグインも mysql_native_passwordを設定しているので8.4でもその認証プラグインを使うようにしておけばそれでよいです。

mysql> CREATE USER 'appuser'@'%' identified WITH mysql_native_password BY '[パスワード]';
+---------+------+-----------------------+
| user    | host | plugin                |
+---------+------+-----------------------+
| appuser | %    | mysql_native_password |
+---------+------+-----------------------+
1 row in set (0.00 sec)

mysql> FLUSH PRIVILEGES;

# 権限付与が足りない場合は指定データベースの全テーブルに対して全権限を付与
mysql> SHOW GRANTS FOR `appuser`@`%`;
GRANT ALL PRIVILEGES ON `apptest`.* TO `appuser`@`%`

3. API実行

 すべてのAPIをリクエスト送信して正常レスポンスが返ってくることを確認しました。

結論

 動作確認結果から、MySQL8.4に対して既存実装の改修は不要という結論に至りました。

【実践2】AWS上でテスト環境構築&QA

目的

 既存のDB InstanceはTerraform管理下にあるため最終的にはTerraformでBlue/Green Deploymentsしたいのですがそれを実行すると良くも悪くもフルマネージドなためテストする暇もなくapply途中で旧Blue環境が削除されてしまいます。

 よって、目的はterraform applyする前に別途新しいDB Instanceを作成してアプリケーションテスト(QA)を実施して問題なく動作すること

手順

  1. コンソールで既存DB InstanceのSnapshot作成
    手順1:スナップショット作成
    手順1:スナップショット作成
  2. SnapshotをMySQL8.4.7にUpgradeさせる
    手順2:スナップショットのアップグレード
    手順2:スナップショットのアップグレード
  3. QA用のParameter GroupをMySQL8.4ベースのもので作成して、設定変更をさせておく
  4. UpgradeさせたSnapshotを元にRestore
  5. AWS Cloud Mapでリストアした新しいDB InstanceをサービスにRegisterしてCNAMEを紐づけ直す
  6. AWS Cloud Mapでサービス登録した既存DB InstanceをDeregister
  7. アプリケーションのQA実施

結論

 手順4では、userの権限や認証プラグインはそのままリストアされているので問題ありませんでした。AWS上でのQAも正常な結果でしたので問題なく動作することが確認取れました。よって、このままBlue/Green Deploymentsを実施可能という判断になりました。

【実践3】TerraformでBlue/Green Deployments

目的

 terraform applyコマンド実行し全自動でmajor version を8.0から8.4にアップグレードすること

手順1:Backupsを有効にする

 既存DB Instanceの設定は自動バックアップを無効化にしていました。AWS公式のDocumentsによれば、Blue/Green Deploymentsを実行する際には自動バックアップを有効化にしなければならない(must)という文言の記載がありましたのでまず有効化にすることにしました。

[Preparing an RDS for MySQL or RDS for MariaDB DB instance for a blue/green deployment]
Before you create a blue/green deployment for an RDS for MySQL or RDS for MariaDB DB instance, you must enable automated backups. For instructions, see Enabling automated backups.
resource "aws_db_instance" "app_db" {
  engine_version          = "8.0"
  backup_retention_period = 1
  blue_green_update {
    enabled = false
  }
}

問題1

backup_retention_period=1で自動バックアップ保持期間を最短の1日にして一旦有効化しようとしたら、以下のようにapply直後にすぐ差分が出てしまうことが判明しました。

$ terraform apply
...
module.rds.aws_db_instance.app_db: Modifications complete after 1m20s [id=db-XXXXXXXX]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
$ terraform plan
...
 ~ resource "aws_db_instance" "app_db" {
      ~ backup_retention_period               = 0 -> 1
        id                                    = "db-XXXXXXXX"
        tags                                  = {}
        # (55 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

 原因は、apply_immediately argument値をtrueにしないと即時反映されないからのようです。つまり、DB Instance再起動を伴う変更ということがわかりました。AWS公式DOCにも以下のような注意書きがありました。

⚠️Important
An outage occurs if you change the backup retention period of a DB instance from 0 to a nonzero value or from a nonzero value to 0.

解決策1

 DBインスタンス再起動を実施することによってダウンタイムが発生してしまうというのは避けたかったので強引に自動バックアップ有効化の変更をBlue/Green Deploymentsの対象としてSwitchoverさせればこのダウンタイムが最小化するかもと思い試してみました。方法は、以下の変更を terraform apply1回で同時適用させることです。

resource "aws_db_instance" "app_db" {
  engine_version          = "8.0"
  backup_retention_period = 1
  blue_green_update {
    enabled = true
  }
}

 結果は、Blue/Green Deployments自体は発動しましたが、Green環境が作成される前にBlue環境のDB Instanceが結局再起動して自動バックアップを有効化にしていたので無駄に終わってしまいました。。したがって、再起動ダウンタイムはどうしても発生してしまうということになりますのでご注意ください。

自動バックアップ有効化実施時のログ
自動バックアップ有効化実施時のログ

手順2:engine_version の変更適用

 以下の変更を terraform apply実行で適用させました。DBパラメータグループは使用中の8.0用のものを更新してしまうとSnapshot作成やBlue環境で使用するParameter groupsが存在しなくなってエラーを引き起こしそうだったので新規で8.4用のリソースを作成しました。

resource "aws_db_instance" "app_db" {
  engine_version          = "8.4"
  parameter_group_name    = aws_db_parameter_group.mysql_8_4.name
  backup_retention_period = 1
  blue_green_update {
    enabled = true
  }
}

resource "aws_db_parameter_group" "mysql_8_4" {
  name   = "mysql-8-4"
  family = "mysql8.4"
}
$ terraform apply
...
...
module.rds.aws_db_instance.app_db: Modifications complete after 30m57s [id=db-XXXXX]

Apply complete! Resources: 1 added, 1 changed, 0 destroyed.

 このフルマネージドな実行時間31分の間にどのようなことが行われているのかを知るためにコンソール上でUIの変更やLogs&eventsタブのログがどのような出力が出るかなどを監視していました。

  • BlueがModifyingのとき(Backupを作成中)、接続は成功していました
  • Blue,GreenどちらもAvailableになるのは18分30秒くらいでした
  • Switchover開始前にNew Blueインスタンスの方のイベントログにTerminate connectionと表示されて terraform apply実行前から敢えてDBに接続し続けていたセッションが切れていることを確認取れています。レプリケーション整合性の担保のための挙動のようです。その後すぐに新規接続を試みれば成功はしました。おそらくこの瞬間が公式DOCにある The switchover typically takes under a minute with no data loss and no need for application changes.に相当する時間なのかと思われます。
$ aws ssm start-session --target ecs:<cluster_name>_<task_id>_<Container runtime ID> --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["<endpoint_name>"],"portNumber":["3306"], "localPortNumber":["3306"]}'
Connection accepted for session [XXXXX]

Connection to destination port failed, check SSM Agent logs.
$ aws ssm start-session --target ecs:<cluster_name>_<task_id>_<Container runtime ID> --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["<endpoint_name>"],"portNumber":["3306"], "localPortNumber":["3306"]}'
Connection accepted for session [xxxxx]
  • 元々Deletion protectionがEnabledの設定をしていたのですが、旧Blue環境のDB Instance自動削除は無事に成功していました!

Blue/Green Deployments実行ログ(一部抜粋)

リソース名 タイプ 日時 イベント内容
bgd-9h8u8mpxqbfcl8ho Blue/green deployment November 20, 2025, 19:02 (UTC+09:00) Your blue/green deployment bgd-9h8u8mpxqbfcl8ho will create a read replica of app_db with storage type gp3, and allocated storage 20.
app_db (New Blue) Primary November 20, 2025, 19:04 (UTC+09:00) Backing up DB instance
app_db (New Blue) Primary November 20, 2025, 19:06 (UTC+09:00) Finished DB Instance backup
bgd-9h8u8mpxqbfcl8ho Blue/green deployment November 20, 2025, 19:24 (UTC+09:00) Blue/green deployment tasks completed. You can make more modifications to the green environment databases or switch over the deployment.
bgd-9h8u8mpxqbfcl8ho Blue/green deployment November 20, 2025, 19:29 (UTC+09:00) Switchover started on blue/green deployment app_db.
app_db (New Blue) Primary November 20, 2025, 19:29 (UTC+09:00) Switchover from primary app_db to app_db-green-lqjrxz started.
app_db (New Blue) Primary November 20, 2025, 19:29 (UTC+09:00) The primary app_db-green-lqjrxz environment is now accepting read and write operations at the database level. The write downtime during the switchover lasted approximately 2 seconds. DNS propagation might take additional time to complete.

まとめ

 本記事では、Amazon RDS for MySQL 8.4へアップグレードするための方法としてフルマネージドBlue/Green DeploymentsをTerraformから実行したときのベストプラクティスを紹介いたしました。既存運用中のDB Instanceが元から自動バックアップ有効化にしている場合にはダウンタイムは何も気にせずに完全自動化に任せて簡単にアップグレードができることがわかりました。Switchover時に発生した接続断の許容ができるレベルのサービスであればメンテナンス中の作業にするまでもなくオンラインで実施可能という実感でした。

最後に

エブリーでは、ともに働く仲間を募集しています。

テックブログを読んで少しでもエブリーに興味を持っていただけた方は、ぜひ一度カジュアル面談にお越しください!

corp.every.tv