Предупреждения (Alert или я еще люблю говорить Тревога) позволяют контролировать работу вашего сервера. Вы можете создавать тревоги на определенные события сервера (ошибки данных, ошибки запросов, ошибки или удачные выполнения работ и т.д.) и направлять сообщения определенным операторам. Когда мы создавали работы, то для них автоматически создаются тревоги, если указан оператор, который должен получать информацию об удачном или не удачном выполнении работы.
Благодаря тревогам, администратор может сидеть в нескольких тысячах километров от SQL сервера. Если произойдет внештатная ситуация, то администратор получит e-mail сообщение и сможет подключиться к серверу и исправить ошибку. Без тревоги, администратору пришлось бы постоянно контролировать работу сервера и наблюдать за большим количеством параметров.
Планировщики, как и работы, выполняются сервисом SQL Service Agent, поэтому он должен быть запущен, желательно, чтобы он запускался автоматически после загрузки ОС.
Для создания собственных сообщений (message) используется процедура SQL сервера sp_addmessage. В общем виде эта процедура выглядит следующим образом:
sp_addmessage [ @msgnum = ] msg_id , [ @severity = ] severity , [ @msgtext = ] 'msg' [ , [ @lang = ] 'language' ] [ , [ @with_log = ] 'with_log' ] [ , [ @replace = ] 'replace' ]
Параметров не так уж и много, поэтому давайте рассмотрим их, прежде чем напишем реальный пример:
Давайте создадим свое сообщение:
EXEC sp_addmessage 60001, 16, 'Ошибка добавления записи'
Чуть позже мы увидим, как воспользоваться сообщениями.
Давайте рассмотрим, как можно удалять сообщения. Для этого используется процедура sp_dropmessage:
sp_dropmessage [ @msgnum = ] message_number [ , [ @lang = ] 'language' ]
Процедуре передается два параметра: номер удаляемого сообщения и язык. Если язык не указан, то будут удалены сообщения для всех национальных языков, существующих в сообщении.
Для создания предупреждения (alert) используется процедура sp_add_alert, которая выглядит следующим образом:
sp_add_alert [ @name = ] 'name' [,[@message_id = ] message_id ] [,[@severity = ] severity ] [,[@enabled = ] enabled ] [,[@delay_between_responses = ] delay_between_responses ] [,[@notification_message = ] 'notification_message' ] [,[@include_event_description_in = ] include_event_description_in ] [,[@database_name = ] 'database' ] [,[@event_description_keyword=]'event_description_keyword_pattern'] [,{[@job_id = ] job_id | [ @job_name = ] 'job_name' } ] [,[@raise_snmp_trap = ] raise_snmp_trap ] [,[@performance_condition = ] 'performance_condition' ] [,[@category_name = ] 'category' ]
Рассмотрим доступные параметры этой процедуры:
SELECT * FROM master..sysmessages
В разделе 3.7.1 мы увидели, как создавать собственные сообщения ошибок.
Например, если вы хотите, чтобы текст добавлялся к e-mail сообщению и к сообщению NET SEND, то необходимо указать число 5 (сумма чисел 1 и 4);
Процедура должна выполняться в базе данных msdb, потому что процедура принадлежит этой базе данных.
Давайте добавим собственное предупреждение или как уже много раз называл эту штуку - тревогу:
EXEC sp_add_alert @name = 'Тестовая тревога', @message_id = 60001, @severity = 0, @include_event_description_in = 7, @notification_message = 'Было сгенерировано сообщение 60001'
В данном примере мы создаем тревогу с названием 'Тестовая тревога', которая будет реагировать на сообщение с номером 60001. Сообщение с таким номером было создано нами в разделе 3.7.1.
Теперь посмотрим, как создать тревогу для уже существующих сообщений. В таблице sysmessages базы данных master я нашел сообщение с номером 9002, которое генерируется в случае, если файл журнала полный. Давайте рассмотрим, как с помощью тревоги и работы можно решить классическую задачу с увеличения файла базы данных и очисткой журнала.
Как мы уже знаем, файлы базы данных и файлы журналов могут увеличиваться бесконечно, но это далеко не всегда удобно. Многие администраторы хотят контролировать выделяемое сервером дисковое пространство, поэтому отказываются от автоматического увеличения. Для журнала транзакций можно не увеличивать размер файла, а уменьшать его очисткой. Получается, что наша задача отловить создать тревогу, которая будет реагировать на переполнение журнала и запускать работу очистки журнала. Это можно сделать следующим образом:
EXEC sp_add_alert @name = 'Файл журнала полный', @message_id = 9002, @severity = 0, @include_event_description_in = 4, @database_name = 'FlenovSQLBook', @job_name = 'Работа очистки журнала',
Теперь создадим работу, которая будет очищать журнал. Да, мы еще не рассматривали резервное копирование, которое необходимо для решения данной задачи и данная тема будет рассмотрена в 4-й главе. Если вы не знакомы с этими командами, то не обращайте внимания на операторы Transact-SQL. Вернитесь к ним после прочтения 4-й главы. Сейчас наша задача создать работу, а заодно лишний раз потренироваться и закрепить пройденный материал на практике. Итак, работу и два шага выполняющих резервирование и обрезание журнала вы можете увидеть в листинге 3.9.
Листинг 3.9. Создание работы из 2-х шагов резервирования журнала
-- Создание работы резервирования и очистки журнала EXECUTE sp_add_job @job_name = 'Работа очистки журнала', @enabled = 1, @owner_login_name = 'sa', @description = 'Работа, которая резервирует и очищает журнал', @notify_level_eventlog = 2, @notify_level_email = 3, @notify_level_netsend = 3, @delete_level= 0 -- Добавить шаги EXECUTE sp_add_jobstep @job_name = 'Работа очистки журнала', @step_id = 1, @step_name = 'Резервирование журнала', @subsystem = 'TSQL', @command = 'BACKUP LOG FlenovSQLBook to disk = ''C:\Backup\FlenovSQLBook_log.bak''', @server = '', @database_name = 'FlenovSQLBook' EXECUTE sp_add_jobstep @job_name = 'Работа очистки журнала', @step_id = 2, @step_name = 'Обрезание журнала', @command = 'Обрезание журнала', @database_name = 'master', @subsystem = 'TSQL', @command = 'BACKUP LOG FlenovSQLBook WITH TRUNCATE_ONLY'
Сообщение 9002 является критичным и генерируется, когда журнал уже полный и сервер не смог сохранить в нем информацию о транзакции. Если нет автоматического увеличения, то серверу негде будет хранить информацию о транзакции и такая транзакция откатывается, а значит, данные не будут сохранены. Так будет со всеми последующими транзакциями, пока в журнале не появиться свободное пространство, поэтому данный метод увеличения журнала нельзя назвать эффективным, потому что с момента переполнения журнала до момента освобождения пространства в журнале сервер будет доступен только для чтения. Именно поэтому, освобождением должна заниматься работа, которая должна выполняться мгновенно, без задержек и не ждите, пока в работу сервера не вмешается администратор, который в этот момент может спать.
Файл данных просто так обрезать не получиться. Вы же не можете просто так удалить все данные из таблиц и начать их заполнять с нуля. В этом случае, увеличение должно происходить, но все же может быть работа, которая будет делать увеличения с помощью Transact-SQL запроса и выделять пространства там, где прописано в сценарии администратором.
Для обновления тревоги используется процедура sp_update_alert. У этой процедуры такие же параметры, как и у процедуры создания тревоги sp_add_alert. Общий вид достаточно большой, потому что содержит достаточно много параметров, и ради экономии места мы не будем рассматривать общий вид.
Для удаления тревоги используется процедура sp_delete_alert, которой нужно передать в качестве параметра только имя удаляемой тревоги, например, так:
EXEC sp_delete_alert 'Файл журнала полный'
Для получения информации о тревогах, используется процедура sp_help_alert, которая выглядит следующим образом:
sp_help_alert [ [ @alert_name = ] 'alert_name' ] [ , [ @order_by = ] 'order_by' ] [ , [ @alert_id = ] alert_id ] [ , [ @category_name = ] 'category' ]
У этой процедуры четыре параметра и все они являются не обязательными. Давайте рассмотрим каждый параметр:
Если выполнить процедуру sp_help_alert без параметров, то результатом будут все тревоги SQL сервера:
EXEC sp_help_alert
Результатом будет таблица, состоящая из полей, которые идентичны по имени и назначению параметрам, которые мы рассматривали у процедуры добавления тревоги sp_add_alert.
Отобразим тот же список, но отсортируем результирующий список по параметру message_id:
EXEC sp_help_alert @order_by='message_id'
У нас есть тревога и есть сообщение. Для создания уведомления необходимо связать эти два объекта, чтобы в ответ на тревогу генерировалось сообщение и направлялось оператору. Такую связь можно назвать уведомлением и для его создания используется процедура sp_add_notification, которая выглядит следующим образом:
sp_add_notification [ @alert_name = ] 'alert' , [ @operator_name = ] 'operator' , [ @notification_method = ] notification_method
Здесь у нас три параметра:
Может быть несколько методов получения уведомления. Для этого в параметре @notification_message нужно указать сумму значений методов. Например, если нужно информировать оператора по e-mail и на пейджер, то в параметре @notification_message указываем значение 3 (1+2).
Прежде чем создавать уведомление добавим оператора:
exec sp_add_operator @name = 'Администратор', @netsend_address ='192.168.77.11'
Чтобы наглядно увидеть результат работы, я задал IP адрес своего компьютера, чтобы получать NET SEND сообщение.
Следующий пример показывает, как создать уведомление, которое будет получать администратор для тревоги, созданной в разделе 3.7.2:
EXEC sp_add_notification @alert_name='Тестовая тревога', @operator_name='Администратор', @notification_method=4
Одна тревога может направлять сообщения нескольким операторам. Следующий пример добавляет уведомление еще одного оператора для тревоги с именем 'Тестовая тревога':
EXEC sp_add_notification @alert_name='Тестовая тревога', @operator_name='Михаил', @notification_method=4
Вот теперь вы можете увидеть результат работы на примере. Для этого необходимо сгенерировать сообщение с помощью функции RAISERROR (более подробно о RAISERROR мы поговорим в разделе 4.3.2):
RAISERROR (60001, 16, 1)
В ответ на это, я получил NET SEND сообщение.
Если вы используете NET SEND сообщения, то убедитесь, что в вашей ОС запущен сервис Messenger, без которого отправка сообщения будет невозможной.
Для обновления уведомления используется процедура sp_update_notification, которая выглядит следующим образом:
sp_update_notification [@alert_name =] 'alert', [@operator_name =] 'operator', [@notification_method =] notification
Параметры такие же, как и при создании уведомления sp_add_notification, только параметр @alert_name определяет тревогу, которую надо обновить, а параметр @operator_name определяет оператора. С помощью параметра и @notification_method можно задать новый метод уведомления.
Для удаления уведомления используется процедура sp_delete_notification, которая в общем виде выглядит следующим образом:
sp_delete_notification [ @alert_name = ] 'alert' , [ @operator_name = ] 'operator'
Параметр @alert_name определяет тревогу, которую надо удалить, а параметр @operator_name определяет удаляемого оператора.