🔋

AWS Database Migration Service(DMS)を使ってデータ移行をしてみた

に公開

こんにちは!
以前あるDBを特定のDBに統合する作業を行った際に、AWS Database Migration Service(DMS)を初めて使ってデータ移行をしてみたので、DMSを使ったデータ移行の流れや、感想をまとめていきたいと思います!

今回統合したDBの環境構成です。

役割 データベースエンジン バージョン
元となるDB MySQL Community Edition 5.7.44
統合先のDB Amazon Aurora MySQL 5.7

なぜDMSを選んだのか

DMSを選んだ主な理由は、レプリケーション機能が使えるからです!
https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/Welcome.html

元となるDBに書き込みが発生しても、レプリケーション機能を使えば差分をリアルタイムで同期できます。
そのため、以下のような手順を踏んだ際に、環境変数を差し替えるときだけメンテナンスモードにすればよく、ダウンタイムを最小限にできると思い選びました。

  1. DMSで移行タスクを作成
  2. レプリケーション機能を利用して、対象テーブルへ移行(移行中、元となるテーブルに書き込まれても、同期してくれる)
  3. メンテナスモード開始
  4. 環境変数の差し替え(元のDBを参照してる箇所を移行先のクラスターに変更)
  5. メンテナンスモードを解除して完了

DMSで選べる移行タイプとテーブル作成オプション

移行タスク

移行タスクを作成する画面を確認すると以下のように、移行タイプを複数選択できました。

移行タイプ 説明
移行(Full load Only) ソースエンドポイントからターゲットエンドポイントへ1回限りの移行を実行します。
移行と複製(Full load Only and CDC) ソースからターゲットへ1回限りの移行を実行し、その後、ソースからターゲットへデータ変更のレプリケーションを継続する。
複製(CDC only) 1回限りの移行は行わず、ソースからターゲットへのデータ変更のレプリケートを継続する。

ターゲットテーブル準備モード

またターゲットテーブル準備モードで、何もしないを選択しておくことで、対象となるDBに移行対象のテーブルがなければ勝手に作ってくれるようです。

ターゲットテーブル準備モード 説明
何もしない ターゲットに既にテーブルが存在する場合、それらは影響を受けません。そうでない場合、AWS DMS は新しいテーブルを作成します。
ターゲット上のテーブルを削除 AWS DMS はテーブルを削除し、代わりに新しいテーブルを作成します。
切り捨て AWS DMS はテーブルとそのメタデータを残しますが、データは削除します。

実際にぶつかった壁

DMSのレプリケーションはbinlog_format=ROWじゃないと動かない

移行タイプを「移行と複製(Full Load and CDC)」に設定してタスクを実行したところ、以下のようなエラーが、、

[SOURCE_CAPTURE ]E: Error Code [10002] : MySQL binary Logging must use ROW format [1020418] (mysql_endpoint_capture.c:433)

ドキュメントを見てみると、以下のように書いてありました。

To use CDC, make sure to enable binary logging. To enable binary logging, the following parameters must be configured in MySQL's my.ini (Windows) or my.cnf (UNIX) file.

パラメータ 説明
binlog_format このパラメータをROWに設定します。
binlog_formatがSTATEMENTに設定されている場合、ターゲットにデータをレプリケートする際に不整合が発生する場合があるため、レプリケーション時にこの設定を推奨します。
また、binlog_formatがMIXEDに設定されている場合、データベース・エンジンは自動的にSTATEMENTベースのロギングに切り替わるため、ターゲット・データベースに矛盾したデータを書き込む可能性があります。

レプリケーションをさせるにはbinlog_format=ROW を設定する必要があるとされています。
確かにパラメータグループを確認すると、バイナリログ形式はMIXEDになっていました。

静的パラメータを変更する際に、クラスターを再起動する必要があり、ダウンタイムが生じてしまうので、レプリケーションは断念しました。

DMSでテーブルを自動生成すると、セカンダリインデックスが引き継がれない

DMSを使ってターゲット側に自動でテーブルを作成すると、テーブル自体は生成されますが、セカンダリインデックスが作成されませんでした。
これも調べてみたところ、以下のように記載されてました。

ソースエンドポイントとターゲットエンドポイント – ソースデータベース内のどの情報とテーブルをターゲットデータベースに移行する必要があるかを確認してください。テーブルとプライマリキーの作成を含む基本的なスキーマ移行 AWS DMS をサポートします。ただし、ターゲットデータベースでは、セカンダリインデックス、外部キー、ユーザーアカウントなどは自動的に作成 AWS DMS されません。

https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/CHAP_BestPractices.html?utm_source=chatgpt.com

今回の対応策

レプリケーションを諦め、一度限りの移行にし、データを移行する前にテーブル定義を対象となるDBに事前にテーブルを作成する対応を行いました。

以下のような手順で対応しました。

  1. 対象となるDBに移行したいテーブルのテーブル定義を事前に用意する
  2. メンテナンスモード開始(元となるDBに新たに書きこみをさせない)
  3. DMSを使って一度限りの移行を行う
  4. 環境変数の差し替え(元のDBを参照してる箇所を移行先のクラスターに変更)
  5. メンテナンスモードの解除

DMSを使ってみた感想

DMSにはテーブル自動作成の機能がありますが、セカンダリインデックスが引き継がれず、結局mysqldumpなどで事前にテーブル定義を用意する必要がありました。
せっかく元となるテーブルを自動作成してくれるなら、完璧にコピーして欲しかったなと思いました。

また、今回レプリケーションが使えず、一度限りの移行にしたため、最初からdumpで良かったのでは?とも思いましたが、データ移行中に、各テーブルへの移行状況をコンソールから確認できたのが良かったなと思っています。

最後に

最後に宣伝です!
スペースマーケットでは、一緒にサービスを成長させていく仲間を探しています。
とりあえずどんなことをしているのか聞いてみたいという方も大歓迎です!
ご興味ありましたら是非ご覧ください!

スペースマーケット Engineer Blog

Discussion