SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

Azure Database Migration Service で SQL Server のオンラインマイグレーションがプレビューで利用可能になりました

leave a comment

プレビューではありますが、Azure Database Migration Service (DMS) で、SQL Server のオンラインマイグレーションが利用できるようになりました。

アナウンスはこちら。

ドキュメントはこちら。

本投稿は、SQL Server → SQL Database へのオンラインマイグレーションですが、この機能のアナウンスがあったタイミングで MySQL についてもオンラインマイグレーションがプレビューで公開されています。
MySQL はこちら。


本投稿を書いている時点では、英語版のドキュメントのみがオンラインマイグレーションについて触れられていましたので、情報は英語を追うとよいかと。
What is the Azure Database Migration Service? で触れられていますが、現状は、利用できるリージョンには、制限があり、次の 3 リージョンに配置された DMS のみが、オンラインマイグレーションを使用することができます。

  • Cental US
  • East US2
  • West Europe

DMS は、Azure の VNET 内のリソースとして作成する必要があり、配置した VNET からアクセス可能な範囲で利用することが可能なサービスとなっています。
しかし、VNET ピアリング 併用することで、上記のリージョン以外に配置されている SQL Server をマイグレーションすることもできますので、現状は上記のリージョンにしか配置できないからと言って、西日本 / 東日本の SQL Server のマイグレーションができないということはありません。
(社内の SQL Server からマイグレーションする場合は、VNET と VPN を貼ることになります)
SKU については、Business Critical でのみオンラインマイグレーションを実行できるようになっており、General Purpose についてはオフライン移行のみとなるようですので、SKU によって利用可能な機能の差も出てくるようですね。
2018/10/31 までは、DMS は無償で利用できるようになっていますので、検証はお早めに。
Migrate SQL Server to Azure SQL Database online using DMS でチュートリアルが公開されていますので、基本的な操作についてはそちらを確認していただき、本投稿ではポイントをまとめておこうかと。
 

DMS の特徴

今後は変わっていくかもしれませんが、現時点で SQL Server で対応しているのは、

  • SQL Server 2005 以降のデータベースから SQL Database への移行

となっています。
異なる RDBMS のオンラインマイグレーションには、現状対応していませんので、移行元 / 移行先にの RDBMS の種類については現時点では固定となっています。
(この辺は、日々進化していくサービスだと思いますので、あくまでも現時点の対応状況です)
今まで、SQL Server と SQL Database 間でオンラインでデータの移行を行おうとした場合、機能でカバーしようとすると、

というような機能を使う必要がありましたが、今後はこれに、DMS のオンラインマイグレーション機能が選択肢として追加されることになります。
DMS のオンラインマイグレーションの最大の特徴は、

  • プライマリーキーが設定されていないテーブルに対してのオンライン移行がサポートされる

点ではないでしょうか。
トランザクションレプリケーション / Data Sync 2.0 で移行対象とすることができたテーブルは、主キーが設定されているテーブルのみとなっており、主キー無しのテーブルには設定できませんでした。
DMS ではこの制約が多少緩和されます。
以降に使用する機能としては 、次の 2 パターンが提供されています。

  • 主キーありのテーブルについては、レプリケーションの機能により変更をトラッキング
  • 主キー無しのテーブルについては、CDC (変更データキャプチャ) により変更をトラッキング

移行元 (ソース) の SQL Server で CDC を利用することができる場合は、主キーが設定されていないテーブルについても移行対象とすることができるようになりました。
CDC は SQL Server 2008 の Enterprise Edition から実装された機能であり、SQL Server 2016 SP1 以降は、Standard Edition でも利用可能となった機能です。
CDC を利用した移行については、バージョン / エディションの制約があるということを覚えておくとよいかと。
レプリケーションしか使用することができない移行元では、主キーが設定されているテーブルのみ、オンラインマイグレーションで移行可能です。
 

移行元の環境

DMS のオンラインマイグレーションを行うためには、移行元の SQL Server では、次のような環境を満たしている必要があります。

  • 移行元の SQL Server のバージョンは SQL Server 2005 以降
  • 移行元の SQL Server で、レプリケーションのディストリビューターを有効にしておく
    • 移行元の SQL Server では、レプリケーションの機能のインストールが必須となる
  • 移行対象のデータベースは「一括ログ復旧」「完全復旧」のいずれかの復旧モデルを使用
    • 初回のデータベースの完全バックアップを取得しておく必要がある
  • 主キーがないテーブルについては、事前に CDC を有効にしておく必要がある
  • 移行可能なテーブルには次のような制限がある (2018/9 のプレビュー時点の制限)
    • テンポラルテーブルは移行することができない
    • hierarchyid を含むテーブルは移行することができない
    • LOB データ型に 32 KB を含むデータが含まれている場合、ターゲットで切り捨てられる
    • timestamp データ型をターゲットで同一値で移行することができない
  • 移行先の SQL Database では、データベーストリガーを無効にする

主キーが設定されていないテーブルについては、このクエリで確認できます。

