binlogが有効でない非暗号化RDS MySQLから暗号化Auroraに無停止で移行する方法

セクションナイン吉田真吾@yoshidashingo)です。

DB無停止移行は人類の夢

RDS MySQLからAuroraに移行したいけど、デフォルトのセキュリティグループを使用してるのでbinlogが有効にできず、無停止でAurora移行ができない、あるいはAurora Read Replicaをマスターに昇格させた後にアプリケーションからMySQL側に更新トランザクションが入りうるために切替え前にアプリを一時的に閉塞させる必要があって移行に二の足を踏んでいることってないでしょうか。

Aurora ReplicaとDMSを組み合せることで無停止で移行することができます。

いったん組んでしまえば、アプリからの書き込みをいつ移行先に切替えてもOK。一部切替後にちょっと移行元に書き込みが入っても大丈夫(PKの競合を起こすようなデータでなければ)。ついでに非暗号化MySQLからデータベースのストレージおよびその他リソースの暗号化もできます。

f:id:yoshidashingo:20170509204051p:plain

利用する特徴

  • Aurora Read Replicaはbinlogが有効でないRDS MySQLからも継続レプリケーションができる(スナップショット経由のため)
  • DMSは非暗号化<->暗号化データベース間の読み書きをサポートしている
  • DMSのターゲットデータベースのロジカルレプリケーションはターゲットへの書き込みもできる

少しAWSに覚えのある方であればこの特徴だけでどうやればよいかわかると思うので、後は読まなくても大丈夫です、これを組み合せることで「binlogの設定を変更しなくても」「無停止で」「移行中の性能をほぼ無影響に」「暗号化もして」移行します。

手順

説明用の3種類のデータベースインスタンス名は以下のような名前になっています。

  • 移行元データベース(MySQL) mydbinstance
  • 中間データベース(DMSのソースデータベース: Aurora) mydbinstance2
  • 移行先データベース(DMSのターゲットデータベース: Aurora) mydbinstance3

移行元データベース(MySQL)

移行元のRDS MySQLではデフォルトのパラメータグループを作成している想定です。

f:id:yoshidashingo:20170509210044p:plain

また、バックアップは1日以上(今回の場合は2日)設定されているものとします。ストレージ暗号化はされていないので、この状態からでは暗号化済みのAuroraに一発で移行することはできません。

f:id:yoshidashingo:20170509210535j:plain

中間データベース(Aurora Read Replica)

CDCを利用した継続レプリケーションを行うために、移行元のRDS MySQLのAurora Read Replicaを作成します。

Auroraのbinlogを有効にするためにはDBクラスターパラメータグループの設定変更が必要です。デフォルトのものは設定変更ができないので、まずは新規にDBクラスターパラメーターグループを作成して以下の値を変更しておき、Aurora Read Replicaの作成時にこれを適用してインスタンスを作成します。

  • binlog_checksum NONE
  • binlog_format ROW

f:id:yoshidashingo:20170509211020p:plain

また、mysqlクライアントで接続し、binlogの保持期間の変更を行っておきます。エラーでレプリケーションが止まっても十分に対応できる程度の時間にしておきましょう。今回は12時間に設定しておきました。

移行先データベース(暗号化済みAurora)

移行先は(せっかくの機会なので)暗号化しときましょう。デフォルトのDBクラスターパラメータグループだと後で設定を返るときに不便ですが今回は無視します。こちらのbinlogは今回不要です。

f:id:yoshidashingo:20170509212314j:plain

DMS

適当なサイズでDMSインスタンスを作っておきます。

ちなみにこの状態だとMySQLとAurora Read Replicaのテーブルにはデータが入ってますが、ターゲットにはデータが入っていない状態になります(上から1号機/2号機/3号機)

f:id:yoshidashingo:20170509213904p:plain

ソース/ターゲットデータベースに接続する

f:id:yoshidashingo:20170509212944p:plain

タスクを作成して実行する

対象のスキーマを指定してマイグレーションタスクを投入します。マイグレーションタイプには初期データのフルロードと継続レプリケーションを選択しましょう。

f:id:yoshidashingo:20170509213302p:plain

このタスクを実行すると、フルデータロードされてターゲットにもデータが同期されます。

f:id:yoshidashingo:20170509214019p:plain

このタイミング、あるいはフルデータロード後に一時停止しておいて一度「Analyze Table」しておきましょう。

継続レプリされているか確認する

もう一行挿入して継続レプリされているか確認しましょう。

f:id:yoshidashingo:20170509214311p:plain

アプリ切替

移行元ではなくターゲットに直接データを書き込んでみましょう。

f:id:yoshidashingo:20170509214636p:plain

ターゲットにのみデータが書き込まれました。

移行元にデータを書き込む

この状態で一部のトランザクションが移行元側に入ってしまっても、ターゲットにまで伝搬するので問題ありません。

f:id:yoshidashingo:20170509215125p:plain

まとめ

手順を見れば分かるとおり、同一レコードへのトランザクションが移行元/移行先に別々に入ってしまう場合や、Auto Increment属性が付与されているテーブルに移行元/移行先に別々に入ってしまう場合などについての考慮は必要になりますが、そういう条件が発生しえない場面においては、レプリケーションを切り離すタイミングとアプリの切替を同期する必要がなくなるのは嬉しい方法ではないかと思います。

また、統計情報の再作成のためのAnalyze Tableのタイミングについては今回適当に継続レプリ中に行いましたが、実際はターゲットデータベースにかかるワークロードを考慮したタイミングを精査しておく必要があると思います。

また、データベースの移行・切替は非常にセンシティブな作業ですので、実際に作業する時は事前に十分な検証したうえで実行しましょう。

投稿日:May 9th 2017

元記事:http://yoshidashingo.hatenablog.com/entry/2017/05/09/220622

– PR –
– PR –