Aurora MySQLの文字コードをutf8からutf8mb4に変更するための備忘録

メディア統括本部 サービスリライアビリティグループ(SRG)の鬼海 雄太(@fat47)です。
#SRG(Service Reliability Group)は、主に弊社メディアサービスのインフラ周りを横断的にサポートしており、既存サービスの改善や新規立ち上げ、OSS貢献などを行っているグループです。
本記事は、RDSのBlueGreen Deployments機能をつかって文字コードはutf8からutf8mb4に変換する方法を書いています。
なにかの役に立てば幸いです。
 

utf8 ( utf8mb3 )


Aurora MySQL Version3(MySQL8.0互換)ではdefaultの文字コードutf8mb4となっていますが、Version2(MySQL5.7互換)ではlatin1となっています。
latin1を使っているところは多くないとは思いますが、utf8(utf8mb3のエイリアス)を指定しているところは案外多いのではないでしょうか。
 
MySQL8.0ではutf8のエイリアスの利用は非推奨となっています。
将来的にutf8のエイリアスはutf8mb4へ変更される可能性があります。
 

utf8が設定されているテーブルとカラムを洗い出す


上記のクエリでutf8_**で設定されているものがあればそれが対象です。

普通にALTER TABLEで対応するとテーブルブロックかかる


ALTER TABLEで文字コードを変換する場合は下記のようなクエリで対応することになります。
しかし、このクエリはテーブルロックがかかるため注意が必要です。
レコード件数が膨大なテーブルでは丸一日以上実行にかかるということもあります。
その間テーブルへの更新はロックされてしまうので、サービスをメンテナンスモードなどにいれて書き込みを停止させる必要がでてきます。

RDS Blue/Green Deployment機能を使いましょう


Blue/Green Deployment機能については何度かこのブログでもとりあげていますので、詳しくはそちらをご参照ください。
 
簡単に説明しますと、下記の図のように現在稼働中のクラスタ(Blue)をもとにGreenクラスタを作成して、 Blue/Green間でレプリケーションの構築、切替操作によるエンドポイントの書き換えをマネージドでおこなってくれる機能です。
AWS公式ドキュメントより引用
AWS公式ドキュメントより引用
 
この機能で生成されたGreenクラスタに対して文字コードの変更を実行することで、元のBlue環境には影響なく変更をすることが可能です。
しかし、ここで注意しないといけない設定があります。
 
このままGreenに対して文字コード変更の実行をしてしまうと、BlueとGreenでテーブルの文字コードが異なる状態になってしまいます。
Blue/Green Deploymentのレプリケーションはbinlog_formatがを選択することがほとんどかと思いますが、これらの設定値の場合、
Blue側とGreen側のカラムのデータ型が完全一致している必要があります。
※AWS公式ドキュメントの推奨はROW
 
初期設定のままカラムのデータ型が異なる状態のレプリケーションが行われると、下記のようなレプリケーションエラーが発生し、レプリケーションが停止されます。
※Auroraの場合はこのエラーが出ましたが、普通のMySQLのレプリケーションの場合は型変換のエラーで停止するはずです。
 

型変換を許容するslave_type_conversions


Aurora MySQL version2系ではslave_type_conversions、
version3系ではreplica_type_conversions
の値をクラスターパラメータグループで指定し、型変換を許容の制御を行います。
 
型変換のモードには下記のものがあります。
モード許容する内容
ALL_LOSSY不可逆変換を許可(型が小さくなる変換)INT → TINYINT
ALL_NON_LOSSY非不可逆変換を許可(型が大きくなる変換)TINYINT → INT
ALL_LOSSY、ALL_NON_LOSSY全ての型変換が許可-
ALL_SIGNED昇格した整数型を符号付き値として扱う(デフォルト)-
ALL_UNSIGNED昇格した整数型を符号なし値として扱う-
ALL_SIGNED、ALL_UNSIGNED昇格した整数型を、可能であれば符号あり、そうでなければ符号なしとして扱う-
 

公式ドキュメントには不穏な記述があるが…


先程の公式ドキュメントのなかで下記のような記載があります。
Supported conversions.  Supported conversions between different but similar data types are shown in the following list:
  • Between any of the string types , and , including conversions between different widths.
    • Conversion of a , or  to a , or  column the same size or larger is never lossy. Lossy conversion is handled by inserting only the first  characters of the string on the replica, where  is the width of the target column.

      Important
      Replication between columns using different character sets is not supported.
サポートされている変換。 異なるが類似のデータ型間でサポートされている変換を以下のリストに示す:
異なる幅間の変換を含む、CHAR、VARCHAR、TEXTのいずれかの文字列型間。
CHAR、VARCHAR、TEXTから、同じサイズ以上のCHAR、VARCHAR、TEXT列への変換は、決して非可逆ではありません。非可逆変換は、レプリカ上の文字列の最初のN文字のみを挿入することで処理されます。

重要 異なる文字セットを使用するカラム間のレプリケーションはサポートされていません。
異なる文字セットを使用するカラム間のレプリケーションはサポートされない…?だめなんですか…?

とにかくこの設定で有効にするとレプリが停止しないか検証


  1. Greenで指定しているクラスタパラメータグループで設定をに変更します。
  1. テスト用のテーブルを文字コードutf8で作成します
    1. 適当にINSERTしてみます
      1. B/G Deployment機能でGreenクラスタを作成します
      1. 生成されたGreenエンドポイントに対してALTER TABLE実行します
        1. BlueとGreenそれぞれのテーブルを確認してみます
          1. Blue
            1. Green(ちゃんとutf8mb4に変更されている)
            1. Blue環境でINSERTを流してみます
              1. Green環境のレプリケーションのステータスが両方Yesなのを確認してみます
                1. Green環境にデータが反映されているか確認します
                  これでレプリケーションが停止していないことが確認できました。
                  あとはこのBlue/Greenを切り替えてあげれば対応完了となります。
                   
                  MySQL公式ドキュメントでの一文は具体的にどういうパターンが許容されないんでしょうか。
                  ついでの試しにBlue側のテーブル文字コードをlatin1にして、Green側とutf8mb4にしてみるテストを同様にしてみましたが、こちらも問題なくレプリケーションされていました。
                   

                  設定をいれないでGreenの文字コードを変更するとどうなる?


                  1. Greenにしているクラスタパラメータグループのをデフォルト値に戻します
                  1. BlueにINSERTを流します
                    1. Greenのレプリケーションの状態を確認するとエラーで停止しています

                      参考URL


                      終わりに


                      MySQLの公式ドキュメントには不穏な一文がありましたが、無事文字コードの変換ができました。
                      カラム指定で文字コードを変更してみたり、文字コードの変更と同時に型サイズの変更を行ってからレプリケーションのテストなどをしてみましたが、
                      どのパターンもレプリケーションのエラーもなく成功することができました。
                      Aurora MySQL Version3へのアップグレードが落ち着いたらこの文字コード対応もおこなっていきたいです。
                       
                      SRG では一緒に働く仲間を募集しています。 ご興味ありましたらぜひこちらからご連絡ください。
                       
                      このエントリーをはてなブックマークに追加