SELECT is_tracked_by_cdc, name AS TableName
FROM sys.tables WHERE type = 'U' and is_ms_shipped = 0 AND
OBJECTPROPERTY(OBJECT_ID, 'TableHasPrimaryKey') = 0;

 
これでヒットしたテーブルを移行したい場合には CDC を有効にする必要がありますので、次のようなクエリを使うことになります。

-- 最初に、DB 単位で CDC を有効化する必要がある
EXEC sys.sp_cdc_enable_db
GO
-- DB で機能を有効化した後は、テーブル単位で有効化する
EXEC sys.sp_cdc_enable_table
@source_schema = N'dbo',
@source_name   = N'CDCTable',
@role_name     =  NULL,
@supports_net_changes = 0
GO
-- 無効化
EXEC sys.sp_cdc_disable_table
@source_schema = N'dbo',
@source_name   = N'CDCTable',
@capture_instance = N'dbo_CDCTable'
GO
-- CDC が設定されているテーブルの確認
SELECT is_tracked_by_cdc , T.name AS TableName, S.name AS SchemaName
FROM sys.tables T JOIN sys.schemas S ON T.schema_id = S.schema_id
where type = 'U' and is_ms_shipped = 0 and OBJECTPROPERTY(OBJECT_ID,'TableHasPrimaryKey') = 0

 
主キーが設定されているテーブルについては、レプリケーションにより、変更のトラッキングが行われますので、レプリケーションが機能として有効化されており、ディストリビューターの設定が完了している必要があります。

-- レプリケーションが有効になっているか
USE master;
DECLARE @installed int;
EXEC @installed = sys.sp_MS_replication_installed;
SELECT @installed as installed;
--ディストリビューターが設定されているか
EXEC sp_get_distributor;

 
データのオンラインマイグレーションは、移行先の SQL Database でクエリを再生することで変更を反映させますので、トリガーなどが設定されていると予期せぬ変更がトリガーされる可能性がありますので、移行元のテーブルに対しての変更操作は、DMS からのみ実施されるようにトリガーについても移行中は無効化しておきます。
Attunity Replicate のようなレプリケーションソフトを使用して連携する場合もそうなのですが、この手の機能を SQL Server で利用する場合は、「レプリケーション」「CDC」の機能と連動するケースが多く、DMS もそのような構成になっていますので、移行元の状態についても気にしておく必要があるのがポイントですね。
ちなみに移行元のテーブルが格納されている DB に対して、管理用テーブルが作成されますので、「DMS で移行を実施するに際して、移行元に対してなにも変更をかけていないか」と言われると、それに対しては No が回答となります。
 

移行のための移行先の整備

DMS のオンラインマイグレーションですが、現状は「データを移行するためのサービス」となっています。

ということで、このサービス単体では、スキーマの移行はしてくれません…。
SQL Server から SQL Database にデータベースの移行を行う際の補助ツールとして、Data Migration Assistant というツールが Microsoft から無償で提供されています。
このツールでは、SQL Server から SQL Database への移行を実施する際のスキーマ生成を行う機能もありますので、まずはこの機能を使って、移行対象のテーブルのスキーマを SQL Database に作成します。
移行元 / 移行先で条件が整っているテーブルについては DMS で移行対象として選択できるようになっています。

表示されてないテーブルについては、移行の条件が満たされていないものになります。

(条件 : 主キーが設定されている / CDC が有効化されている / 移行先にテーブルが作成されている)
image
 

データ移行の仕組み

DMS によるオンラインマイグレーションのデータ移行ですが、

  • フェーズ 1 : 初期移行
  • フェーズ 2 : 増分移行
  • フェーズ 3 : カットオーバー

の 3 フェーズで実施されます。
現状の移行方法としては、この流れがセットになっており、「他の方法で全体を移行してから、増分移行を実施」ということはできません。

1 ~ 3 の流れをすべて通して実行する必要があります。
フェーズ 1
フェーズ 1 では、初期のデータ移行として、一括で SQL Database にデータの移行が行われます。

SQL Database で、移行対象テーブルに既にデータが存在している場合、データが初期化されますので、移行は必ずゼロからのスタートとなります。
今回は、Basic の DTU を使用していたのですが、初期移行は、SQL Server から全件データを取得して、1,000 件ぐらいずつ一括挿入をしているように見受けられました。
初期移行は、SQL Server の読み取り性能だけでなく、SQL Database のログの書き込み性能も移行速度に影響を与える一因となりますので、移行時には、一時的に高い性能の DTU を割り当てておくというような考慮が必要となります。
 
フェーズ 2
フェーズ 2 が、増分移行となり、フェーズ 1 で移行が完了した移行の変更内容について SQL Database に連携が行われます。

DMS のデータ移行方法については、現時点では、内部的な動作の詳細な情報が公開されていないので、トレース等を自分で取得した内容をベースに解析をしていますが、結構興味深い移行方法が行われていそうでした。

