見出し画像

MySQL5.7→8.0へ向けて Amazon Aurora のブルー/グリーンデプロイの素振りをしたので備忘録を残す

どうも、背番号8です。

現在、Funds のデータベースは Amazon Aurora 上で稼働しておりますが エンジンが MySQL5.7 となっておりまして、いい加減 MySQL8.0 へ上げましょうよ、というので着々と準備を進めております。

バージョン移行に際しては Amazon Aurora のブルー/グリーンデプロイを利用する方向で動いており、検証のために素振りを行ったので備忘録を残そうと思います。

MySQL5.7を利用していることのリスク

改めてお話することでもないですが MySQL5.7 はすでに公式サポートが終了(EOL)しており、控えめに言っても見逃せる状況ではありません。

MySQL5.7を利用していることのリスク

影響調査と対応

もたもたせずにササッと上げてしまいたいところですがメジャーバージョンのアップグレードには破壊的変更を含むのが世の常です。

これに対しては、公式のマイグレーションガイドと先人達の知恵を借りつつ影響調査を行っています。

上記は、主に参考にさせていただいている記事ですが、各項目をスプレッドシートにまとめて、対応の要否/具体的な対応内容、等を取りまとめています。

影響調査表一部抜粋

幸いにもアプリケーションの改修を強いられるような影響はなさそうではありましたが、照合順序のデフォルトの設定が utf8mb4_0900_ai_ci に変更になった点などについては引き続き utf8mb4_general_ci を利用していきたい当社にとっては考慮が必要でした。

対応必須の課題/対応の内容

Amazon Aurora の ブルー/グリーンデプロイについて

本番と同様のステージング環境を作成し、同期した状態を保ったままテストを実施でき、短時間のダウンタイムで切り替えを行うことができるという便利な仕組みです。

MySQLのアップグレード作業にはこちらを利用していきたいと考えており絶賛素振りを繰り返している最中です。

影響調査も作成したグリーン環境で行いました。

事前準備

ブルー/グリーン環境を作成する前の事前準備として以下を行いました

スナップショットから復元

素振りのデータとしてはスナップショットから復元したデータを利用しました。

なお、ブルー/グリーンデプロイの作成にはインスタンスのDBパラメータにて binlog_format が有効である必要があります。

# binlog_format を有効に
$ aws rds modify-db-cluster-parameter-group \
    --db-cluster-parameter-group-name <クラスターのパラメータグループの名前> \
    --parameters "ParameterName=binlog_format,ParameterValue=ROW,ApplyMethod=pending-reboot"

# 再起動しないと反映されない
$ aws rds reboot-db-instance --db-instance-identifier <インスタンスの名前>

MySQL8.0向けのDBパラメータグループ用意

MySQL5.7 と MySQL8.0 とではパラメータグループファミリーが異なり、再利用できないため MySQL8.0 用にクラスターとインスタンスとそれぞれDBパラメータグループを別途用意しました。

この時、文字セットや照合順序のデフォルトが変更になる点を考慮して、あらかじめ、文字セット → utf8mb4照合順序 → utf8mb4_general_ci となるような設定を追加しておきました。

$ aws rds describe-db-cluster-parameters \
   --db-cluster-parameter-group-name <クラスターのパラメータグループの名前> \
   --query 'Parameters[?contains(ParameterName, `collation`) || contains(ParameterName, `character_set`)].{ParameterName:ParameterName,ParameterValue:ParameterValue}'
[
    {
        "ParameterName": "character_set_client",
        "ParameterValue": "utf8mb4"
    },
    {
        "ParameterName": "character_set_connection",
        "ParameterValue": "utf8mb4"
    },
    {
        "ParameterName": "character_set_database",
        "ParameterValue": "utf8mb4"
    },
    {
        "ParameterName": "character_set_filesystem",
        "ParameterValue": "utf8mb4"
    },
    {
        "ParameterName": "character_set_results",
        "ParameterValue": "utf8mb4"
    },
    {
        "ParameterName": "character_set_server",
        "ParameterValue": "utf8mb4"
    },
    {
        "ParameterName": "collation_connection",
        "ParameterValue": "utf8mb4_general_ci"
    },
    {
        "ParameterName": "collation_server",
        "ParameterValue": "utf8mb4_general_ci"
    }
]

ブルー/グリーンデプロイの作成

グリーン環境が MySQL8.0 になるよう指定して作成します。

aws rds create-blue-green-deployment \
    --blue-green-deployment-name <ブルー/グリーンデプロイの名前> \
    --source <元ソースとなるクラスターのARN> \
    --target-engine-version 8.0 \
    --target-db-cluster-parameter-group <MySQL8.0用のクラスターDBパラメータグループ> \
    --target-db-parameter-group-name <MySQL8.0用のDBパラメータグループ>

コンソールにてグリーン環境のステータスが以下の状態となっていることが確認できたら作成完了です。

ブルー/グリーンデプロイ作成完了

グリーン環境の作成について少しお話すると初め、元ソースと同じ MySQL5.7 で一度クラスターを作成した後に MySQL8.0 へエンジンが切り替わるような挙動をしていて、以下の記事でも言及がある通り、たしかに完了までに体感40分程度はかかるなあという所感でした。

検証

接続してみる

Amazon Aurora 3 のデフォルトである MySQL8.0.28 にて稼働していることが確認できました。

