25.4.23

Tips for DBA: Deadlock Event Notifications

Начиная с SQL Server 2005, на службе DBA появилась такая замечательная возможность, как Event Notifications, что в русской версии BOL принято называть уведомлением о событиях. Этот механизм позволяет включить незаметную трассировку системных событий и извлекать информацию о заданных события из очереди для анализа или реакции со стороны администратора. Полный список событий, которые таким образом можно отслеживать, можно найти в статье: События трассировки для использования с уведомлениями о событии

Давайте рассмотрим упрощённый пример организации уведомлений о тупиковой блокировке и сделаем так, чтобы по электронной почте можно было получить письмо с графом блокировок.

Подготовительные действия

Для начала настройте на тестовом сервере Database Mail и убедитесь, что всё работает правильно. С возможными проблемами с почтой поможет статья: Устранение неполадок в работе компонента Database Mail

У меня с настройками возникла только одна проблема, пришлось учесть, что вызов системной хранимой процедуры в следующем ниже примере будет выполняться не в том контексте, в котором я привык работать :) В общем, пришлось на время сделать её доступной всем желающим. Вот один из способов это сделать:


USE MSDB 

GO

GRANT EXECUTE ON msdb.dbo.sp_send_dbmail TO public

GO

Для того, чтобы задействовать очереди событий для интересующих нас баз данных, нужно включить компонент Service Broker. Как это сделать для базы AdventureWorks показано в следующем сценарии:

USE master

GO

ALTER DATABASE [AdventureWorks]

SET ENABLE_BROKER WITH NO_WAIT -- с базой должен работать брокер

SELECT name, is_broker_enabled FROM sys.databases -- проверка, что брокер включён

GO

Создание очереди, службы, сообщения и маршрута

В качестве места базирования наших очередей и сообщений мы выберем системную базу данных tempdb. Она есть на любом сервере и Service Broker для неё включён по умолчанию. Первым делом мы заготавливаем процедуру, которая будет вызываться при регистрации интересующего нас события:

USE tempdb

GO

CREATE PROCEDURE [p_Notify]  AS

DECLARE  @subject nvarchar(128), @body nvarchar(MAX) 

DECLARE  @NotificationStore TABLE (message_body varbinary(MAX));

-- извлекаем сообщения из очереди и помещаем их в табличную переменную

RECEIVE TOP (1) message_body FROM tempdb..DEADLOCK_Queue INTO @NotificationStore

-- собираем тему и содержимое электронного письма

SELECT TOP (1) @body = CAST(message_body AS nvarchar(MAX)) FROM @NotificationStore        

SELECT @subject = CAST(CURRENT_TIMESTAMP AS varchar) + ' Случился DEADLOCK'

IF @body IS NOT NULL EXEC msdb.dbo.sp_send_dbmail    

               @profile_name = 'ПОЧТОВЫЙ ПРОФИЛЬ' -- профиль по умолчанию и не скрытый 

              ,@recipients   = 'АДРЕСАТ@ХОСТ.ru' -- адресат 

              ,@subject      = @subject 

              ,@body         = @body

GO

-- создаём очередь 

CREATE  QUEUE DEADLOCK_Queue WITH    

 STATUS = ON 

,RETENTION = OFF 

,ACTIVATION (    PROCEDURE_NAME = tempdb..p_Notify

                                  ,    MAX_QUEUE_READERS = 1

                                  ,    EXECUTE AS 'dbo'        

            )

GO

-- создаём службу

CREATE SERVICE DEADLOCK_Notify ON QUEUE DEADLOCK_Queue   ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])

GO

-- определяем локальную маршрутизацию

CREATE ROUTE DEADLOCK_Route WITH SERVICE_NAME = 'DEADLOCK_Notify'

                               , ADDRESS = 'LOCAL';

GO

-- создаём уведомление уровня сервера для событий появления графа тупиковой блокировки

CREATE EVENT NOTIFICATION DEADLOCK_Event ON SERVER FOR DEADLOCK_GRAPH 

-- если нужны все виды сообщений о блокировках, используйте TRC_LOCKS

TO SERVICE 'DEADLOCK_Notify', 'current database'

-- проверка

SELECT * FROM sys.server_event_notifications

WHERE name = 'DEADLOCK_Event';

SELECT * FROM sys.server_events

GO

После того, как представленный выше сценарий будет успешно применён на тестовом сервере, будет создано всё необходимое для получения почтовых сообщений. В теле письма будет правильный XML, у которого в теге <TextData> лежит стандартный граф взаимоблокировки, который открывается тэгом <deadlock-list>. Если его вырезать и сохранить в файле с расширением xdl, то при открытии такого файла в приложении SQL Server Management Studio, вы увидите привычную схему блокировки, обычно получаемую с помощью SQL Server Profiler.

Удаление созданных для тестовых целей объектов

Удалить следы наших сценариев в базе данных tempdb помогут следующие команды:

-- DROP PROCEDURE p_Notify

-- DROP EVENT NOTIFICATION DEADLOCK_Event ON SERVER 

-- DROP ROUTE DEADLOCK_Route

-- DROP SERVICE DEADLOCK_Notify

-- DROP QUEUE DEADLOCK_Queue

-- ALTER DATABASE [AdventureWorks] SET  DISABLE_BROKER WITH NO_WAIT


Комментариев нет:

Отправить комментарий