SQL Server / SQL Database では、「sys.dm_os_ring_buffers」という Ring Buffer の情報を確認することができます。
「Using sys.dm_os_ring_buffers To Diagnose Memory Issues in SQL Server」 等で解説をされているのですが、SQL Server の様々な情報をメモリ上に確保している DMV となります。
この DMV では timestamp という値を持っているのですが、この値を加工するためには、sys.dm_os_sys_info の ms_ticks を元にして、コンピューターを起動してからの経過時間を使用していつのイベントなのかを確認するのが一般的です。
しかし、sys.dm_os_sys_info については、SQL Database では使用することができず、この DMV では、コンピューターを起動してからの経過時間を取得することができません。
SQL Database で timestamp を実際の時間に直す方法が何かないか考えてみたのですが、sys.dm_os_memory_cache_clock_hands の round_start_time の最大値で代替できそうでした。
round_start_time を使用したクエリですが、次のようなクエリで実現できそうでした。
DECLARE @round_start_time bigint = (SELECT MAX(round_start_time) FROM sys.dm_os_memory_cache_clock_hands)
SELECT
rb.ring_buffer_address,
rb.ring_buffer_type,
rb.timestamp,
DATEADD(ms, (rb.timestamp - @round_start_time), GETDATE()) AS record_time,
CAST(rb.record AS xml) AS record,
CAST(rb.record AS xml).value('(/Record/@id)[1]','int') AS id,
CAST(rb.record AS xml).value('(//Error)[1]','int') AS Error,
CAST(rb.record AS xml).value('(//Severity)[1]','int') AS Severity,
CAST(rb.record AS xml).value('(//State)[1]','int') AS State,
m.text
FROM
sys.dm_os_ring_buffers AS rb
LEFT JOIN sys.messages AS m
ON m.message_id = CAST(rb.record AS xml).value('(//Error)[1]','int')
-- AND m.severity = CAST(rb.record AS xml).value('(//Severity)[1]','int')
AND m.language_id = 1033
WHERE
ring_buffer_type = 'RING_BUFFER_EXCEPTION'
ORDER BY timestamp DESC
round_start_time の最大値を ms_ticks の代替として利用したところ、数秒のずれはありますがおおよその日付として妥当性のある情報となっていました。
![]()
Ring Buffer は標準で取得されている情報であり、SQL Server / SQL Database で何があったかを把握したいときに調査の一助となりますので、SQL Database でも「どのタイミングで記録された情報なのか?」がわかると利便性が高いのではないでしょうか。