Azure SQL 数据库和 Azure SQL 托管实例中的扩展事件

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

有关扩展事件的简介,请参阅:

Azure SQL 数据库和 Azure SQL 托管实例中扩展事件的特征集、功能和使用方案与 SQL Server 中提供的特征集、功能和使用方案类似。 主要差异在于:

  • 目标 event_file 始终使用Azure 存储中的 blob,而不是使用磁盘上的文件。
  • Azure SQL 数据库仅支持数据库范围的事件会话。 这意味着:
    • 一个数据库中的事件会话无法收集另一个数据库中的事件。
    • 事件必须发生在用户数据库的上下文中才能包含在会话中。
  • 在Azure SQL 托管实例中,可以创建服务器范围和数据库范围的事件会话。 建议在大多数情况下使用服务器范围的事件会话。

开始使用

以下两个示例可帮助快速了解 Azure SQL 数据库和 Azure SQL 托管实例中的扩展事件:

  • 在 Azure 存储中创建具有 event_file 目标的会话。 此示例演示如何使用 event_file 目标在Azure 存储中捕获文件 (blob) 中的事件数据。 如果需要持久化捕获的事件数据,或者想使用 SQL Server Management Studio (SSMS) 中的事件查看器来分析捕获的数据,请使用此功能。
  • 在内存中创建具有 ring_buffer 目标的会话。 此示例演示如何使用 ring_buffer 目标从内存中的事件会话捕获最新事件。 使用此方法可以快速查看临时调查或故障排除期间最近发生的事件,而无需存储捕获的事件数据。

扩展事件可用于监视只读副本。 有关详细信息,请参阅副本上的读取查询

最佳实践

采用以下最佳做法可在 Azure SQL 数据库以及 Azure SQL 托管实例中可靠地使用扩展事件,且不会影响数据库引擎运行状况和工作负载性能。

  • 如果使用 event_file 目标:
    • 使用与创建事件会话的数据库或托管实例位于同一 Azure 区域的存储帐户。
    • 使存储帐户的冗余与数据库、弹性池或托管实例的冗余保持一致。 对于本地冗余的资源,请使用 LRS、GRS 或 RA-GRS。 对于区域冗余的资源,请使用 ZRS、GZRS 或 RA-GZRS。 有关详细信息,请参阅 Azure 存储冗余
    • 请勿使用除 Hot 以外的任何 Blob 访问层
  • 如果要创建在数据库引擎每次重启后会自动启动的持续运行的事件会话(例如故障转移或维护事件之后),请在 CREATE EVENT SESSIONALTER EVENT SESSION 语句中包含事件会话选项 STARTUP_STATE = ON
  • 反之,用 STARTUP_STATE = OFF 创建短期事件会话,例如临时故障排除中使用的会话。
  • 在 Azure SQL 数据库中,不要从内置 dl 事件会话读取死锁事件。 如果收集了大量死锁事件,则使用 sys.fn_xe_file_target_read_file() 函数读取它们可能会导致 master 数据库中出现内存不足错误。 这可能会影响登录处理并导致应用程序中断。 有关监视死锁的建议方法,请参阅使用扩展事件收集 Azure SQL 数据库中的死锁图

事件会话目标

Azure SQL 数据库和 Azure SQL 托管实例支持以下目标:

  • event_file 目标。 将完整缓冲区写入 Azure 存储容器中的 blob。
  • ring_buffer 目标。 在事件数据替换为新事件数据前,将其保存在内存中。
  • event_counter 目标。 计算在扩展事件会话过程中发生的所有事件的数目。
  • 直方图目标。 计算不同存储桶中不同值的字段或操作的出现次数。
  • event_stream。 将事件数据流式传输到 .Net 应用程序。

注意

Azure SQL 数据库和Azure SQL 托管实例中的 event_stream 目标处于预览状态。

Transact-SQL 的差异

在 SQL Server 和 Azure SQL 托管实例 中执行 CREATE EVENT SESSIONALTER EVENT SESSIONDROP EVENT SESSION 语句时,请使用 ON SERVER 子句。 在 Azure SQL 数据库 中,改用 ON DATABASE 子句,因为 Azure SQL 数据库中的事件会话是针对数据库范围的。

扩展事件目录视图

扩展事件提供多个目录视图。 目录视图告知事件会话 元数据定义。 视图不会返回有关活动事件会话的实例的信息。

目录视图名称 说明
sys.database_event_session_actions 返回针对事件会话的每个事件执行的每个操作所对应的行。
sys.database_event_session_events 返回事件会话中每个事件所对应的行。
sys.database_event_session_fields 返回针对事件和目标上显式设置的每个可自定义列所对应的行。
sys.database_event_session_targets 返回事件会话的每个事件目标所对应的行。
sys.database_event_sessions 返回数据库中每个事件会话所对应的行。

扩展事件动态管理视图

扩展事件提供若干动态管理视图 (DMV)。 DMV 可返回有关“已启动”的事件会话的信息。

DMV 的名称 说明
sys.dm_xe_database_session_event_actions 返回有关事件会话操作的信息。
sys.dm_xe_database_session_events 返回有关会话事件的信息。
sys.dm_xe_database_session_object_columns 显示绑定到会话的对象的配置值。
sys.dm_xe_database_session_targets 返回有关会话目标的信息。
sys.dm_xe_database_sessions 返回当前数据库中运行的每个事件会话所对应的行。