(この辺の移行方法の詳細については、Ignite 2018 で解説されるセッションがあるのではないかと思いますが)
増分データのベースとしている内容についてはおそらく 3 種類の情報を組み合わせているのかと思います。

  • レプリケーションから、連携対象のログシーケンス番号 (LSN) の判断
  • CDC から連携対象の LSN の判断
  • 移行データをトランザクションログから読み込み

このような感じで増分データを連携していそうでした。
DMS でオンラインマイグレーションの設定を行うと、移行元の SQL Server に次のようなレプリケーションの設定がされます。
image
SQL Server のレプリケーションでは、データはサブスクライバーに対して転送が行われるという動作になりますが、DMS で設定されるレプリケーションはサブスクライバーが存在しないレプリケーションとして作成が行われます。

つまり、レプリケーションの機能をそのまま使ってデータ転送がされていないということですね。
動作を見ているとレプリケーションや、CDC の設定は、どこまでログレコードを連携したかという LSN の把握に使っており、それらの機能で使用する連携 / 履歴データをそのまま SQL Database に流すのではなく、

  • トランザクションログのログレコードを取得し、それを元に、生成したクエリを SQL Database 側で実行させる

というようなアーキテクチャが使用されていそうでした。
そのため、DMS を設定するとバックグラウンドで定期的に fn_dblog の内容を取得するクエリが実行されます。

この際、LSN を指定してログレコードの検索をしており、「どこまでデータを連携したか」「どの LSN からが増分データの対象となるか」というような情報を生成するためのレプリケーションや CDC のように見受けられました。
データ同期のソフトによっては、レプリケーションのログリーダーの仕組みや、CDC によって、作成された履歴データをもとに、移行先で再生するというようなアーキテクチャがとられることがあるのですが、DMS は

  • トランザクションログのログレコードを直接検索し、内部のバイナリデータをもとに、SQL Database で実行するクエリを生成する

というような興味深い手法がとられていそうでした。

トランザクションログのレコードを使用するので「一括復旧」または「完全復旧」のモデルが必要となるわけですね。
ログレコードを直接読む関係上、「未連携のレコードがトランザクションログのバックアップで切り捨てられる」ことは避けなくてはいけません。

その対応として、移行元のデータベースに「dms_truncation_safeguard」というテーブルを作成し、このテーブルの内容を使用して、トランザクションログのバックアップによるログレコードの切り捨てを制御するというアーキテクチャがとられていそうでした。
このテーブルには、「LatchKey」が「A」「B」のレコードがセットとなっており、データ作成時には同一時間帯の「latchLocker」が設定されたレコードが作成されます。
image
このレコードは 5 分間隔で更新され、「A」が更新された 5 分後に「B」のレコードを更新するというように、1 レコードずつ更新タイミングをずらしながらトランザクションを発生させていく仕組みのようでした。
このような仕組みを採用している理由ですが、

  • アクティブなトランザクションが存在している場合、そのトランザクション以降のログレコードはバックアップを実施しても切り捨てされない

という動作を使うためのように見受けられます。
これにより、DMS 自身が「どのトランザクションログがバックアップを取得された際に切り捨てられてもよいか」を制御できるようにしているようです。

この仕組みを理解するまでにちょっと時間がかかったのですが、中々に面白いことをしていますね。
SQL Database 側にデータを反映する際にエラーとなったレコードについては、SQl Database に作成される「dms_apply_exceptions」というテーブルで確認することができます。
SQL Database の DB は、読み取り専用になっているわけではなく、書き込みも実行できてしまいますので、自分で INSERT を実行すると、キー重複が発生する状況なども作り出すことができてしまいます。

データの反映に失敗した場合は、上記のテーブルにログが記録されますので、移行中はこのテーブルを定期的に確認した方がよさそうでした。
フェーズ 3
フェーズ 3 は、移行を最終完了させ、データの同期を終了するフェーズとなります。

日本語のポータルでは「一括で開始」となっていて、ちょっと何のことかわかりずらいのですが、

image
英語のポータルでは、「Sttart Cutover」となっています。

image
個人的には、英語版の方が意味が通じやすいのではと思いますが、要は、SQL Database を最新の情報を持った稼働系のサーバーとするために、データの最終同期を行うというものになります。
これを実行するとデータ同期が終了しますので、このタイミングでは、一時的に SQL Server への更新が発生しないようにする必要があります。

これにより、データ同期が完了し、以降はアプリケーションの接続先は、SQL Database を設定し、完全に切り替えを行うことになります。
今後、ドキュメントや情報がいろいろと出てくるかと思いますが、調べてみるとなかなか面白い方法でデータ同期をしていそうですね。
AWS でも Database Migration Serivce (DMS) が存在しています。

データ移行の考え方は、プラットフォームが違っていても、勉強になるところが多いですので、Azure だけでなく、AWS ではどうやっているかを調べることも大事かと。

Share

Written by Masayuki.Ozawa

9月 2nd, 2018 at 10:14 pm

Leave a Reply