SQL Database のテレメトリ情報を取得する方法としては、次の DMV / システムビューを検索するという方法があります。
- sys.resource_stats
- sys.dm_db_resource_stats
- sys.dm_resource_governor_resource_pools_history_ex
- sys.dm_resource_governor_workload_groups_history_ex
SQL Database で発生している「イベント」を取得する方法としては、sys.event_log を参照するという方法があるのですが、このシステムビューは、検索に時間がかかる、かつ、v11 での利用を想定しており、現在の v12 の環境では有益な情報を取得できないケースがあります。
v12 の環境で、「発生しているイベント」を取得する方法として、sys.event_log / 拡張イベントを使用しなくても標準で取得されているテレメトリからイベントを取得するという方法がありますので、本投稿ではその方法についてみていきたいと思います。
現状、初期状態で「デッドロック」の情報を取得するためには、本投稿の内容を使用することになるかと思います。
Contents
sys.fn_xe_telemetry_blob_target_read_file を活用する
sys.event_log のドキュメントに書かれているのですが、現状の v12 の SQL Database で、デッドロックの情報を取得するためには、簡単な例 に記載されている 「sys.fn_xe_telemetry_blob_target_read_file」から、BLOB に保存されているテレメトリ情報を取得する必要があります。
ドキュメントには次のクエリが記載されています。
WITH CTE AS ( SELECT CAST(event_data AS XML) AS [target_data_XML] FROM sys.fn_xe_telemetry_blob_target_read_file('dl', null, null, null) ) SELECT target_data_XML.value('(/event/@timestamp)[1]', 'DateTime2') AS Timestamp, target_data_XML.query('/event/data[@name=''xml_report'']/value/deadlock') AS deadlock_xml, target_data_XML.query('/event/data[@name=''database_name'']/value').value('(/value)[1]', 'nvarchar(100)') AS db_name FROM CTE
デッドロックが発生していた場合、クエリを実行することで、次のような情報を取得することができます。
「deadlock_xml」が XML で出力されているデッドロックの情報となります。
この XML は拡張子を「xdl」にして保存し、SSMS で開くと、次のようなデッドロックグラフを表示することができます。
SQL Server の場合は、system_health で既定でデッドロックの情報が取得されるように設定が行われています。
SQL Database の場合は、sys.fn_xe_telemetry_blob_target_read_file で確認ができる、標準で BLOB に取得されているテレメトリ情報の拡張イベントから情報を取得することができますので、デッドロックの情報を後追いすることが、SQL Server と同様に可能となっています。
sys.fn_xe_telemetry_blob_target_read_file で確認が可能な情報
sys.fn_xe_telemetry_blob_target_read_file で情報を確認する際には ‘dl’ として検索を行っていました。
この仕組みは拡張イベント相当の情報が使用されているようで、’dl’ として検索を行った場合は、「dl で始まるファイルを対象として検索を行う」というような動作となります。
デッドロック用の dl で始まるファイル以外にはどのようなものがあるのでしょうか?
次のようなスクリプトを実行して確認をしてみます。
Clear-Host $conString = "server=xxxxxx.database.windows.net;user=xxxxx;password=xxxxxx" $con = New-Object System.Data.SqlClient.SqlConnection($conString) $con.Open() $sb = New-Object System.Text.StringBuilder 97..122 | %{ $first = [char]$_ 97..122 | %{ $second = [char]$_ $sql = ("select top 10 '{0}{1}' AS type, timestamp_utc, object_name, file_name, cast(event_data as xml) as event_data from sys.fn_xe_telemetry_blob_target_read_file('{0}{1}', null, null, null) order by timestamp_utc desc" -f $first,$second) $cmd = New-Object System.Data.SqlClient.SqlCommand($sql, $con) $cmd.CommandTimeout = 0 $reader = $cmd.ExecuteReader() $dt = New-Object System.Data.DataTable $dt.Load($reader) if($dt.Rows.Count -ne 0){ Write-Host $sql } $reader.Close() } } $con.Dispose()
私が使用している環境では、次のような結果が取得できました。
少なくても、次のような 4 つのタイプについては標準で取得されているようです。
select top 10 'dl' AS type, timestamp_utc, object_name, file_name, cast(event_data as xml) as event_data from sys.fn_xe_telemetry_blob_target_read_file('dl', null, null, null) order by timestamp_utc desc select top 10 'el' AS type, timestamp_utc, object_name, file_name, cast(event_data as xml) as event_data from sys.fn_xe_telemetry_blob_target_read_file('el', null, null, null) order by timestamp_utc desc select top 10 'rs' AS type, timestamp_utc, object_name, file_name, cast(event_data as xml) as event_data from sys.fn_xe_telemetry_blob_target_read_file('rs', null, null, null) order by timestamp_utc desc select top 10 'ru' AS type, timestamp_utc, object_name, file_name, cast(event_data as xml) as event_data from sys.fn_xe_telemetry_blob_target_read_file('ru', null, null, null) order by timestamp_utc desc
冒頭で記載した DMV の情報では、リソースの使用状況の情報が取得されていますが、保持期間は次のようになっています。
- sys.resource_stats : 5 分間隔で最大 14 日
- sys.dm_db_resource_stats : 15 秒間隔で最大 1 時間
今回取得した BLOB のテレメトリ情報は、私の環境では、次のようになっていました。
- dl : database_xml_deadlock_report
- el : login_event : 48 日 ?? (私の環境では 44 日前のデータが残っていました)
- rs : external_telemetry_resource_stats : 5 分間隔で最大 14 日
- ru : external_telemetry_resource_usage : 1 時間間隔で最大 44 日 ?? (私の環境では 44 日前のデータが残っていました)
BLOB に保存されているデータの方が保持期間が長いものもありそうですので、DMV と併用することができそうですね。
まとめ
SQL Database では、system_health セッションを使用することはできませんが、sys.fn_xe_telemetry_blob_target_read_file で取得できる情報でいくつかのテレメトリが取得されています。
拡張イベント等による情報取得を明示的に実施していない環境でも、sys.fn_xe_telemetry_blob_target_read_file から情報を確認することで、いくつかの情報については後追いできる可能性がありますので、活用してみると良いのではないでしょうか。
情報検索の体感的には、sys.event_log / sys.event_log_ex より高速に検索出来ている気がしますので、データ検索の即応性についても sys.event_log より、sys.fn_xe_telemetry_blob_target_read_file の方が情報を確認しやすい気がします。
[…] https://blog.engineer-memo.com/2021/04/15/sql-database-%e3%81%a7%e6%a8%99%e6%ba%96%e3%81%ae%e3%83%86… […]
【後で読みたい!】SQL Database で sys.fn_xe_telemetry_blob_target_read_file を使用して標準取得されているテレメトリ情報を確認する | Tak's Bar
17 4月 21 at 16:28