扩展事件目标

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Microsoft Fabric 预览版中的 SQL 数据库

本文介绍何时以及如何使用扩展事件目标。 对于每个目标,本文介绍了:

  • 其收集和报告事件数据的能力
  • 使用目标的事件会话示例

下表描述了不同 SQL 平台中每个目标类型的可用性。

目标类型 SQL Server Azure SQL 数据库与 Fabric 中的 SQL 数据库 Azure SQL 托管实例
事件文件
环形缓冲区 (ring_buffer)
event_stream
直方图
事件计数器
配对匹配
etw_经典同步目标

除非以不同的方式指出,否则目标会以异步方式处理它们接收的数据。

若要充分利用本文,应:

event_file 目标

目标将 event_file 事件会话输出从内存缓冲区写入磁盘文件或 Azure 存储中的 Blob。

  • filename 子句中指定 ADD TARGET 参数。 文件扩展名必须为 xel
  • 你选择的文件名由系统用作附加基于日期时间的数值的前缀,后跟 xel 扩展名。
  • 可以选择指定 MAX_FILE_SIZE 参数。 它定义文件在创建新文件之前可以增长到的最大大小(MB)。
  • 可以选择指定MAX_ROLLOVER_FILES选项,来决定除了当前文件外,文件系统中保留的最大文件数。 默认值为 UNLIMITED。 当 MAX_ROLLOVER_FILES 被评估时,如果文件数超过 MAX_ROLLOVER_FILES 设置,旧文件将被删除。

重要

根据添加到会话的事件,目标生成的 event_file 文件可能包含敏感数据。 仔细查看文件系统,并共享目录和单个 .xel 文件(包括继承的访问权限)的权限,以避免授予不必要的读取访问权限。 遵循 最低特权原则。 为了降低无意中收集敏感数据的风险,如果可能会收集敏感数据,请避免长时间运行的事件会话。

注意

Azure SQL 数据库和 Azure SQL 托管实例仅支持 Azure 存储 中的二进制大对象作为 filename 参数的值。 event_file有关 Azure SQL 数据库、Fabric 中的 SQL 数据库或 Azure SQL 托管实例的代码示例,请参阅在 Azure 存储中创建具有event_file目标的事件会话

在本地文件系统中创建具有event_file目标的事件会话

有关使用 event_file 本地文件存储、SSMS 或 T-SQL 创建事件会话的演练,请参阅 快速入门:扩展事件

在 Azure 存储中创建具有event_file目标的事件会话

有关如何在 Azure 存储中创建存储帐户的详细说明,请参阅 “创建存储帐户”。 可以使用 Azure 门户、PowerShell、Azure SQL、ARM 模板或 Bicep 模板创建存储帐户。 使用一个满足以下条件的帐户:

  • Standard general-purpose v2是一个帐户。
  • Hot使用 二进制大对象访问层
  • 如果在 Azure VM 中使用 SQL Server,则存储帐户应与 Azure VM 位于同一 Azure 区域中。
  • 未启用 分层命名空间

接下来,使用 Azure 门户在此存储帐户 中创建容器 。 还可以 使用 PowerShell 或使用 Azure CLI 创建容器。

记下创建的 存储帐户容器 的名称。 你将在以下步骤中使用它们。

若要读取和写入事件数据,数据库引擎需要特定访问权限。 根据所选的身份验证类型,您可以通过不同方式授予此访问权限:托管标识或< c1 >使用共享访问签名(SAS)令牌进行的基于机密的身份验证。

若要向 Azure 存储进行身份验证,数据库引擎需要 服务器范围的凭据或数据库范围的凭据 ,该凭据告知其要使用的身份验证类型,并为基于机密的身份验证提供机密。 创建此凭据需要 CONTROL 数据库权限。

对于 SQL Server 和 Azure SQL 托管实例,数据库中需要 master 此权限。 默认情况下,权限由数据库角色db_owner的成员master以及实例上的服务器角色的成员sysadmin持有。 对于 Fabric 中的 Azure SQL 数据库和 SQL 数据库,此权限由数据库所有者(dbo)、数据库角色的成员 db_owner 和逻辑服务器的管理员持有。

创建凭据后,创建事件会话的剩余步骤不需要 CONTROL 权限。 有关所需的特定权限,请参阅 “权限 ”。

使用托管标识授予访问权限

