示例:使用用于服务器事件的 WMI 提供程序创建 SQL Server 代理警报

使用 WMI 事件提供程序的一种常见方法是创建响应特定事件的 SQL Server 代理警报。 下面的示例演示了一个简单的警报,用于在表中保存 XML 死锁图形事件以供以后分析。 SQL Server 代理提交 WQL 请求,接收 WMI 事件,并运行作业以响应事件。 请注意,尽管涉及多个 Service Broker 对象来处理通知消息,但 WMI 事件提供程序处理创建和管理这些对象的详细信息。

示例:

首先,在数据库中创建 AdventureWorks 一个表来保存死锁图形事件。 该表包含两列: AlertTime 列保存警报运行的时间,该 DeadlockGraph 列包含包含死锁图的 XML 文档。

然后,将创建警报。 该脚本首先创建警报将运行的作业,将作业步骤添加到作业,并将该作业定向到 SQL Server 的当前实例。 然后,该脚本将创建警报。

作业步骤检索 WMI 事件实例的 TextData 属性,并将该值插入到 DeadlockEvents 表的 DeadlockGraph 列中。 请注意,SQL Server 将字符串隐式转换为 XML 格式。 由于作业步骤使用 Transact-SQL 子系统,因此作业步骤不指定代理。

每当记录死锁图形跟踪事件时,警报就会运行作业。 对于 WMI 警报,SQL Server 代理使用指定的命名空间和 WQL 语句创建通知查询。 对于此警报,SQL Server 代理监视本地计算机上的默认实例。 WQL 语句请求 DEADLOCK_GRAPH 默认实例中的任何事件。 若要更改警报监视器的实例,请将实例名称替换为警报中的@wmi_namespace实例名称MSSQLSERVER

注释

要使 SQL Server 代理接收 WMI 事件,必须在 msdbAdventureWorks2012 中启用 Service Broker。

USE AdventureWorks ;  
GO  
  
IF OBJECT_ID('DeadlockEvents', 'U') IS NOT NULL  
BEGIN  
    DROP TABLE DeadlockEvents ;  
END ;  
GO  
  
CREATE TABLE DeadlockEvents  
    (AlertTime DATETIME, DeadlockGraph XML) ;  
GO  
-- Add a job for the alert to run.  
  
EXEC  msdb.dbo.sp_add_job @job_name=N'Capture Deadlock Graph',   
    @enabled=1,   
    @description=N'Job for responding to DEADLOCK_GRAPH events' ;  
GO  
  
-- Add a jobstep that inserts the current time and the deadlock graph into  
-- the DeadlockEvents table.  
  
EXEC msdb.dbo.sp_add_jobstep  
    @job_name = N'Capture Deadlock Graph',  
    @step_name=N'Insert graph into LogEvents',  
    @step_id=1,   
    @on_success_action=1,   
    @on_fail_action=2,   
    @subsystem=N'TSQL',   
    @command= N'INSERT INTO DeadlockEvents  
                (AlertTime, DeadlockGraph)  
                VALUES (getdate(), N''$(ESCAPE_SQUOTE(WMI(TextData)))'')',  
    @database_name=N'AdventureWorks' ;  
GO  
  
-- Set the job server for the job to the current instance of SQL Server.  
  
EXEC msdb.dbo.sp_add_jobserver @job_name = N'Capture Deadlock Graph' ;  
GO  
  
-- Add an alert that responds to all DEADLOCK_GRAPH events for  
-- the default instance. To monitor deadlocks for a different instance,  
-- change MSSQLSERVER to the name of the instance.  
  
EXEC msdb.dbo.sp_add_alert @name=N'Respond to DEADLOCK_GRAPH',   
@wmi_namespace=N'\\.\root\Microsoft\SqlServer\ServerEvents\MSSQLSERVER',   
    @wmi_query=N'SELECT * FROM DEADLOCK_GRAPH',   
    @job_name='Capture Deadlock Graph' ;  
GO  

测试示例

若要查看作业运行,请引发死锁。 在 SQL Server Management Studio 中,打开两个 SQL 查询 选项卡并将这两个查询连接到同一实例。 在某个查询选项卡中运行以下脚本。 此脚本生成一个结果集并完成。

USE AdventureWorks ;  
GO  
  
BEGIN TRANSACTION ;  
GO  
  
SELECT TOP(1) Name FROM Production.Product WITH (XLOCK) ;  
GO  

在第二个查询选项卡中运行以下脚本。此脚本生成一个结果集,然后阻止,等待获取锁定 Production.Product

USE AdventureWorks ;  
GO  
  
BEGIN TRANSACTION ;  
GO  
  
SELECT TOP(1) Name FROM Production.Location WITH (XLOCK) ;  
GO  
  
SELECT TOP(1) Name FROM Production.Product WITH (XLOCK) ;  
GO  

在第一个查询选项卡中运行以下脚本。此脚本阻止,等待获取锁定。Production.Location 超时后,SQL Server 会选择此脚本或示例中的脚本作为死锁受害者并结束事务。

SELECT TOP(1) Name FROM Production.Location WITH (XLOCK) ;  
GO  

在引发死锁后,请等待几分钟,让 SQL Server 代理激活警报并运行作业。 通过运行以下脚本检查表的内容 DeadlockEvents

SELECT * FROM DeadlockEvents ;  
GO  

DeadlockGraph 列应包含一个 XML 文档,该文档显示死锁图形事件的所有属性。

另请参阅

服务器事件概念的 WMI 提供程序