SE の雑記

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

SQL Databaese の Ring Buffer の Time Stamp を日付に変換してみる

leave a comment

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 の代替として利用したところ、数秒のずれはありますがおおよその日付として妥当性のある情報となっていました。
image
Ring Buffer は標準で取得されている情報であり、SQL Server  / SQL Database で何があったかを把握したいときに調査の一助となりますので、SQL Database でも「どのタイミングで記録された情報なのか?」がわかると利便性が高いのではないでしょうか。

Share

Written by Masayuki.Ozawa

1月 13th, 2020 at 8:51 pm

Posted in SQL Database

Tagged with

Leave a Reply