Azure SQL Managed Instance に SQL Server のデータベースバックアップを連続的に復元してを移行する際には、次の機能を使用することができます。
- ログ再生サービス (Log Replay Service: LRS)
- Azure Data Studio (ADS) + Azure Database Migration Service (DMS)
これらの機能では、
- 完全バックアップ
- 差分バックアップ
- トランザクションログバックアップ
を継続的に復元することで、Managed Instance にデータベースをリストアすることができ、Managed Instance にデータベースの移行時にダウンタイムを抑えた移行に活用することができます。
ログ再生サービスを使用しようとした場合に、コンテナー名に制限があることが分かったことと、問題が発生した際に確認すべき情報について把握できて来たので情報をまとめておきたいと思います。
LRS と ADS + DMS のどちらも再生可能なリストア (Resumable restore) の機能が使用されているため本内容はどちらのリストア方法でも該当します。
参考としては次の情報を確認しておくとよいかと思います。
- Log Replay Service (プレビュー) を使用して SQL Server から SQL Managed Instance にデータベースを移行する
- Azure Data Studio 用 Azure SQL 移行拡張機能を使用してデータベースを移行する
- チュートリアル: Azure Data Studio と DMS を使用して SQL Server を Azure SQL Managed Instance にオンラインで移行する
- Database migrations to Azure SQL Managed Instance – Restore with Full and Differential backups
- Getting Started with Log Replay Service for Azure SQL Managed Instance
直近で実施された改善として、次のアナウンスで 36 時間の実行時間の制限については 30 日に拡大されているようなので、この機能の最新情報については次の情報も確認しておくとよいかと思います。
Contents
Managed Instance にリストアするデータベースバックアップの取得
この内容については、今回の本題ではないので軽いメモとして記載しておきたいと思いm差う。
Managed Instance にリストアをするデータベースのバックアップについては 「CHECKSUM」オプションを指定して取得を行う必要がありますので、このオプションを指定したバックアップの取得を行います。
「COMPRESSION」については必須ではありませんが、圧縮しておいたほうが、BLOB ストレージへのファイルアップロード時間を短縮できるため、可能であれば指定しておいたほうが良いかと思います。
SQL Server のバックアップですが、最大で 64 個のバックアップデバイスに分割して取得することができます。
データベースサイズが大きい場合には、分割したバックアップを取得して、ファイルのアップロードを実施したほうが効率が良いので、バックアップファイルが大きくなる場合には分割を検討しておきます。
バックアップファイルの配置場所
SQL Server のバックアップファイルを Managed Instance にリストアする場合、リストア方法に応じて、利用可能なバックアップファイルの配置場所が異なってきます。
- RESTORE ステートメント: Azure BLOB ストレージ
- ログ再生サービス: Azure BLOB ストレージ
- ADS + DMS: SMB ファイル共有 / Azure BLOB ストレージ
ADS + DMS を使用している場合は、SMB ファイル共有を使用することができますが、それ以外の方法では Azure BLOB ストレージ上に配置しているバックアップファイルをリストアすることにります。
Azure BLOB ストレージを使用したリストアが汎用的な方法になると思いますので、本投稿でも Azure BLOB ストレージに配置したバックアップファイルをリストアする前提で作業を行っています。
LRS ベースの機能で Azure BLOB ストレージからリストアする際の準備
事前の準備としては、次の二つが必要となります。
- Azure BLOB ストレージにバックアップファイルを格納する
- 使用する SAS を生成する
前述のとおり、LRS / ADS + DMS では Azure BLOB ストレージからデータベースのバックアップをリストアすることができますが、BLOB への接続については Shared Access Signature (SAS) を使用します。
使用する SAS については、必要となる権限が設定されているものを使用する必要があります。
次の設定で生成した SAS であれば使用できるはずです。
Read / List のみの権限が設定されているというのがポイントとなり、それ以外のアクセス許可が設定されていると、次のエラーで実行ができないので使用する SAS については権限を注意しておく必要があります。
Start-AzSqlInstanceDatabaseLogReplay : The external backup storage container SAS token is invalid – SAS token must have only read and list permission.
LRS ベースの機能で Azure BLOB ストレージを使用する際に使用できないコンテナー名
LRS ではメッセージが表示されないのですが、ADS + DMS を使用した場合には、分かりやすいメッセージが表示されます。
メッセージに出力されているように、LRS のアーキテクチャを使用するリストア方法では「backup」というコンテナー名については制限があり使用することができません。
そのため「https://xxxxxxxx.blob.core.windows.net/backup/db01」という コンテナーの指定をすると、リストアができずエラーとなりますので、バックアップファイルを保存する BLOB ストレージのコンテナー名については気を付けておく必要があります。
LRS が動作しない場合に確認したい情報
ADS + DMS を使用した場合は上述のとおり、エラー内容を判断しやすいメッセージが出力されるのですが、LRS で実行した場合には、次のようなメッセージとなり、エラー内容を把握することができません。
LRS が動作しない場合は、Managed Instance 側で情報を参照する必要があり、次の情報を参照するとよいかと思います。
- ERRORLOG
- 拡張イベント (or SQL Server プロファイラー)
ERRORLOG
Managed Instance は ERRORLOG を確認することができますので、SSMS や次のクエリで ERROR LOG を確認できます。
-- EXEC sp_cycle_errorlog EXEC sp_readerrorlog
Managed Instance の ERRORLOG は蓄積されますので、「sp_cycle_errorlog」を実行してログをローテートして最新の情報のみを確認できるようにしておいてもよいかと思います。
LRS が動作しない場合、ERRORLOG に次のようなメッセージが出力されています。
Sending the notification action: NotifyRestoreProgress
Http code after sending the notification for action NotifyRestoreProgress: 204
このようなメッセージが出力されている場合は、バックアップの不備や、コンテナー名の制約により LRS が動作していない可能性があります。
拡張イベント (or SQL Server プロファイラー)
LRS によるリストアについては、BackupService / RestoreService で実行されますので、これらのプログラムから実行されているクエリを取得することでも動作を確認することができます。
Managed Instance の拡張イベントはライブイベントを取得できますので、次のようなイベントを作成すると実行されているクエリを確認することができます。
CREATE EVENT SESSION [backup_restore] ON SERVER ADD EVENT sqlserver.rpc_completed( ACTION(sqlserver.client_app_name) WHERE ([sqlserver].[client_app_name]=N'BackupService' OR [sqlserver].[client_app_name]=N'RestoreService')), ADD EVENT sqlserver.sql_batch_completed(SET collect_batch_text=(1) ACTION(sqlserver.client_app_name) WHERE ([sqlserver].[client_app_name]=N'BackupService' OR [sqlserver].[client_app_name]=N'RestoreService')) WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF) GO
この拡張イベントで情報を確認していると、エラーが発生している (backup というコンテナーを使用している) と、次のようなクエリをキャプチャすることができます。
declare @p2 nvarchar(1024) set @p2=NULL exec sp_cloud_get_xstore_credential @XStorePath=N'https://xxxxxxx.blob.core.windows.net',@output=@p2 output select @p2
実行しているのは、BLOB ストレージへの資格情報を指定するクエリになるのですが、「@p2」が NULL になっていることが確認できます。正常な実行方法であれば、この変数には LRS の開始時に指定した SAS が指定されるのですが、エラーが発生している状態では SAS がストアドに連携されておらず、何らかの問題が発生している可能性を検討することができます。
また、実行結果については、次のようなストアドプロシージャが実行されていることが確認できます。
declare @p3 int set @p3=204 exec sp_cloud_send_global_action @action=N'NotifyRestoreProgress', @payload=0x7B20226D65737xxxxxxxx343D22207D, @httpcode=@p3 output select @p3
このストアドプロシージャのメッセージが LRS の実行状態を示すメッセージのペイロードとして使用されているようなのですが、「@payload」の 16 進数の値は次のようにしてエンコードすることができます。
- 「@payload」の内容を varchar に変換
- 変換後の出力結果の JSON を Base64でデコード
実際に変換してみると次のようになります。
varchar に変換することで、メッセージを取り出すことができます。
Base64でデコードすると、次のようにメッセージを取り出すことができます。
これらの情報を確認すると、現在何が起こっているのかを把握する一助になります。
今回はドキュメントに記載されていない「backup というコンテナー名が使用できない」という内部使用により、LRS でエラーが発生していたのですが (ドキュメントへの記載については検討してもらっています) 、このような情報の取得方法を覚えておくと内部的にどのような処理が行われているかを把握することができ、SR で問い合わせをする際にもスムーズに情報を伝達できるのではないでしょうか。