PLAY DEVELOPERS BLOG

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

HuluやTVerなどの日本最大級の動画配信を支える株式会社PLAYが運営するテックブログです。

AWS DMS を使って Aurora MySQL の無停止エンジン更新を試してみた

こんにちは、SaaSプロダクト開発部の滝波です。弊社プロダクト「PLAY VIDEO STORES」のエンジニアを担当しています。

昨年末、AWSから重要な通知が届きました。

Amazon Aurora MySQL は、2024 年 1 月 15 日にバージョン 3.01 と 3.02 (MySQL 8.0.23 互換) を廃止する予定です。
お客様の AP-NORTHEAST-1 リージョンでは前述した Aurora MySQL マイナーバージョンで実行されている Aurora MySQL クラスターが 1 つ以上あるため、3 か月前にお知らせします。

多くの場合、DBエンジンの更新にはインスタンスの再起動が不可欠であり、その間にサービスを停止させる必要があります。
Amazon RDS を利用したアプリケーション開発を行う上で、インスタンスの再起動は避けられない物であり、誰もがサービス無停止で実施する方法を考えると思います。
今回は AWS DMSを活用したサービス無停止でのDB移行によるDBエンジンの更新手順を紹介します。

前提と手順

さっそく、本題に移りましょう。

サービスの中断を最小限に抑えつつ、最新のエンジンで構築した新しいDBに移行することで、DBエンジンの更新を行います。
今回は AWS DMS を使用して、Amazon Aurora MySQLからAmazon Aurora MySQLへの移行となります。

移行元DB:Amazon Aurora MySQL 3.02.1
移行先DB:Amazon Aurora MySQL 3.05.1
移行ツール:AWS Database Migration Service(DMS)

移行の手順とDMSの全体図は以下の通りです。

  1. 移行元Aurora MySQLクラスター( ソース )のbinlogを有効にする
  2. 移行先Aurora MySQLクラスター( ターゲット )を構築しておく
  3. DMSで移行元と移行先クラスターをレプリケーションさせる
  4. レプリケーション状態と遅延を確認する
  5. アプリケーションからの接続先を移行先クラスターのエンドポイントに向ける
  6. 移行元Aurora MySQLクラスターを縮退する

事前準備

移行元のDBの設定

まずは移行元DBの設定です。
DMSの移行元(ソース)にAurora MySQLを利用する場合は、binlog_formatがROWで設定されている必要があります。
RDSのパラメータグループから、binlog_formatの設定を確認しましょう。
※ binlog_formatがROWになっていない場合は、設定の変更とインスタンスの再起動が必要になります。

docs.aws.amazon.com

移行先のDBの設定

次に移行先(ターゲット)となるDBを準備します。
DBのエンジンバージョンを3.05.1に設定し、初期構築を行います。

インデックス・制約の移行

※ DMSでは外部キー等の制約を自動移行できないので、別途手動での移行が必要になります。

docs.aws.amazon.com

移行元のDBのSchema情報をあらかじめ取得しておき、移行先のDBに移しましょう。

mysqldump --no-data sourceDB > schema.sql
mysql targetDB < schema.sql

移行元DBと移行先DBのインデックス・制約が一致するかを確認します。

-- インデックスの確認
SELECT 
    TABLE_SCHEMA, 
    TABLE_NAME, 
    COLUMN_NAME, 
    INDEX_NAME 
FROM INFORMATION_SCHEMA.STATISTICS 
ORDER BY TABLE_NAME;

-- 制約の確認
SELECT 
    TABLE_NAME,
    COLUMN_NAME,
    CONSTRAINT_NAME,
    REFERENCED_TABLE_NAME,
    REFERENCED_COLUMN_NAME 
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE REFERENCED_TABLE_NAME IS NOT NULL 
ORDER BY TABLE_NAME;

これで事前準備完了です。

DMSの設定

ここからはDMSの設定です。
AWS 上で移行に必要な各種設定を行なっていきます。

サブネットグループの作成

