Amazon AuroraからRDS for MySQLに移行した話

この記事は ウィルゲート Advent Calendar 2022 7 日目の記事です。

RDSをRDS for MySQLからAmazon Auroraに移行した結果コストが想定以上に膨れ上がってしまったのでAmazon AuroraからRDS for MySQLに戻すということを行いました。

作業としてはAmazon AuroraからRDS for MySQLへレプリケーションを設定し、メンテナンス時にRDS for MySQLへ切り替えるという作業を行いました。

今回はその作業工程を書いていきます。

手法を決める

Amazon Auroraの仕様の確認したところ

  • Amazon Auroraはバイナリログを使用してレプリカを行っていない(Amazon CloudWatchを使っている)
  • スナップショットからの復元はできない(Amazon AuroraのスナップショットからはAmazon Auroraしか作れない)
  • Amazon Auroraはmysqldumpで--master-dataのオプションは使用できない

と言う制約があったので以下の手法を取ることにしました。

  1. Amazon Auroraのクラスターのスナップショットを取得する
  2. Amazon Auroraのクラスターを復元する
  3. 復元したクラスターのライターインスタンスからmysqldumpを行う
  4. RDS for MySQLを作成し、dumpしたデータのリストアを行う
  5. Amazon AuroraからRDS for MySQLへレプリカをする

この手法を選択した理由として MySQLの場合はクエリコマンドでバイナリログのファイル名とポジションの確認を行うことができますが、Amazon Auroraでは確認することができません。 レプリカ作成でも、スナップショット復元でもRDS for MySQLとして作成することができないので、何か方法はないかとAWSサポートに問い合わせなどを行って確認をとり 「インスタンス単体ではなくクラスターごとスナップショットを取得し、復元することでバイナリログのファイル名とポジションの確認を行える」 と連絡をもらえたのでその手法を用いて確認し、レプリカ設定を行う事にしました。

作業

binlog_formatの確認

まずは、Amazon Auroraクラスターパラメータグループがbinlog_formatがMIXEDになっている事を確認します。

なっていない場合は変更が必要になります。

変更を反映するにはRDSの再起動が必要なので注意しましょう。

バイナリログの保持期間確認

Amazon Aurora に接続(rootアカウント)してバイナリログの保持期間を確認します。

確認コマンド

call mysql.rds_show_configuration;

実行結果は以下のようになります。

MySQL [(none)]> call mysql.rds_show_configuration;
+------------------------+-------+------------------------------------------------------------------------------------------------------+
| name                   | value | description                                                                                          |
+------------------------+-------+------------------------------------------------------------------------------------------------------+
| binlog retention hours | 144   | binlog retention hours specifies the duration in hours before binary logs are automatically deleted. |
+------------------------+-------+------------------------------------------------------------------------------------------------------+

実行結果に表示されているvalueが保持期間(単位は時間)になります。

表示がない場合は設定されてない状態なので以下を行います。

保持期間を設定するコマンド

CALL mysql.rds_set_configuration('binlog retention hours', 144);

数字の部分に時間を入れて設定します。

※コマンドで入力している144は6日間です。

Amazon Auroraクラスターのスナップショットを取得

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

取得したスナップショットからクラスターごと復元します。

復元後にライターインスタンスのイベントを見るとスナップショット取得時のバイナリログ名とポジションが出力されているので控えておきます。(レプリカ設定時に使用します)

データのdump

復元したAmazon Auroraからデータをdumpします。

mysqldump --databases DB1 DB2 --set-gtid-purged=OFF --single-transaction --order-by-primary -r backup.sql -u ユーザー -p -h Amazon Auroraのエンドポイント  > dumpファイル名

※注意する点として、稼働中のAmazon Auroraではなく復元したAmazon Auroraからデータをdumpしないといけないです。

レプリカ用のRDS for MySQL作成

RDSを作成するだけなので詳細は割愛します。

データのリストアする

作成したRDS for MySQLにデータをリストアします。

mysql -u ユーザー -p -h RDS for MySQLのエンドポイント
ログインしてから
mysql > source dumpファイル名;

レプリカ設定

Amazon Aurora側

レプリケーションのユーザーを作成します。

CREATE USER 'repl_user'@'%' IDENTIFIED WITH mysql_native_password BY 'パスワード';
REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'%';
FLUSH PRIVILEGES;

RDS for MySQL側

レプリカ設定をします。

CALL mysql.rds_set_external_master(
'マスターのアドレス',
'ポート', 
'ユーザー名', 
'パスワード',
'バイナリログのファイル名',
'同期開始位置',
'SSL接続の有無'
);

CALL mysql.rds_start_replication;

マスターのアドレスはRDSのエンドポイントだと長すぎて設定できないので適時CNAME等に置き換える必要がありました。

設定ができたらSlaveの確認をします。

show slave status\G;

エラーがなければデータの確認と同期の確認を行います。

最後に

本番稼働しているDBのレプリカを作成すると言う事で、バイナリログの同期開始位置を使用しようとしましたが、 Amazon Auroraの仕様の問題で少しの遠回りをしました。

AWSサポートにも協力して頂き、無事にAmazon Auroraに対しRDS for MySQLのレプリカを作成することができました。

この後、無事にマスターDBをAmazon AuroraからRDS for MySQLに移行し問題なく稼働しています。

ウィルゲート Advent Calendar 2022」、翌日は 清水隆亮さんの「転職3ヶ月経って感じたウィルゲート開発室について」です!