$ mysql <データベース> -P 3306 -u <接続ユーザー> -p -h <グリーン環境のクラスターのエンドポイント> 
Enter password:
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 14140
Server version: 8.0.28 Source distribution

Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

テーブルを作成してみる

文字セット、照合順序がDBパラメータグループ指定の値を引き継いでいることが確認できます。

CREATE TABLE t1 (
  name varchar(20)
) ENGINE = InnoDB;

SHOW TABLE STATUS FROM <データベース> WHERE NAME = 't1'\G
*************************** 1. row ***************************
           Name: t1
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2024-03-08 01:48:53
    Update_time: NULL
     Check_time: NULL
      Collation: utf8mb4_general_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.01 sec)

尚、中途半端に文字セットだけDDL実行時に指定すると MySQL8.0 のデフォルトの utf8mb4_0900_ai_ci が参照されてしまうので注意が必要です(CHARSET, COLLATE 両方指定するのはOK)。

CREATE TABLE t2 (
  name varchar(20)
) ENGINE = InnoDB
CHARSET = utf8mb4;

SHOW TABLE STATUS FROM <データベース> WHERE NAME = 't2'\G
*************************** 1. row ***************************
           Name: t2
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 0
 Avg_row_length: 0
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2024-03-08 01:50:53
    Update_time: NULL
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci
       Checksum: NULL
 Create_options:
        Comment:
1 row in set (0.01 sec)

認証プラグインのデフォルト値

MySQL8.0から認証プラグインのデフォルトが caching_sha2_password になるのですが、default_authentication_plugin の値を確認してみたところ mysql_native_password が適応されているみたいでした。

SHOW GLOBAL VARIABLES LIKE '%default_authentication_plugin%'\G
*************************** 1. row ***************************
Variable_name: default_authentication_plugin
Value: mysql_native_password
1 row in set (0.00 sec)

再起動して設定値が切り替わる懸念があったので念の為、試してみたところそのような挙動はみられませんでした。

再起動したら書き込みできなくなった

前段の認証プラグインの設定値の確認の際、インスタンスを再起動したところ書き込みができなくなってしまいました。

原因が良くわからなかったのでAWSのサポートに問い合わせてみたところ以下の回答がありました。

Aurora MySQL のグリーン環境は、DB クラスターの作成後にデフォルトで書き込み操作が許可されますが、再起動を行うと read_only パラメータの設定にしたがって、書き込み操作の可否が変化します[1]。デフォルトのパラメータグループでは read_only パラメータが 1 に設定されますので、再起動後は DB クラスターへの書き込み操作が拒否されます[2]。 書き込み操作を許可する場合は、パラメータグループから read_only パラメータを 0 に設定した後に、DB インスタンスの再起動を実施いただければと存じます。

パラメータグループの設定を変更すれば解決するということでしたが、用意したパラメータグループはすでに read_only = 0 になっていました。

aws rds describe-db-cluster-parameters --db-cluster-parameter-group-name qa-funds-db-mysql8 --query 'Parameters[?contains(ParameterName, `read_only`)].{ParameterName:ParameterName,ParameterValue:ParameterValue}'
[
    ... ,
    {
        "ParameterName": "read_only",
        "ParameterValue": "0"
    }
]

となるとどのパラメータグループを変更すれば?、というところで進捗が止まっており再度サポートに確認中です。

恐らく、以下の変数を直接変えないといけないんじゃないかなー、と予想していますが検証作業時に権限がなかったので試せませんでした。

show variables like 'read_only'\G
*************************** 1. row ***************************
Variable_name: read_only
        Value: ON
1 row in set (0.00 sec)

ここは進展があり次第更新したいと思います。

グリーン環境の昇格

ブルー/グリーンデプロイのリソースIDとタイムアウトの値(sec)を指定して実行します。

aws rds switchover-blue-green-deployment \
    --blue-green-deployment-identifier <ブルー/グリーンデプロイのリソースID> \
    --switchover-timeout 600

実行が完了すると以下のように、ブルー環境 → 古いブルー環境、グリーン環境 → 新しいブルー環境、という状態に切り替わっていることが確認できます。

ここのは本当に早いです。米研いでたら完了してました。

グリーン環境の昇格完了

これにより、エンドポイント等、接続先の情報はそのままにアップグレードした Amazon Aurora のクラスターに接続することができます。

尚、昇格した環境に接続してみたところ書き込みの設定は有効に戻ってました(そうであって欲しかった)。

mysql> show variables like 'read_only'\G
*************************** 1. row ***************************
Variable_name: read_only
        Value: OFF
1 row in set (0.00 sec)

ブルー/グリーンデプロイの削除

切り替えが完了したらデプロイの設定は不要なので消してしまします。

aws rds delete-blue-green-deployment \
    --blue-green-deployment-identifier <ブルー/グリーンデプロイのリソースID>

削除が完了すると、昇格したクラスターと元ソースのクラスターの識別子に -old がついた形でそれぞれ残る形となります。

今後

見える範囲での影響は特定できましたが、まだパフォーマンス面での検証が済んでおらず性能試験を実施予定です。

その後、段取りを整備して切り替えを実施していく形となりますが何事もなく無事に済めば良いなと思ってます🙏

では、また。


この記事が気に入ったらサポートをしてみませんか?