通用 DMV

有通用于 Azure SQL 数据库、Azure SQL 托管实例和 SQL Server 的其他扩展事件 DMV:

可用的扩展事件、操作和目标

与在 SQL Server 中一样,可以使用此查询获取可用事件、操作和目标:

SELECT o.object_type,
       p.name AS package_name,
       o.name AS db_object_name,
       o.description AS db_obj_description
FROM sys.dm_xe_objects AS o
INNER JOIN sys.dm_xe_packages AS p
ON p.guid = o.package_guid
WHERE o.object_type IN ('action','event','target')
ORDER BY o.object_type,
         p.name,
         o.name;

权限

提示

2022 年,微软针对扩展事件推出了许多更精细的新权限,有关详细信息,请参阅博客:SQL Server 2022 和 Azure SQL 的新粒度权限,以改进对 PoLP 的遵守

在 Azure SQL 数据库和 Azure SQL 托管实例中,扩展事件支持精细的权限模型。 可授予以下权限:

CREATE ANY DATABASE EVENT SESSION
DROP ANY DATABASE EVENT SESSION
ALTER ANY DATABASE EVENT SESSION
ALTER ANY DATABASE EVENT SESSION ADD EVENT
ALTER ANY DATABASE EVENT SESSION DROP EVENT
ALTER ANY DATABASE EVENT SESSION ADD TARGET
ALTER ANY DATABASE EVENT SESSION DROP TARGET
ALTER ANY DATABASE EVENT SESSION ENABLE
ALTER ANY DATABASE EVENT SESSION DISABLE
ALTER ANY DATABASE EVENT SESSION OPTION

有关每个权限控件的信息,请查阅 CREATE EVENT SESSIONALTER EVENT SESSION、和 DROP EVENT SESSION

所有这些权限都包含在数据库或托管实例的 CONTROL 权限中。 在 Azure SQL 数据库中,数据库所有者 (dbo)、db_owner 数据库角色的成员和逻辑服务器管理员持有数据库 CONTROL 权限。 在 Azure SQL 托管实例中,sysadmin 服务器角色的成员对实例拥有 CONTROL 权限。

存储容器授权和控制

使用 event_file 目标时,事件数据存储在 Azure 存储容器中的 blob 中。 运行事件会话的数据库引擎必须具有对此容器的特定访问权限。 可通过以下方式之一授予此访问权:

  • 存储 Blob 数据参与者 RBAC 角色分配给容器中 Azure SQL 逻辑服务器或 Azure SQL 托管实例的托管标识,并创建凭证以指示数据库引擎使用托管标识进行身份验证。

    作为分配存储 Blob 数据参与者 RBAC 角色的替代方法,可以分配以下 RBAC 操作:

    命名空间 操作
    Microsoft.Storage/storageAccounts/blobServices/containers/ read
    Microsoft.Storage/storageAccounts/blobServices/containers/blobs/ delete
    Microsoft.Storage/storageAccounts/blobServices/containers/blobs/ read
    Microsoft.Storage/storageAccounts/blobServices/containers/blobs/ write

    注意

    使用托管标识与扩展事件会话的功能目前处于预览阶段。

  • 为容器创建 SAS 令牌,并将令牌存储在凭证中。

    在Azure SQL 数据库中,必须使用数据库范围的凭据。 在Azure SQL 托管实例中,使用服务器范围的凭据。

    为 Azure 存储容器创建的 SAS 令牌必须满足以下要求:

    • 具有 rwdl (ReadWriteDeleteList) 权限。
    • 具备包含事件会话生存期的开始时间和到期时间。
    • 无 IP 地址限制。

资源治理

在Azure SQL 数据库中,扩展事件会话的内存消耗由数据库引擎动态控制,以便最大程度地减少资源争用。

事件会话的可用内存有上限:

  • 在单一数据库中,会话总内存上限为 128 MB。
  • 在弹性池中,单个数据库受单个数据库限制,总共不能超过 512 MB。

如果收到关于内存限制的错误消息,可以采取以下纠正措施:

  • 减少运行的并发事件会话。
  • 对事件会话使用 CREATEALTER 语句,减少在会话的 MAX_MEMORY 子句中指定的内存量。

注意

在扩展事件中,MAX_MEMORY 子句出现在两个上下文中:创建或更改会话时(会话级别),以及使用 ring_buffer 目标时(目标级别)。 上述限制适用于会话级别内存。

在 Azure SQL 数据库中,启动的事件会话存在数量上限:

  • 在单一数据库中,上限为 100 个。
  • 在弹性池中,限制为每个池 100 个数据库范围的会话。

密集弹性池中,即使启动的会话总数低于 100,启动新的扩展事件会话也可能因内存限制而失败。

要查找事件会话消耗的总内存,请在连接到启动事件会话的数据库时执行以下查询:

SELECT name AS session_name,
       total_buffer_size + total_target_memory AS total_session_memory
FROM sys.dm_xe_database_sessions;

要查找弹性池的事件会话内存总量,则需要在池中的每个数据库中执行此查询。