如果使用托管标识进行 Microsoft Entra 身份验证,请将 存储 Blob 数据参与者 RBAC 角色分配给数据库引擎所使用的容器托管标识。 有关详细信息,请参阅以下 SQL 平台相关内容:

设定好 RBAC 角色分配后,使用以下步骤:

  1. 使用 T-SQL 创建凭据。

    在执行以下 T-SQL 批处理之前,请进行以下更改:

    • 在所有三个https://<storage-account-name>.blob.core.windows.net/<container-name>出现项中,将<storage-account-name>替换为存储帐户的名称,并将<container-name>替换为容器的名称。 请确保 URL 末尾没有尾随斜杠。

    创建服务器范围的凭据适用于: SQL Server、Azure SQL 托管实例

    使用 SSMS 等客户端工具打开一个新的查询窗口,连接到 master 要在其中创建事件会话的实例上的数据库,并粘贴以下 T-SQL 批处理。

    /* The name of the credential must match the URL of the blob container. */
    IF EXISTS ( SELECT 1 FROM sys.credentials
                WHERE name = 'https://<storage-account-name>.blob.core.windows.net/<container-name>' )
        DROP CREDENTIAL [https://<storage-account-name>.blob.core.windows.net/<container-name>];
    
    /* When using managed identity, the credential does not contain a secret */
    CREATE CREDENTIAL [https://<storage-account-name>.blob.core.windows.net/<container-name>]
    WITH IDENTITY = 'MANAGED IDENTITY';
    

    创建数据库范围的凭据适用于: Azure SQL 数据库、Azure SQL 托管实例、Fabric 中的 SQL 数据库

    使用 SSMS 等客户端工具打开一个新的查询窗口,连接到创建事件会话的用户数据库,并粘贴以下 T-SQL 批处理。 请确保已连接到用户数据库,而不是连接到 master 数据库。

    /* The name of the credential must match the URL of the blob container. */
    IF EXISTS ( SELECT 1 FROM sys.database_credentials
              WHERE name = 'https://<storage-account-name>.blob.core.windows.net/<container-name>' )
        DROP DATABASE SCOPED CREDENTIAL
            [https://<storage-account-name>.blob.core.windows.net/<container-name>];
    
    /* When using managed identity, the credential does not contain a secret */
    CREATE DATABASE SCOPED CREDENTIAL
        [https://<storage-account-name>.blob.core.windows.net/<container-name>]
    WITH IDENTITY = 'MANAGED IDENTITY';
    
  2. 然后,按照步骤 在 SSMS 中创建包含 event_file 目标的事件会话,并将其存储在 Azure 存储中

使用共享访问签名(SAS)令牌授予访问权限

如果使用 基于机密的身份验证,请为容器创建 共享访问签名 (SAS) 令牌 。 若要使用此身份验证类型,必须为存储帐户启用 “允许存储帐户密钥访问 ”选项。 有关详细信息,请参阅阻止对 Azure 存储帐户进行共享密钥授权

  1. 在 Azure 门户中,导航到创建的存储帐户和容器。 选择容器,然后导航到 “设置 > 共享访问令牌”。

    SAS 令牌必须满足以下要求:

    • 权限设置为 Read,,WriteDeleteList
    • 开始时间和到期时间必须包含事件会话的生存期。 创建的 SAS 令牌仅在此时间间隔内有效。
    • 对于 Fabric 中的 Azure SQL 数据库、Azure SQL 托管实例和 SQL 数据库,SAS 令牌必须没有 IP 地址限制。

    选择“ 生成 SAS 令牌和 URL ”按钮。 SAS 令牌位于 Blob SAS 令牌 框中。 可以复制它以在下一步中使用。

    重要

    SAS 令牌提供对此容器的读取和写入访问权限。 将其视为处理密码或任何其他机密。

    Azure 存储容器的“共享访问令牌”屏幕的屏幕截图,其中为示例容器生成了 SAS 令牌。

  2. 创建凭据以使用 T-SQL 存储 SAS 令牌。

    在执行以下 T-SQL 批处理之前,请进行以下更改:

    • 如果您要创建服务器范围的凭据并使用 CREATE MASTER KEY 语句,请将 <password> 替换为用于保护主密钥的实际密码。 有关详细信息,请参阅 CREATE MASTER KEY
    • 在所有三个https://<storage-account-name>.blob.core.windows.net/<container-name>出现项中,将<storage-account-name>替换为存储帐户的名称,并将<container-name>替换为容器的名称。
    • SECRET 子句中,将 <sas-token> 替换为上一步中复制的 SAS 令牌。

    创建服务器范围的凭据:适用于 SQL Server、Azure SQL 托管实例

    使用 SSMS 等客户端工具打开一个新的查询窗口,将其连接到 master 创建事件会话的实例上的数据库,并粘贴以下 T-SQL 批处理。

    /* Create a master key to protect the secret of the credential */
    IF NOT EXISTS (
                  SELECT 1
                  FROM sys.symmetric_keys
                  WHERE name = '##MS_DatabaseMasterKey##'
                  )
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<password>';
    
    /* The name of the credential must match the URL of the blob container. */
    IF EXISTS
        (SELECT 1 FROM sys.credentials
        WHERE name = 'https://<storage-account-name>.blob.core.windows.net/<container-name>'
        )
        DROP CREDENTIAL
            [https://<storage-account-name>.blob.core.windows.net/<container-name>];
    
    /* The secret is the SAS token for the container. */
    CREATE CREDENTIAL
        [https://<storage-account-name>.blob.core.windows.net/<container-name>]
    WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
        SECRET = '<sas-token>';
    

    创建数据库范围的凭据:适用于 Azure SQL 数据库、Azure SQL 托管实例、Fabric 中的 SQL 数据库

    使用 SSMS 等客户端工具打开一个新的查询窗口,连接到创建事件会话的数据库,并粘贴以下 T-SQL 批处理。 请确保已连接到用户数据库,而不是连接到 master 数据库。

    /* The name of the credential must match the URL of the blob container. */
    IF EXISTS
        (SELECT 1 FROM sys.database_credentials
        WHERE name = 'https://<storage-account-name>.blob.core.windows.net/<container-name>')
        DROP DATABASE SCOPED CREDENTIAL
            [https://<storage-account-name>.blob.core.windows.net/<container-name>];
    
    /* The secret is the SAS token for the container. */
    CREATE DATABASE SCOPED CREDENTIAL
        [https://<storage-account-name>.blob.core.windows.net/<container-name>]
    WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
        SECRET = '<sas-token>';
    
  3. 然后,按照下一部分中的步骤在 SSMS 中创建一个事件会话,并将 event_file 目标设置在 Azure 存储中

在 Azure 存储中使用event_file目标在 SSMS 中创建事件会话

创建提供对存储容器访问权限的凭据后,可以创建事件会话。 与创建凭据不同,创建事件会话不需要 CONTROL 权限。 创建凭据后,即使拥有更多受限的权限,也可以创建事件会话。 有关所需的特定权限,请参阅 “权限 ”。

若要在 SSMS 中创建新的事件会话,请执行以下作:

  1. 对于 SQL Server 和 Azure SQL 托管实例,请展开“管理”文件夹下的“扩展事件”节点。 对于 Fabric 中的 Azure SQL 数据库和 SQL 数据库,展开数据库下的 扩展事件 节点。
  2. 右键单击 “会话 ”文件夹,然后选择“ 新建会话...”
  3. “常规 ”页上,输入会话的名称,该名称将 example-session 用于以下代码示例。
  4. 在“ 事件 ”页上,选择要添加到会话的一个或多个事件。 例如,可以选择事件 sql_batch_starting
  5. “数据存储 ”页上,选择 event_file 为目标类型。 将存储容器的 URL 粘贴到 “存储 URL ”框中。 在此 URL 的末尾输入正斜杠(/),然后输入文件 (blob) 名。 例如,https://<storage-account-name>.blob.core.windows.net/<container-name>/example-session.xel
  6. 配置会话后,可以选择“ 脚本 ”按钮创建会话的 T-SQL 脚本,以便稍后保存。
  7. 选择“确定”以创建会话。
  8. 在对象资源管理器中,展开“会话”文件夹以查看创建的事件会话。 默认情况下,会话在创建时不会启动。 要启动会话,请右键单击会话名称,然后选择“启动会话”。 如果会话正在运行,稍后可以同样通过选择“停止会话”来停止会话。

执行 T-SQL 批处理时,会话会将 sql_batch_starting 事件 example-session.xel 写入存储容器中的 Blob。

注意

对于 SQL 托管实例,请使用“脚本”按钮创建会话的 T-SQL 脚本,而不是粘贴“数据存储”页面上的存储容器 URL。 将容器 URL 指定为参数的值 filename ,并执行脚本来创建会话。

在 T-SQL 中,在 Azure 存储中创建目标为 event_file 的事件会话

下面是一个示例,包含一个使用CREATE EVENT SESSIONADD TARGET子句,添加了一个基于Azure存储的event_file目标。

CREATE EVENT SESSION [example-session] ON SERVER
ADD EVENT sqlserver.sql_batch_starting
ADD TARGET package0.event_file
    (SET filename=
     N'https://<storage-account-name>.blob.core.windows.net/<container-name>/example-session.xel')
GO

若要在 Azure SQL 数据库或 Fabric 中的 SQL 数据库中使用此示例,请替换为 ON SERVERON DATABASE

排查 Azure 存储中event_file目标的事件会话问题

以下列表包含启动使用 Azure 存储的扩展事件会话时可能会遇到的错误,并提供了错误的可能解释。

  • 作系统返回错误 5:“访问被拒绝”。
    • 如果使用托管标识身份验证:
      • 数据库引擎使用的托管标识没有所需的 RBAC 角色分配。 有关详细信息,请参阅 使用托管标识授予访问权限
      • 已启用存储帐户 防火墙 ,同时启用了允许受信任的 Azure 服务访问存储帐户的异常,但 Microsoft.Sql/servers 尚未将逻辑服务器的资源实例添加到已授予访问权限的资源实例列表中。 有关详细信息,请参阅 从 Azure 资源实例授予访问权限
      • 如果使用具有强制模式 的网络安全外围 ,则数据库和存储帐户不在同一外围中。
    • 如果使用 SAS 令牌身份验证:
      • 存储帐户的 防火墙 已启用。 使用 SAS 令牌身份验证的事件会话不适用于此。
      • SAS 令牌没有足够的权限或已过期。 有关详细信息,请参阅 使用 SAS 令牌授予访问权限
      • 如果使用强制模式的网络安全外围,则缺乏允许数据库进行不受限制的出站通信以及允许存储帐户进行不受限制的入站通信的访问规则。
  • 作系统返回错误 86:“指定的网络密码不正确。
    • 没有任何数据库范围的凭据(适用于 Azure SQL 数据库)或服务器范围的凭据(对于 Azure SQL 托管实例或 SQL Server)的名称与 Blob 存储容器 URL 匹配。 有关详细信息,请参阅使用 托管标识授予访问权限 的示例,或使用 SAS 令牌授予访问权限
    • 凭据名称以斜杠结尾(/)。 凭据名称应以容器名称结尾,并且不包括末尾的斜杠。
  • 作系统返回错误 3:“系统找不到指定的路径。
    • Blob 容器 URL 中指定的容器不存在。
  • 作系统返回错误 13:“数据无效。
    • Blob 容器上存在 不可变策略 。 事件会话不支持不可变存储。
    • 存储帐户已启用 分层命名空间 。 事件会话不支持启用了分层命名空间的存储帐户。

sys.fn_xe_file_target_read_file() 函数

event_file 目标以二进制格式(不可人工读取)存储其接收的数据。 该 sys.fn_xe_file_target_read_file 函数允许将文件的内容 xel 表示为关系行集。 有关详细信息,包括用法示例,请参阅 sys.fn_xe_file_target_read_file

ring_buffer 目标

目标 ring_buffer 可用于快速启动事件会话并仅收集内存中的事件数据。 当环形缓冲区中的可用内存由事件使用时,将丢弃较旧的事件。 当您停止事件会话时,所有输出到 ring_buffer 目标的会话内容也会被丢弃。

如以下示例所示,通过将其转化为 XML 来使用 ring_buffer 中的数据。 转换过程中会省略任何 4MB XML 文档无法容纳下的数据。 因此,即使是使用更大的 MAX_MEMORY 值捕获环形缓冲区中的更多事件(或将此参数保留为其默认值不变),也无法使用全部数据,因为考虑到 XML 标记和 Unicode 字符串的开销问题,XML 文档大小的上限为 4MB。

例如,如果 XML 文档中的 truncated 属性设置为 1,则你知道在转换为 XML 的过程中会忽略环形缓冲区的内容:

<RingBufferTarget truncated="1" processingTime="0" totalEventsProcessed="284" eventCount="284" droppedCount="0" memoryUsed="64139">

提示

添加 ring_buffer 目标时,将其 MAX_MEMORY 参数设置为 1,024 KB 或更少。 使用更大的值可能会占用更多不必要的内存。

默认情况下, MAX_MEMORY 目标 ring_buffer 在 SQL Server 中不受限制,在 Azure SQL 数据库、Azure SQL 托管实例和 Fabric 中的 SQL 数据库中限制为 32 MB。

创建一个具有ring_buffer目标的事件会话

下面是使用目标创建事件会话 ring_buffer 以收集 lock_acquired 事件的示例,将环形缓冲区中的事件总数限制为 100。 在此示例中,参数 MAX_MEMORY 显示两次:一次将 ring_buffer 目标内存设置为 1024 KB,一次将事件会话缓冲区内存设置为 2 MB。

若要在 Azure SQL 数据库或 Fabric 中的 SQL 数据库中使用此示例,请替换为 ON SERVERON DATABASE

CREATE EVENT SESSION ring_buffer_lock_acquired ON SERVER
    ADD EVENT sqlserver.lock_acquired
    ADD TARGET package0.ring_buffer
    (
        SET MAX_EVENTS_LIMIT = 100,
            MAX_MEMORY = 1024
    )
    WITH
    (
        MAX_MEMORY = 2 MB,
        MAX_DISPATCH_LATENCY = 3 SECONDS
    );

若要启动事件会话,请执行以下语句:

ALTER EVENT SESSION ring_buffer_lock_acquired ON SERVER STATE = START;

若要查看 SSMS 中环形缓冲区中收集的事件数据,请展开会话节点并选择 package0.ping_buffer 目标。 数据以 XML 格式显示。

若要在会话处于活动状态时查看关系行集中目标的事件数据 ring_buffer ,请使用 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_session_targets AS xst
INNER JOIN sys.dm_xe_sessions AS xs
ON xst.event_session_address = xs.address
WHERE xs.name = N'ring_buffer_lock_acquired'
),
/* 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;

event_stream 目标

可以在用 C# 等语言编写的 .NET 程序中使用 event_stream 目标。 开发人员可以通过命名空间中的 Microsoft.SqlServer.XEvents.Linq .NET Framework 类访问事件流。 此目标在任何事件会话中都隐式存在。 无法使用 T-SQL 添加它。

有关详细信息,请参阅 sys.fn_MSxe_read_event_stream

如果遇到错误 25726,The event data stream was disconnected because there were too many outstanding events. To avoid this error either remove events or actions from your session or add a more restrictive predicate filter to your session. 当从 event_stream 目标进行取决时,意味着事件流填满数据的速度快于客户端使用数据的速度。 这导致数据库引擎断开与事件流的连接以避免影响数据库引擎的性能。

histogram 目标

目标 histogram 计算字段或操作中不同值的事件出现次数。 对于每个独特值,使用单独的计数容器。 histogram 目标同步处理所接收的数据。

参数 SOURCE_TYPE 控制目标的行为 histogram

  • SOURCE_TYPE = 0:收集某个事件字段的数据。
  • SOURCE_TYPE = 1:收集某个操作的数据。 这是默认情况。

参数的 SLOTS 默认值为 256。 如果指定另一个值,该值将四舍五入为下一个 2 的幂。 例如,SLOTS = 59 将被向上舍入至64。 目标 histogram 的最大直方图槽数量为 16,384。

使用 histogram 命令作为目标时,有时可能会看到意外结果。 某些事件可能不会出现在预期的槽中,而其他槽则可能显示比预期的事件计数更高的计数。 如果将事件分配到槽时发生哈希冲突,则可能会发生这种情况。 虽然这种情况很少见,如果发生哈希冲突,则本应在一个槽中计数的事件会计入到另一个槽中。 出于此原因,应注意假设事件未发生,只是因为特定槽中的计数显示为零。

例如,请考虑以下情形:

  • 设置一个扩展事件会话,使用 histogram 作为目标,并按 object_id 对事件进行分类,以收集存储过程执行统计信息。
  • 执行存储过程 A。 然后,执行存储过程 B

如果哈希函数返回 object_id 这两个存储过程的相同值,则直方图显示 A 两次执行,而 B 不会出现。

若要解决非重复值数量相对较少这一问题,请将直方图槽的数量设置得高于预期非重复值的平方。 例如,如果 histogram 目标的 SOURCE 设置为 table_name 事件字段,且数据库中有 20 个表,则 20*20 = 400。 2 比 400 大的下一个乘方是 512,也就是本示例中建议使用的槽数量。

每个 histogram 目标仅接受来自单一来源(事件字段或操作)的数据,并且只包含一个直方图。 每个事件会话不能添加多个相同类型的目标。 每个histogram目标也不可能有多个源类型。 因此,需要新的事件会话来跟踪单独histogram目标中的任何其他操作或事件字段。

使用直方图目标创建一个事件会话

以下是创建包含 histogram 目标的事件会话的示例。

若要在 Azure SQL 数据库或 Fabric 中的 SQL 数据库中使用此示例,请替换为 ON SERVERON DATABASE

CREATE EVENT SESSION histogram_lock_acquired
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
        (
        ACTION
            (
            sqlos.system_thread_id
            )
        )
    ADD TARGET package0.histogram
        (
        SET
            FILTERING_EVENT_NAME = N'sqlserver.lock_acquired',
            SLOTS = 16,
            SOURCE = N'sqlos.system_thread_id',
            SOURCE_TYPE = 1
        );

ADD TARGET ... (SET ...)子句中,目标参数SOURCE_TYPE被设置为1,这表示histogram目标跟踪一个动作。

ADD EVENT ... (ACTION ...)子句将sqlos.system_thread_id操作添加到事件中。 该 SOURCE 参数设置为 sqlos.system_thread_id,以使用由该操作收集的系统线程 ID 作为 histogram 目标的数据来源。 在此示例中,histogram目标是在会话处于活动状态时计算每个获取锁的系统线程的lock_acquired事件数。

若要启动事件会话,请执行以下语句:

ALTER EVENT SESSION histogram_lock_acquired ON SERVER STATE = START;

若要查看 SSMS 中收集的直方图数据,请展开会话节点并选择 package0.histogram 目标。 数据以两列网格形式显示。 每一行表示一个由非重复值构成的分组及其出现次数。

下面是此示例中目标histogram可能捕获的数据的外观。 value 列中的值是 system_thread_id 值。 例如,系统线程 6540 总共获取了 236 个锁。

value   count
-----   -----
 6540     236
 9308      91
 9668      74
10144      49
 5244      44
 2396      28

event_counter 目标

event_counter 目标对每个指定事件发生的次数进行计数。

目标 event_counter 没有参数并处理它同步接收的数据。

创建一个具有 event_counter 目标的事件会话

以下是创建包含 event_counter 目标的事件会话的示例。 会话对前四 checkpoint_begin 个事件进行计数,然后停止计数,因为它的谓词将发送到目标的事件数限制为 4。 可以通过执行checkpoint_begin命令来生成CHECKPOINT此示例的事件。

若要在 Azure SQL 数据库或 Fabric 中的 SQL 数据库中使用此示例,请替换为 ON SERVERON DATABASE

CREATE EVENT SESSION event_counter_checkpoint_begin
    ON SERVER
    ADD EVENT sqlserver.checkpoint_begin
    (
        WHERE package0.counter <= 4
    )
    ADD TARGET package0.event_counter
    WITH
    (
        MAX_MEMORY = 4096 KB,
        MAX_DISPATCH_LATENCY = 3 SECONDS
    );

若要启动事件会话,请执行以下语句:

ALTER EVENT SESSION event_counter_checkpoint_begin ON SERVER STATE = START;

若要查看 SSMS 中收集的数据,请展开会话节点并选择 package0.event_counter 目标。 数据显示在三列网格中。 每一行表示一个事件,其出现次数为计数。

下面是四个检查点后这个示例中由event_counter目标采集的数据可能呈现的样子。

package_name   event_name         count
------------   ----------------   -----
sqlserver      checkpoint_begin   4

pair_matching 目标

pair_matching 目标可让你检测到没有对应结束事件发生的开始事件。 例如,您可能会发现lock_acquired事件没有匹配的lock_released事件,这可能表明一个长期运行的事务正在持有锁。

扩展事件不会自动匹配开始和结束事件。 而是要在pair_matching目标规范中利用CREATE EVENT SESSION语句定义匹配逻辑。 当开始和结束事件被匹配时,目标将丢弃这对事件,但保留未匹配的起始事件。

使用pair_matching目标创建事件会话

对于此示例,我们将创建一个名为 T1,插入三行的示例表,并获取 object_id 此表的值。 为简单起见,我们在此示例中创建数据库中的 tempdb 表。 如果使用其他数据库,请调整以下 T-SQL 示例代码中的数据库名称。

CREATE TABLE T1
(
id int PRIMARY KEY
);

INSERT INTO T1 (id)
VALUES (1),(2),(3);

SELECT OBJECT_ID('T1') AS object_id;
-- object_id = 1029578706

以下事件会话收集两个事件, lock_acquired 以及 lock_released。 它还有两个目标。 一个是提供每个事件出现次数的目标 event_counter。 用于定义将开始 pair_matching 事件和结束 lock_acquired 事件配对的逻辑的目标是 lock_released

分配给 BEGIN_MATCHING_COLUMNSEND_MATCHING_COLUMNS 的以逗号分隔的字段序列必须相同。 即使空格正确,但是以逗号分隔的值中所涉及的字段之间不允许有制表符或换行符。

在事件会话定义中,我们使用事件谓词仅在数据库中收集那些事件,其中事件中的tempdb与表object_id的对象 ID 匹配。 调整子句中的 WHERE 谓词以使用您的表的对象 ID。

若要在 Azure SQL 数据库或 Fabric 中的 SQL 数据库中使用此示例,请替换为 ON SERVERON DATABASE

CREATE EVENT SESSION pair_matching_lock_acquired_released
    ON SERVER
    ADD EVENT sqlserver.lock_acquired
    (
        SET
            COLLECT_DATABASE_NAME = 1,
            COLLECT_RESOURCE_DESCRIPTION = 1
        ACTION (sqlserver.transaction_id)
        WHERE
        (
            database_name = 'tempdb'
            AND
            object_id = 1029578706
        )
    ),
    ADD EVENT sqlserver.lock_released
    (
        SET
            COLLECT_DATABASE_NAME = 1,
            COLLECT_RESOURCE_DESCRIPTION = 1
        ACTION (sqlserver.transaction_id)
        WHERE
        (
            database_name = 'tempdb'
            AND
            object_id = 1029578706
        )
    )
    ADD TARGET package0.event_counter,
    ADD TARGET package0.pair_matching
    (
        SET
            BEGIN_EVENT = N'sqlserver.lock_acquired',
            BEGIN_MATCHING_COLUMNS =
                N'resource_0, resource_1, resource_2, transaction_id, database_id',
            END_EVENT = N'sqlserver.lock_released',
            END_MATCHING_COLUMNS =
                N'resource_0, resource_1, resource_2, transaction_id, database_id',
            RESPOND_TO_MEMORY_PRESSURE = 1
    )
    WITH
    (
        MAX_MEMORY = 8192 KB,
        MAX_DISPATCH_LATENCY = 15 SECONDS
    );

若要启动事件会话,请执行以下语句:

ALTER EVENT SESSION pair_matching_lock_acquired_released ON SERVER STATE = START;

启动一个更新 T1 表的事务,但不要提交或回滚。 这可确保获取但未释放锁。

BEGIN TRANSACTION;

UPDATE T1 SET
id = id + 1;

检查 SSMS 中事件会话的每个目标的 pair_matching_lock_acquired_released 输出。

目标 event_counter 具有以下输出,显示一个锁未释放。 然而,此目标对象未显示该锁的任何详细信息。

package_name   event_name      count
------------   ----------      -----
sqlserver      lock_acquired   4
sqlserver      lock_released   3

目标 pair_matching 具有以下输出,为简洁起见截断。 正如 event_counter 输出所示,我们的确看到了一行关于未配对 lock_acquired 事件的记录,其中提供了更多关于该事件的详细信息。

package_name  event_name    timestamp                     associated_object_id  database_id  database_name
------------  ------------  ---------                     -------------         -----------  -------------
sqlserver    lock_acquired   2025-10-01 20:06:07.1890000  1029578706            2            tempdb

请回滚该事务。

ROLLBACK;

如果在由 pair_matching 目标收集的事件上添加动作,动作数据也会被收集。 例如,可以将 sqlserver.sql_text 操作提供的 T-SQL 文本包含在事件中。 在此示例中,它将收集获取锁的查询。

etw_classic_sync_target 目标

在 SQL Server 中,扩展事件可以和 Windows 事件跟踪 (ETW) 相互操作来监视系统活动。 有关详细信息,请参阅:

此 ETW 目标处理同步接收的数据。