Поделиться через


Пример. Создание оповещения агент SQL Server с помощью поставщика WMI

Область применения: SQL Server

Один из общепринятых способов использования поставщика событий WMI состоит в создании предупреждений агента SQL Server, которые отвечают на конкретные события. В следующем образце представлено простое предупреждение, которое сохраняет события графа взаимоблокировок XML в таблице для последующего анализа. Агент SQL Server отправляет запрос WQL, получает события WMI и запускает задание в ответ на событие. Обратите внимание, что в обработке сообщения уведомления участвуют несколько объектов компонента Service Broker, но детальные операции создания и управления этими объектами возлагаются на поставщика событий WMI.

Пример

Прежде всего в базе данных AdventureWorks2022 создается таблица для хранения событий графа взаимоблокировок. Таблица содержит два столбца: AlertTime столбец содержит время выполнения оповещения, а DeadlockGraph столбец содержит XML-документ, содержащий граф взаимоблокировки.

Затем создается предупреждение. Скрипт сначала создает задание, которое будет выполняться оповещением, добавляет шаг задания в задание и предназначен для задания в текущий экземпляр SQL Server. После этого скрипт создает предупреждение.

Шаг задания извлекает TextData свойство экземпляра события WMI и вставляет это значение в DeadlockGraph столбец DeadlockEvents таблицы. SQL Server неявно преобразует строку в xml-формат. Так как шаг задания использует подсистему Transact-SQL, шаг задания не указывает прокси-сервер.

Предупреждение запускает задание каждый раз, когда регистрируется событие трассировки графа взаимоблокировок. Для предупреждения WMI агент SQL Server создает запрос уведомления с использованием пространства имен и указанной инструкции WQL. Применительно к этому предупреждению агент SQL Server наблюдает за экземпляром по умолчанию на локальном компьютере. Инструкция WQL запрашивает любое событие DEADLOCK_GRAPH в экземпляре по умолчанию. Чтобы изменить экземпляр, за которым ведется наблюдение с помощью предупреждения, измените имя экземпляра на MSSQLSERVER в @wmi_namespace для события.

Примечание.

Чтобы агент SQL Server получать события WMI, компонент Service Broker должен быть включен msdb и AdventureWorks2022.

USE AdventureWorks2022;
GO

IF OBJECT_ID('DeadlockEvents', 'U') IS NOT NULL
DROP TABLE DeadlockEvents;
GO

CREATE TABLE DeadlockEvents (
    AlertTime DATETIME,
    DeadlockGraph XML
);
GO

Добавьте задание для запуска оповещения.

EXEC msdb.dbo.sp_add_job @job_name = N'Capture Deadlock Graph',
    @enabled = 1,
    @description = N'Job for responding to DEADLOCK_GRAPH events';
GO

Добавьте шаг задания, который вставляет текущее время и граф взаимоблокировки в таблицу DeadlockEvents .

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'AdventureWorks2022';
GO

Установите сервер заданий для задания текущим экземпляром SQL Server.

EXEC msdb.dbo.sp_add_jobserver @job_name = N'Capture Deadlock Graph';
GO

Добавьте оповещение, реагирующее на все DEADLOCK_GRAPH события для экземпляра по умолчанию. Чтобы отслеживать взаимоблокировки для другого экземпляра, измените MSSQLSERVER имя экземпляра.

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 AdventureWorks2022;
GO

BEGIN TRANSACTION;
GO

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

Выполните следующий скрипт на второй вкладке запроса. Этот скрипт создает один результирующий набор, а затем блокируется, ожидая получения блокировки Production.Product.

USE AdventureWorks2022;
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-документ, который показывает все свойства события графа взаимоблокировок.