レプリケーションインスタンスで使用するサブネットグループを作成します。
データベースの移行に使用するネットワークの一部として、使用する予定の VPC のサブネットを指定する必要があります。

レプリケーションインスタンスの作成

レプリケーションインスタンスを作成します。
インスタンスクラスやエンジンバージョンは移行するデータの量、および、インスタンスが実行するタスクによって変更します。

レプリケーションサブネットグループには今回作成したものを設定します。

エンドポイントの作成

エンドポイントを作成します。
エンドポイントにはDBの接続情報、タイプ、場所等を設定します。
DMSはソースエンドポイントからターゲットエンドポイントへデータを移行します。

ソースエンドポイント

移行元のDB接続情報を入力します。

ターゲットエンドポイント

ソースエンドポイントと同じく、移行先のDB接続情報を入力します。
事前準備で構築した移行先のDBには、外部キー等の設定が入っており、そのままだとDMSのデータ挿入時にエラーになってしまいます。

repost.aws

エラーを回避するために、エンドポイント設定に外部制約チェックを無視する設定を追加しましょう。

initstmt=SET FOREIGN_KEY_CHECKS=0

エンドポイントの設定完了後、接続テストを行い「successful」になることを確認します。
※ このテストが成功していないと移行タスクが実行されません。

データベース移行タスクの作成

最後にデータベースの移行タスクを作成します。
移行タスクは、移行に関するすべての処理が行われる場所です。
ログ記録要件、制御テーブルデータ、エラー処理、移行に使用するテーブルとスキーマを指定します。

移行先のDBは空の状態なので、ターゲットテーブル準備モードは「何もしない」を設定します。
CloudWatchのログを有効化しておくと、移行タスクでエラーになった際に調査がしやすいので有効化しておきます。

テーブルマッピングでは、今回移行させるDBスキーマ・テーブルを選択しておきます。
移行前評価は、移行タスク開始前にエラーチェックを行い結果をs3に出力してくれる機能になります。今回は設定無しで実行します。
移行タスクのスタートアップ設定で「作成時に自動で行う」を選択し、タスクを作成します。

しばらく待つと、ステータスが「ロード完了、レプリケーション進行中」になりました。
これで移行元DBと移行先DBがレプリケーションされている状態になりました。
ステータスで「エラー」や「エラーを伴って実行中」が出ている場合はCloudWatchのログを確認しましょう。

レプリケーション状態と遅延を確認する

アプリケーションからの接続先の切り替えの前にレプリケーション状態と遅延を確認しましょう。

レプリケーションの状態は移行タスクのテーブル統計で確認できます。
移行元のデータからロードされたデータ、レプリケーションされたデータ、ターゲットのレコード数等が確認できるので、データの欠損がないか確認しましょう。

次にCloudWatch メトリクスでレイテンシーを確認します。
ターゲットのレイテンシーで移行元に挿入されたデータがどのくらいの遅延で移行後のDBに反映されるかが確認できます。
今回の対象DBのレイテンシーは最大で5秒でした。

docs.aws.amazon.com

接続先切り替え

最後にアプリケーションからの接続先を移行先DBクラスターに向けて移行完了です。
移行完了後もしばらくは移行元DBからレプリケーションでデータが入ってくる可能性があるので、すぐに移行タスクは停止せず動かしておきましょう。移行元のデータが全て入ったことを確認後、移行タスクを停止します。

まとめ

本記事では、Amazon Aurora MySQLの無停止移行を実現するための手順として、DMS(データベース移行サービス)の活用方法を紹介しました。初めてDMSを使用しましたが、効率よく移行準備から完了までを実施することができました。

実際に稼働しているシステムのDBをこの手順で移行しましたが、サービス無停止かつ問題も発生することなく移行を完了することができました。

DBインスタンスの再起動やメンテナンス時におけるサービス中断の最小化は、システム開発において重要な課題です。
サービスの規模やデータ量に応じて変わりますが、本記事がサービス無停止で作業を行いたいと考えている皆様のご参考になれば幸いです。
ぜひ、ご自身の環境で実践してみてください!