メモリ内に ring_buffer ターゲットを含むイベント セッションを作成する

適用対象:Azure SQL データベースAzure SQL Managed Instance

このチュートリアルの手順の概要は次のとおりです:

  1. ring_buffer ターゲットとのイベント セッションを作成して開始する
  2. キャプチャされたイベント データを XML として表示する
  3. キャプチャされたイベント データをリレーショナル行セットとして表示する

ring_buffer ターゲットでは、Azure Storage にイベント データを格納する必要がないため、手順は event_file ターゲットよりも簡単です。

ring_buffer ターゲットとのイベント セッションを作成して開始する

SQL Server Management Studio (SSMS) で新しいイベント セッションを作成するには、オブジェクト エクスプローラーで同じデータベースを展開し、[拡張イベント] ノードを展開します。 このノードは、Azure SQL データベースのデータベース フォルダーの下にあり、Azure SQL Managed Instance の管理フォルダーの下にあります。 [セッション] フォルダーを右クリックし、[新しいセッション...] を選択します。[全般] ページで、セッションの名前を入力します。この例では、example-session です。 [イベント] ページで、セッションに追加する 1 つ以上のイベントを選択します。 この例では、sql_batch_starting イベントが選択されています。

Screenshot of the New Session SSMS dialog showing the event selection page with the sql_batch_starting event selected.

[データ ストレージ] ページで、ring_buffer をターゲットの種類として選択します。 メモリを節約するには、イベントの数を少数 (既定では 1,000) にし、最大バッファー メモリを 1 MB (メガバイト) 以下に設定することをお勧めします。 詳細については、「ring_buffer ターゲット」を参照してください。

Screenshot of the New Session SSMS dialog showing the data storage selection page with a ring_buffer target selected.

セッションが構成されたので、必要に応じて [スクリプト] ボタンを選択して、後で保存するセッションの T-SQL スクリプトを作成できます。 このセッション例のスクリプトを次に示します:

CREATE EVENT SESSION [example-session] ON DATABASE
ADD EVENT sqlserver.sql_batch_starting
ADD TARGET package0.ring_buffer(SET max_memory=(1024))
GO

[OK] を選択してセッションを作成します。

セッション データを XML として表示する

オブジェクト エクスプローラーで、セッション フォルダーを展開して、作成したイベント セッションを表示します。 既定では、セッションは作成時に開始されません。 セッションを開始するには、セッション名を右クリックし、[セッションの開始] を選択 します。 セッションが実行されたら、同様に [セッションの停止] を選択して、後で停止できます。

このデータベースまたはマネージド インスタンスで T-SQL バッチが実行されると、セッションはメモリ バッファーにイベントを書き込みます。 メモリ バッファーのサイズは有限であるため、すべてのメモリが使用されると、古いイベントは破棄され、新しいイベント用の領域が作られます。

オブジェクト エクスプローラーで、セッションを展開して package0.ring_buffer ターゲットを表示し、ターゲットをダブルクリックします。 右クリックして [ターゲット データの表示...] を選択することもできます。こうすると、XML 断片が表示されたグリッドが開きます。 この XML 断片を選択すると、メモリ バッファーの内容を表す XML ドキュメントが表示されます。

XML ドキュメントの最初の行では、セッションとターゲットのメタデータについて説明しています:

<RingBufferTarget truncated="0" processingTime="0" totalEventsProcessed="17" eventCount="17" droppedCount="0" memoryUsed="32070">

この例では、17 個のイベントが ring_buffer ターゲットによって処理されたことがわかります。 バッファー メモリが使い果たされておらず、構成したイベントの最大数 (1,000) に達していないため、イベントは削除されませんでした。

ヒント

truncated 属性に注意してください。 1 に設定されている場合は、メモリ バッファーの XML 表記にバッファーの内容全体が表示されていないことを意味します。 詳細については、「ring_buffer ターゲット」を参照してください。

XML ドキュメントの残りの部分にはイベントが含まれています。 XML での 1 つのイベントの表記は次のようになります:

  <event name="sql_batch_starting" package="sqlserver" timestamp="2023-10-18T17:43:34.079Z">
    <data name="batch_text">
      <type name="unicode_string" package="package0"></type>
      <value><![CDATA[SELECT
'DatabaseXEStore[@Name=' + quotename(CAST(db_name() AS sysname),'''') +' and @ServerName=' + quotename(CAST(SERVERPROPERTY('servername') AS sysname),'''') + ']' AS [Urn],
CAST(db_name() AS sysname) AS [Name],
CAST(SERVERPROPERTY('servername') AS sysname) AS [ServerName],
(SELECT count(*) FROM sys.dm_xe_database_sessions) AS [RunningSessionCount]]]></value>
    </data>
  </event>

ここでは、value 属性に T-SQL バッチ (この例では 1 つのクエリ) が含まれています。

セッション データをリレーショナル行セットとして表示する

リレーショナル行セット内のターゲットからの ring_buffer イベント データを表示するには、XQuery 式を使用して XML をリレーショナル データに変換する T-SQL クエリを記述する必要があります。

作成したセッションの例を次に示します。最初に最新のイベントが表示されます:

WITH
/* An XML document representing memory buffer contents */
RingBuffer AS
(
SELECT CAST(xst.target_data AS xml) AS TargetData
FROM sys.dm_xe_database_session_targets AS xst
INNER JOIN sys.dm_xe_database_sessions AS xs
ON xst.event_session_address = xs.address
WHERE xs.name = N'example-session'
),
/* A row for each event in the buffer, represented as an XML fragment */
EventNode AS
(
SELECT CAST(NodeData.query('.') AS xml) AS EventInfo
FROM RingBuffer AS rb
CROSS APPLY rb.TargetData.nodes('/RingBufferTarget/event') AS n(NodeData)
)
/* A relational rowset formed by using the XQuery value method */
SELECT EventInfo.value('(event/@timestamp)[1]','datetimeoffset') AS timestamp,
       EventInfo.value('(event/@name)[1]','sysname') AS event_name,
       EventInfo.value('(event/data/value)[1]','nvarchar(max)') AS sql_batch_text
FROM EventNode
ORDER BY timestamp DESC;