使用 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 事件,必须在 msdb 和 AdventureWorks2012 中启用 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 文档,该文档显示死锁图形事件的所有属性。