使用 WMI 提供程序处理服务器事件

适用范围:SQL Server

本文提供了在使用 WMI 提供程序进行服务器事件编程之前应考虑的准则。

启用 Service Broker

WMI Provider for Server Events 通过将事件的 WQL 查询转换为目标数据库中的事件通知而发挥作用。 在针对提供程序编程时,了解事件通知的工作方式可能对您很有用。 有关详细信息,请参阅 适用于服务器事件的 WMI 提供程序概念

具体而言,由于 WMI 提供程序创建的事件通知使用 SQL Server 发送有关服务器事件的消息,因此必须在生成事件的位置启用此服务。 如果程序查询服务器实例上的事件,则必须启用该实例中的 msdb Service Broker,因为这是由提供程序创建的目标 Service Broker 服务(名为 SQL/Notifications/ProcessWMIEventProviderNotification/v1.0)的位置。 如果程序查询数据库中的事件或特定数据库对象上的事件,则必须启用该目标数据库中的 Service Broker。 如果在部署应用程序后未启用相应的 Service Broker,则基础事件通知生成的任何事件将发送到事件通知使用的服务队列,但在启用 Service Broker 之前不会返回到 WMI 管理应用程序。

以下查询确定在服务器实例上启用的 Service Broker 和 Broker 实例 GUID:

SELECT name, is_broker_enabled, service_broker_guid FROM sys.databases;

服务代理 GUID msdb 尤其感兴趣,因为这是提供程序的目标服务的位置。

若要在数据库中启用 Service Broker,请使用 ALTER DATABASE 语句的 ENABLE_BROKER SET 选项。

指定连接字符串

应用程序通过连接到提供程序定义的 WMI 命名空间,将 WMI Provider for Server 事件定向到 SQL Server 实例。 Windows WMI 服务将此命名空间映射到提供程序 DLL Sqlwep.dll 并将其加载到内存。 SQL Server 的每个实例都有自己的 WMI 命名空间,默认为:\\.\root\Microsoft\SqlServer\ServerEvents\instance_name在 SQL Server 的默认安装中,instance_name默认为 MSSQLSERVER。

权限和服务器身份验证

若要访问 WMI 提供程序 for Server 事件,WMI 管理应用程序所发起的客户端必须与应用程序连接字符串中指定的 SQL Server 实例中经过 Windows 身份验证的登录名或组相对应。

权限和事件通知范围

WMI Provider for Server Events 将 WQL 查询转换为目标数据库中的事件通知。 因此,调用应用程序不仅必须具有访问提供程序所需的最低权限,还必须在数据库中具有正确的权限才能创建所需的事件通知。 以下是对这些权限的说明:

  • 若要创建以数据库为作用域的事件通知,至少需要在当前数据库中具有 CREATE DATABASE DDL EVENT NOTIFICATION 权限。

  • 若要对以服务器为作用域的 DDL 语句创建事件通知,至少需要在该服务器中具有 CREATE DDL EVENT NOTIFICATION 权限。

  • 若要对跟踪事件创建事件通知,至少需要在服务器中具有 CREATE TRACE EVENT NOTIFICATION 权限。

  • 若要创建以队列为作用域的事件通知,至少需要对该队列具有 ALTER 权限。

有关如何确定 WQL 查询的作用域的信息,请参阅 将 WQL 与 WMI Provider for Server Events 结合使用

为了对作用域进行说明,请考虑包含以下 WQL 查询的一个 WMI 提供程序应用程序:

SELECT * FROM ALTER_TABLE
WHERE DatabaseName = "AdventureWorks2022"
    AND SchemaName = "Person"
    AND ObjectName = "Person"
    AND ObjectType = "TABLE";

该 WMI 提供程序将此查询转换为在 AdventureWorks2022 数据库中创建的事件通知。 这意味着调用方必须具有创建这类事件通知所需的权限,具体而言,就是在 AdventureWorks2022 数据库中具有 CREATE DATABASE DDL EVENT NOTIFICATION 权限。

如果 WQL 查询指定事件通知作用域为服务器级,例如通过发出查询 SELECT * FROM ALTER_TABLE,调用应用程序必须具有服务器级 CREATE DDL EVENT NOTIFICATION 权限。 服务器范围内的事件通知存储在 master 数据库中。 可以使用 sys.server_event_notifications 目录视图查看其元数据。

注意

WMI 提供程序创建的事件通知的作用域(服务器、数据库或对象)最终取决于 WMI 提供程序使用的权限验证过程的结果。 这受调用提供程序的用户的权限集和正在查询的数据库验证的影响。

在上面的示例中,提供程序首先尝试创建以数据库为作用域的事件通知 (ON DATABASE)。 如果提供程序验证数据库存在且调用方具有对其创建事件通知所需的权限,则注册成功。 如果未成功,提供程序将尝试在服务器上创建事件通知(ON SERVER)。 假设此尝试成功,则服务器上发生的所有 ALTER_TABLE 事件都会从 SQL Server 进程发送到 WMI 服务进程。 但是,提供程序会筛选掉任何不适用于 AdventureWorks2022 数据库的事件。 尽管此过程可能增加事件作用域所需的网络流量,但是它使您在创建数据库前可以选择在数据库上注册 WQL 查询,然后在创建数据库并启动针对它的 DDL 活动后接收事件数据。

权限和消息验证

如果满足以下两个条件,WMI 提供程序不会为事件通知发送消息:

  • 通过 WMI 提供程序创建了事件通知的用户已不存在于数据库中,或不再具有创建类似事件通知所需的权限。

  • 为以下事件创建事件通知:

    • DROP_LOGIN

    • ALTER_LOGIN

    • DROP_USER

    • ALTER_USER

    • ADD_ROLE_MEMBER

    • DROP_ROLE_MEMBER

    • ADD_SERVER_ROLE_MEMBER

    • DROP_SERVER_ROLE_MEMBER

    • DENYREVOKE (仅适用于ALTER DATABASE、、ALTER ANY DATABASE EVENT NOTIFICATIONCREATE DATABASE DDL EVENT NOTIFICATIONCONTROL SERVERALTER ANY EVENT NOTIFICATIONCREATE DDL EVENT NOTIFICATIONCREATE TRACE EVENT NOTIFICATION权限。

在客户端处理事件数据

在目标数据库中创建所需的事件通知后,事件通知会将事件数据发送到名为 SQL/Notifications/ProcessWMIEventProviderNotification/v1.0 的目标服务msdb。 目标服务将事件放入名为 WMIEventProviderNotificationQueuemsdb队列中。 (服务与队列在首次连接到 SQL Server 时由提供程序动态创建。然后,提供程序从此队列中读取 XML 事件数据,并将其转换为托管对象格式(MOF),然后再将其返回到客户端应用程序。 MOF 数据由 WQL 查询作为公共信息模型 (CIM) 类定义请求的事件属性组成。 每个属性具有相应的 CIM 类型。 例如,属性 SPID 作为 CIM 类型 Sint32 返回。 每个属性的 CIM 类型在 WMI 事件类和属性WMI 提供程序中的每个事件类下列出。