在内存中创建具有 ring_buffer 目标的事件会话

适用于:Azure SQL 数据库Azure SQL 托管实例

本演练中的大致步骤包括:

  1. 使用 ring_buffer 目标创建并启动事件会话
  2. 将捕获的事件数据视为 XML
  3. 将捕获的事件数据视为关系行集

使用 ring_buffer 目标时,比 event_file 目标的使用步骤更简单,因为无需在Azure 存储中存储事件数据。

使用 ring_buffer 目标创建并启动事件会话

要在 SQL Server Management Studio (SSMS) 中创建新的事件会话,请展开扩展事件节点。 此节点位于 Azure SQL 数据库的数据库文件夹下,位于 Azure SQL 托管实例的管理文件夹下。 右键单击“会话”文件夹,然后选择“新建会话...”。在“常规”页上,输入在此示例中为 example-session 的会话的名称。 在“事件”页上,选择要添加到会话的一个或多个事件。 在此例中,选择了 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 个),并将最大缓冲区内存设置为 1MB 或更少。 有关详细信息,请参阅 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

选择“确定”以创建会话。

将会话数据视为 XML

在对象资源管理器中,展开“会话”文件夹以查看创建的事件会话。 默认情况下,会话在创建时不会启动。 要启动会话,请右键单击会话名称,然后选择“启动会话”。 如果会话正在运行,稍后可以同样通过选择“停止会话”来停止会话。

在此数据库或托管实例中执行 T-SQL 批处理时,会话会在内存缓冲区中写入事件。 由于内存缓冲区的大小是有限的,因此在内存用尽后,旧事件会被弃用,以便为较新的事件腾出空间。

在对象资源管理器中,展开会话以查看 package0.ring_buffer 目标,然后双击该目标。 还可以右键单击并选择“查看目标数据...”。这会打开一个显示 XML 段落的网格。 选择此 XML 段落以查看展示内存缓冲区内容的 XML 文档。

XML 文档的第一行描述了会话和目标元数据:

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

在此示例中,我们会看到 ring_buffer 目标处理了 17 个事件。 未删除任何事件,因为缓冲区内存尚未耗尽,并且未达到我们配置的最大事件数(1,000 个)。

提示

请注意属性 truncated。 如果设置为 1,则表示内存缓冲区的 XML 表示形式未显示整个缓冲区内容。 有关详细信息,请参阅 ring_buffer 目标

XML 文档的其余部分包含事件。 XML 中单个事件的表示形式可能如下所示:

  <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 批处理(此示例中的单个查询)。

将会话数据视为关系行集

要查看关系行集中 ring_buffer 目标的事件数据,则需要编写 T-SQL 查询,该查询使用 XQuery 表达式将 XML 转换为关系数据。

下面是我们创建的会话示例,其中首先显示最新的事件:

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;