Прочитано:
1 257
В сегодняшнем выпуске заметок я покажу какие действия нужно проделать, чтобы при запуске Плана обслуживания в который входит задача создания бекапа, после приходило уведомление на почту о состоянии данной запланированной задачи. Т.е. не просто был настроен ежедневный полный бекап базы данных, но и отчет на почту о статусе, времени начала и завершения и другой полезной технической информации. В таком отчете будет наглядная расшифровка если что-то пойдет не так, так на много лучше чем заступаю на смену заходить на каждый сервер и анализировать логи работы задания. Ранее я описывал, как сделать текущую задачу этой заметки для SQL Server 2008 R2, а в этот раз для новой редакции SQL Server 2014.
Считаю что все что используется на работе или дома в системном администрировании должно быть задокументировано, проанализировано дабы потом не было мучительно вспоминать в впопыхах , а как восстановить работу или настройку.
Итак текущие характеристики сервера под базу данных
- Server 2008 R2 SP1 Enterprise
- RAM = 8Gb
- CPU = 2, Cores = 2
- HDD = 50Gb (System), 100GB — Data (DATA,LOG,BACKUP)
- SQL Server 2014 (12.0.5000.0) установлен с использование двух пакетов:
- SQLServer2014SP1-FullSlipstream-x64-ENU
- SQLServer2014SP2-FullSlipstream-x64-ENU
Шаг №1: Запускаем оснастку SQL Server Management Studio (SQL Server 12.0.5000.0)
Start — All Programs — Microsoft SQL Server 2014 — SQL Server 2014 Management Studio, авторизуюсь, перехожу в меню Management — Database Mail — и через правый клик вызываю настройку: Configure Database Mail
Set up Database Mail by performing the following tasks → и нажимаем Next,
The Database Mail feature is not available: Would you like to enable this feature? — Yes
- Profile name: mssql-plan
SMTP accounts: — Add
- Account name: mssql-plan
Outgoing Mail Server (SMTP):
- E-mail address: mssql-plan@<mail_zimbra_server>
- Display name: mssql-plan
- Server name: 10.9.9.10
- Port number: 25
- SMTP Auhtentication: Basic authentication
- User name: mssql-plan@<mail_zimbra_server>
- Password: Aa1234567
- Confirm password: Aa1234567
И нажимаем OK
В итоге получаются настройки нового профиля mssql-plan:
Нажимаем Next, теперь нужно определить кому будет доступен данный профиль: либо публичный, либо приватный и какой из них назначен будет дефолтным, я выбираю для своих настроек Public Profiles
Нажимаем Next → Next — Finish, конфигурирование профиля под почтовый сервер Zimbra прошло успешно:
Шаг №2: После проверяем отправку тестового письма:
меню Management оснастки SQL Management Studio — Database Mail — и через правый клик вызываем меню: Send Test E-Mail…, заполняем поля кому придет тестовое письмо:
Database Mail Profile: mssql-plan
To: alexander.ollo@<mail_zimbra_server>
Subject: Database Mail Test
Body: This is a test e-mail from Database Mail on SRV-BD4
и нажимаю Send Test E-Mail
Проверяю свой почтовый ящик и вижу, что письмо успешно доставлено:
Шаг №3: После создаю кому нужно будет присылать отчет о результатах отработанной задачи: меню SQL Server Agent оснастки SQL Server Management Studio — Operators — New Operator… —
General:
- Name: backup
- Enabled: отмечено галочкой
- E-Mail name: alexander.ollo@<mail_zimbra_server>
Шаг №4: После переключаюсь на меню Management оснастки SQL Server Management Studio — Maintenance Plans — и через правый клик мышью вызываем меню Maintenance Plan Wizard:
- Name: Backup
- Run as: SQL Server Agent service account
- Single schedule for the entire plan or no schedule: отмечаю этот пункт
Schedule: → Change:
- Name: MaintenancePlanBackup
- Schedule type: Recuring
- Enable: отмечаю галочкой
- Frequency → Occurs: Daily
- Recurs every: 1 days
- Daily frequency: Occurs once at: 3:00:00 PM
После нажимаем OK, Next, выбираю задачу для этого плана → Back Up Database (Full), Next, Next: на вкладке General нужно указать какие базы нужно бекапировать полностью:
General:
- Database(s): BazaBuh
- Back up to: Disk
вкладка Options:
- Set backup compression: Compress backup
После всех настроек нажимаем Next и изменяем поведение опции отчета, мне нужно не в лог файл, а на почту:
Нажимаю Next, Finish, Close.
Шаг №5: После проверяю, как отработает план и что мне придет на почту.
Меню Management оснастки SQL Server Management Studio — Maintenance Plans — Backup — и через правый клик мышью вызываю меню Execute
Исполнение задачи в процессе…
Хотя когда план обслуживания отработал есть возможность в ручную отправить отчет по почте:
Но у меня все в автоматическом режиме, так что проверяю почту:
Итого отчет на почту успешно пришел о полном завершении бекапа с некоторой отладочной информацией для ознакомления.
Работает, как я смотрю на задокументированные шаги выше все просто или просто тому кто был заинтересован сделать это, а не отлынивал с отмазками, а чем можно заняться, мне нечего делать, мне не поручают ничего важного. Просто любое свободное время на работе нужно использовать с пользой повышая свою квалификацию, как делаю я описываю в шагах интересующие меня настройки и задачи. На этом всё, с уважением автор блога Олло Александр aka ekzorchik.
НАСТРОЙКА ОПОВЕЩЕНИЙ О РЕЗУЛЬТАТАХ ВЫПОЛНЕНИЯ ЗАДАНИЙ И ЗАДАЧ MS SQL SERVER
Для оперативного реагирования необходимо своевременно получать информацию об ошибках выполнения заданий. Для этого в SQL Server существует специальный механизм оповещение. В этой статье мы рассмотрим как его настроить.
МЕХАНИЗМ ОПОВЕЩЕНИЙ
Настройку оповещений можно разделить на 4 этапа:
- Включение и настройка профиля компонента Database Mail
- Создание оператора оповещений и настройка почты агента SQL Server
- Включение триггеров и задач оповещений
- Проверка работоспособности
НАСТРОЙКА ПРОФИЛЯ КОМПОНЕНТЫ DATABASE MAIL
Включить компонент работы с почтой DATABASE MAIL нужно с помощью следующего запроса:
sp_configure ‘show advanced options’, 1; GO RECONFIGURE; GO sp_configure ‘Database Mail XPs’, 1; GO RECONFIGURE GO
Для того чтобы настроить учетную запись компонента Database Mail необходимо в дереве «Обозревателя Объектов» (Object Explorer) выбрать настраиваемый экземпляр SQL Server, перейти в «Управление» (Management), далее «Компонент Database Mail» (Database Mail). Щелкнув правой клавишей мыши на данном пункте, будет открыто контекстное меню, в котором необходимо выбрать «Настроить…» (Configure…), после чего будет открыто окно мастера настройки.
Первую страницу можно пропустить, поэтому перейдем сразу ко второй. Здесь нам необходимо выбрать первый пункт «Установить компонент Database Mail…» (Setup Database Mail…) и нажать «Далее» (Next). На третьей странице задаем имя и описание профиля, затем нажимаем кнопку «Добавить» для добавления учетной записи SMTP. В открывшемся окне необходимо заполнить данные учетной записи (e-mail адрес, сервер и порт SMTP, а так же параметры аутентификации).
На следующей странице необходимо назначить безопасность профиля: указать открытый это профиль или частный (и для каких пользователей), а также можно указать является ли профилем по умолчанию. Для наших целей достаточно сделать профиль открытым и профилем по умолчанию. На пятой странице оставляем все по умолчанию, на последней странице жмем «Готово» (Finish)
После того как профиль настроен, его надо проверить, для этого в контекстном меню пункта «Компонент Database Mail»(вызываемым щелчком правой мыши по данному пункту) надо выбрать «Отправить тестовое сообщение» (Send Test E-Mail). В открывшемся окне следует заполнить поле «Кому» (To) и нажать «Отправить …» (Send …)
Если все сделано правильно, тогда в ближайшее время на почту будет доставлено тестовое письмо. Если нет, то выполните настройки системных параметров по картинке:
ДОБАВЛЕНИЕ ОПЕРАТОРА ОПОВЕЩЕНИЙ
Операторы — это псевдонимы людей или групп, которые могут получать электронные уведомления о завершении задач, заданий или предупреждения. Для добавления нового оператора оповещений необходимо в дереве «Обозревателя Объектов» (Object Explorer) выбрать настраиваемый экземпляр SQL Server, перейти в «Агент SQL Server» (SQL Server Agent), далее «Операторы» (Operators). Щелкнув правой клавишей мыши на данном пункте, выбрать «Создать оператора» (New Operator), после чего будет открыто окно свойств оператора оповещений.
Настройки оператора находятся на закладке «Общие» (General). Здесь необходимо заполнить «Имя» (Name), указать состояние «Включено» (Enabled), ввести адрес электронной почты. В целом, существуют альтернативные способы оповещения помимо электронной почты: с помощью команды net send или сообщением на пейджер.
На этом настройка оператора завершена, перейдем к следующему шагу.
НАСТРОЙКА ПОЧТЫ АГЕНТА SQL SERVER
Данный пункт необходим для рассылки уведомлений по электронной почты агентом SQL Server. Такая рассылка происходит, например, для уведомления о статусе выполнения задания. Для настройки почты агента необходимо в дереве «Обозревателя Объектов» (Object Explorer) выбрать настраиваемый экземпляр SQL Server, перейти в «Агент SQL Server» (SQL Server Agent), из контекстного меню выбрать «Свойства» (Properties).
В открывшемся окне перейдем на вкладку «Система предупреждений» (Alert System), установим флажок «Включить почтовый профиль» (Enable mail profile), в качестве почтовой системы оставим «Компонент Database Mail» (Database Mail) и выберем ранее созданный профиль в соответствующем поле.
ВКЛЮЧЕНИЕ ТРИГГЕРОВ И ЗАДАЧ ОПОВЕЩЕНИЯ
Для удобства проверки настроим оповещения на успешное выполнение заданий, в реальной жизни больше имеет смысл подключать оповещения на случай ошибки. В целях демонстрации настроим оповещения на наше «Задание» (Job), а так же добавим оповещение в наш план обслуживания. Итак, откроем наш план обслуживания, в нем выделим субплан «UpdateStatistics». На рабочую область субплана перетащим задачу «Уведомление оператора» (Notify Operator Task). Протянем стрелку от задачи «Обновление статистики». Двойным кликом по задаче «Уведомление оператора» откроем ее свойства, отметим созданного оператора, а так же введем «Тему»(Subject) и «Текст» (Message) письма. Для того чтобы изменить условие оповещения (по умолчанию стрелка вида «Успешное завершение») надо щелкнуть правой клавишей мыши на стрелке и выбрать ее вид: успешное выполнение/ошибка/выполнение.
Теперь перейдем к настройке оповещений в «Заданиях» (Jobs). Откроем свойства нашего задания и перейдем на вкладку «Уведомления» (Notifications). Установим галки рядом с видами уведомлений, которые мы хотим использовать (у меня это только электронная почта), далее выберем оператора и условие оповещения (успешное завершение/завершение с ошибкой/любое завершение).
ПРОВЕРКА РАБОТОСПОСОБНОСТИ ОПОВЕЩЕНИЙ
Выполним ручной запуск нашего задания, для этого щелкнем правой клавишей мыши на нем и выберем «Запустить задание на шаге» (Start Job at Step). В результате должно прийти на почту 2 письма: одно (с установленными нами темой и текстом) соответствует задаче «Уведомления оператора» в плане обслуживания; второе — информирует о выполнении задания в целом.
Если не пришло ни одного письма тогда, возможно:
- Ошибка в параметрах учетной записи SMTP. Попробуйте отправить тестовое сообщение, если оно не отправляется — перепроверьте параметры
- Ошибка в правах безопасности профиля. Перепроверьте установлены ли права как описано ранее. Если все установлено верно, а результата нет — попробуйте указать все права: открытый и все частные, а так же сделать профилем по умолчанию для каждого права
Если не пришло только письмо с результатом выполнения задания: проверьте что почта SQL Server’а настроена в соответствии с вышеизложенным.
Доброго времени, читатели блога Любителя экспериментов! В продолжении статьи о Maintenance Plans для MS SQL 2005 дополняю статьей о том, как настроить уведомление об ошибках Maintenance Plan MS SQL 2005 по электронной почте. Это позволит сэкономить время и силы ) на ежедневный ручной контроль выполнения регламентных заданий.
Введение в Database Mail в MS SQL Server 2005
Database Mail появился в SQL Server 2005, заменив собой компонент SQLMail. Данный компонент используется для отправки сообщений электронной почты компонентом сервера — Database Engine. Database Mail не требует установленного почтового клиента и сам общается с почтовым сервером по протоколу SMTP. Для того, чтобы все корректно заработало, необходимо несколько вещей: 1. Собственно, сам Microsoft SQL Server; 2. почтовый сервер, доступный с машины с SQL Server’ом; 3. членство в роли sysadmin у вашей учетной записи в SQL Server, поскольку настройку могут производить только члены этой роли.
Настройка Database Mail в MS SQL Server 2005
Шаг 1. Настройка Database Mail
В первую очередь, подключимся к нашему SQL Server’у с помощью SQL Server Management Studio. Раскрываем ветку Management, выбираем пункт Database Mail, жмахаем по нему правой кнопкой мыши и выбираем «Configure Database Mail»:
В появившемся мастере нажимаем Далее (Next). Теперь мы можем: настроить Database Mail, изменить профили и аккаунты Database Mail, изменить безопасность профилей и, наконец, изменить конфигурацию системы. Поскольку Database Mail мы ранее не использовали — изменять нам пока нечего, выбираем первый пункт «Set up Database Mail» и нажимаем «Next». Если ранее Database Mail не был настроен, то появиться сообщение о необходимости включить данную функцию — соглашаемся.
Создадим новый профиль, например с именем «Алярмер» — именно он будет использоваться для отправки почты о невыполненных заданиях (job’ах) и добавим в него одну учетную запись (Account) — для чего нажмем кнопку «Add»:
Поля в окне мастера Database Mail Configuration Wizard необходимо настроить под свои параметры и нажать несколько раз Next:
На данном этапе можно добавить дополнительные учетные записи на тот случай, если одна из записей «откажет». После нажатия Next мы попадаем в следующее окно:
В данном окне мастера на вкладке Private Profiles мы можем создать несколько профилей, то есть каждому пользователю msdb, включенному в роль DatabaseMailUserRole, можно назначить свой почтовый профиль. Или даже несколько почтовых профилей. Для этого необходимо установить галку «Access». Default Profile — если стоит «Yes», при использовании хранимой процедуры sp_send_dbmail, имя профиля по-умолчанию можно не указывать, туда будет подставлено имя профиля, отмеченного Default для этого пользователя. На закладке Public Profiles можно установить для свежесозданного профиля признаки Default = «Yes» и Public = «Yes». Теперь этот профиль смогут использовать все пользователи msdb включенные в роль DatabaseMailUserRole (и пользователи серверной роли sysadmin). После нажатия «Next» мы попадаем на предпоследний экран мастера настройки.
Здесь мы можем настроить:
- Account Retry Attempts — количество попыток отправки письма с использованием конкретной учетной записи (помните, что мы можем добавить в профиль несколько учетных записей? Вот, сначала SQL Server попробует отправить письмо от имени учетной записи с приоритетом 1 столько раз, сколько мы укажем, а потом, если письмо так и не уйдет — будет перебирать менее приоритетные учетные записи)
- Account Retry Delay (seconds) — именно столько секунд SQL Server будет ждать прежде чем повторить попытку отправить письмо
- Maximum File Size (Bytes) — SQL Server может добавлять файлы-вложения в письмо. Этим параметром можно ограничить размер такого вложения
- Prohibited Attachment File Extensions — запрещенные разрешения для вложений, чтобы пользователь не мог сгененерировать и отправить файл .vbs, например
- Database Mail Executable Minimum Lifetime (seconds) — Database Mail представляет из себя отдельный файл DatabaseMail(90-110).exe — этот параметр определяет через какой промежуток времени SQL Server «прибьет» запущенный процесс при отсутствии активности
- Logging Level — этот параметр определяет как много информации будет писаться в лог, при работе Database Mail.
На последнем экране мы увидим какие учетные записи и профили будут созданы, а так же каким пользователям будет добавлена возможность использовать созданный профиль. Жмахаем «Finish». Настройку профиля и учетной записи почты можно считать завершенной.
Шаг 2. Отправка тестового письма
Для проверки корректности настроек можно отправить тестовое письмо. Для этого:
После ввода адреса получаетля и нажатия «Send Test E-Mail» — тестовое сообщение будет отправлено и при удачном стечении обстоятельств — будет получено получателем. Если сообщение до получателя не дошло, то бегом смотреть логи и искать ошибки. Во-первых, посмотрите журнал Database Mail. В SSMS зайдите в Management, ткните в Database Mail правой кнопкой мыши и выберите там Database Mail Log. Возможно вы просто неправильно указали параметры подключения к серверу — это, как ни странно, довольно-таки распространенная ошибка. Второе, что нужно проверить — это то, что в базе данных msdb включен Service Broker. Именно он используется для отправки сообщений. Для проверки, создайте новый запрос и выполните там:
SELECT is_broker_enabled FROM sys.databases WHERE name = 'msdb'
Если возвращаемое значение отличается от единицы, Service Broker выключен. Вы можете включить его так:
ALTER DATABASE msdb SET ENABLE_BROKER
Будем считать, что теперь Database Mail у нас настроена и тестовое письмо пришло.
Шаг 3. Создание оператора (получателя писем)
Для создания учетной записи лица, которое будет получать письма, необходимо:
Заполнить указанные поля. Задать произвольное имя, поставить чекбокс «Enable» и задать адрес получателя. Нажать ОК.
Шаг 4. Настройка агента (SQL Server Agent)
Для настройки Ms SQL Server Agent необходимо:
Как видно, необходимо задать систему, используемую для отправки сообщений и созданный нами профиль. Далее нажать ОК и перезапустить SQL Server Agent.
Шаг 5. Настройка Maintenance Plan и Jobs
Для всех заданий, по которым необходимо уведомление, необходимо:
Зайти в свойства задания на вкладку Notifications и поставить чекбокс E-mail. Выбрать недавносозданного оператора и при каком условии посылать уведомление. «When the job fails«, т.е. уведомления посылать только если задание завершится с ошибкой, «When the job succeeds» — когда задание завершится успешно, «When the job completes» — когда задание завершится вообще хоть как-то — с ошибкой, либо без ошибок.
В случае ошибок выполнения заданий будет послано сообщение, примерно следующего содержания:
From: sql@server.ru Sent: Friday, December 16, 2011 9:30 PM To: mc-sim@server.ru Subject: SQL Server Job System: 'название_невыполненной_задачи' completed on \SQL
JOB RUN: 'название_невыполненной_задачи' was run on 16.12.2011 at 21:30:00 DURATION: 0 hours, 0 minutes, 1 seconds STATUS: Failed MESSAGES: The job failed. The Job was invoked by Schedule 17 (название_невыполненной_задачи). The last step to run was step 1 (название_невыполненной_задачи).
В этом сообщении можно разобрать следующее:
- Когда и какое задание выполнялось (JOB RUN: ‘название_невыполненной_задачи’was run on 16.12.2011 at 21:30:00)
- Сколько времени выполнялось задание до того как обнаружилась ошибка (DURATION: 0 hours, 0 minutes, 1 seconds)
- Итог выполнения (STATUS: Failed)
- Сообщение из журнала событий этого задания (MESSAGES: The job failed. The Job was invoked by Schedule 17 (название_невыполненной_задачи). The last step to run was step 1 (название_невыполненной_задачи)), включающее в себя краткое описание ошибки
Резюме
Большая часть материала была скопирована со статьи (http://habrahabr.ru/blogs/mssql/132902/), за что автору спасибо. Хотя планировал все сделать сам Более подробную информацию можно получить в документации по Database Mail от разработчиков в ссылках ниже. Данная функция очень помогает в своевременном разрешении проблем с обслуживанием, НО не избавляет от необходимости периодически читать логи сервера! Удачных вам бэкапов!
Что еще почитать
Включение Database Mail в MS SQL Express — http://weblogs.sqlteam.com/mladenp/archive/2007/07/01/60245.aspx
Документация по Database Mail от разработчика — http://msdn.microsoft.com/ru-ru/library/ms175887.aspx
С Уважением, Mc.Sim!
Теги: HOWTO, Microsoft Windows, sql
Время прочтения
14 мин
Просмотры 8.6K
Предисловие
Часто возникает потребность каким-либо способом сообщать администраторам о проблемах, возникших на сервере. Причем уведомления в большинстве своем делятся на 2 типа:
1) реального времени, т. е. те, которые должны приходить сразу при возникновении проблемы
2) отложенного времени, т. е. те, которые приходят через достаточно продолжительное время (более 1 часа) после возникновения проблемы.
В моей работе было необходимо расширить функционал обычного Database Mail.
В данной статье будет рассмотрен пример того, как формировать уведомления в HTML-таблицы с последующей отправкой по почте администраторам.
Решение
1. Настроим Database Mail
2. Создадим таблицу для получателей:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [srv].[Recipient](
[Recipient_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[Recipient_Name] [nvarchar](255) NOT NULL, --основной почтовый адрес получателя
[Recipient_Code] [nvarchar](10) NOT NULL, --код получателя
[IsDeleted] [bit] NOT NULL, --признак удаления (используется получатель или нет)
[InsertUTCDate] [datetime] NOT NULL,
CONSTRAINT [PK_Recipient] PRIMARY KEY CLUSTERED
(
[Recipient_GUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [AK_Recipient_Code] UNIQUE NONCLUSTERED
(
[Recipient_Code] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [AK_Recipient_Name] UNIQUE NONCLUSTERED
(
[Recipient_Name] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [srv].[Recipient] ADD CONSTRAINT [DF_Recipient_Recipient_GUID] DEFAULT (newsequentialid()) FOR [Recipient_GUID]
GO
ALTER TABLE [srv].[Recipient] ADD CONSTRAINT [DF_Recipient_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]
GO
ALTER TABLE [srv].[Recipient] ADD CONSTRAINT [DF_Recipient_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]
GO
3. Создадим таблицу для адресов получателей:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [srv].[Address](
[Address_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[Recipient_GUID] [uniqueidentifier] NOT NULL, --получатель
[Address] [nvarchar](255) NOT NULL, --почтовый адрес
[IsDeleted] [bit] NOT NULL, --признак удаления (используется адрес или нет)
[InsertUTCDate] [datetime] NOT NULL,
CONSTRAINT [PK_Address] PRIMARY KEY CLUSTERED
(
[Address_GUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [AK_Address] UNIQUE NONCLUSTERED
(
[Recipient_GUID] ASC,
[Address] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [srv].[Address] ADD CONSTRAINT [DF_Address_Address_GUID] DEFAULT (newsequentialid()) FOR [Address_GUID]
GO
ALTER TABLE [srv].[Address] ADD CONSTRAINT [DF_Address_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]
GO
ALTER TABLE [srv].[Address] ADD CONSTRAINT [DF_Address_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]
GO
4. Создадим таблицу для очереди сообщений:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [srv].[ErrorInfo](
[ErrorInfo_GUID] [uniqueidentifier] NOT NULL,
[ERROR_TITLE] [nvarchar](max) NULL, --заголовок
[ERROR_PRED_MESSAGE] [nvarchar](max) NULL, --предварительная информация
[ERROR_NUMBER] [nvarchar](max) NULL, --код сообщения (ошибки)
[ERROR_MESSAGE] [nvarchar](max) NULL, --сообщение
[ERROR_LINE] [nvarchar](max) NULL, --номер строки
[ERROR_PROCEDURE] [nvarchar](max) NULL, --хранимая процедура
[ERROR_POST_MESSAGE] [nvarchar](max) NULL, --пояснительная информация
[RECIPIENTS] [nvarchar](max) NULL, --получатели через ';'
[InsertDate] [datetime] NOT NULL,
[StartDate] [datetime] NOT NULL, --дата и время начала
[FinishDate] [datetime] NOT NULL, --дата и время окончания
[Count] [int] NOT NULL, --кол-во раз
[UpdateDate] [datetime] NOT NULL,
[IsRealTime] [bit] NOT NULL, --признак реального времени
[InsertUTCDate] [datetime] NULL,
CONSTRAINT [PK_ErrorInfo] PRIMARY KEY CLUSTERED
(
[ErrorInfo_GUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_ErrorInfo_GUID] DEFAULT (newid()) FOR [ErrorInfo_GUID]
GO
ALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_InsertDate] DEFAULT (getdate()) FOR [InsertDate]
GO
ALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_StartDate] DEFAULT (getdate()) FOR [StartDate]
GO
ALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_FinishDate] DEFAULT (getdate()) FOR [FinishDate]
GO
ALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_Count] DEFAULT ((1)) FOR [Count]
GO
ALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF__ErrorInfo__Updat__5FFEE747] DEFAULT (getdate()) FOR [UpdateDate]
GO
ALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_IsRealTime] DEFAULT ((0)) FOR [IsRealTime]
GO
ALTER TABLE [srv].[ErrorInfo] ADD CONSTRAINT [DF_ErrorInfo_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]
GO
5. Создадим архивную таблицу для отправленных сообщений из очереди сообщений:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [srv].[ErrorInfoArchive](
[ErrorInfo_GUID] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[ERROR_TITLE] [nvarchar](max) NULL,
[ERROR_PRED_MESSAGE] [nvarchar](max) NULL,
[ERROR_NUMBER] [nvarchar](max) NULL,
[ERROR_MESSAGE] [nvarchar](max) NULL,
[ERROR_LINE] [nvarchar](max) NULL,
[ERROR_PROCEDURE] [nvarchar](max) NULL,
[ERROR_POST_MESSAGE] [nvarchar](max) NULL,
[RECIPIENTS] [nvarchar](max) NULL,
[InsertDate] [datetime] NOT NULL,
[StartDate] [datetime] NOT NULL,
[FinishDate] [datetime] NOT NULL,
[Count] [int] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[IsRealTime] [bit] NOT NULL,
[InsertUTCDate] [datetime] NULL,
CONSTRAINT [PK_ArchiveErrorInfo] PRIMARY KEY CLUSTERED
(
[ErrorInfo_GUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_ErrorInfo_GUID] DEFAULT (newsequentialid()) FOR [ErrorInfo_GUID]
GO
ALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ArchiveErrorInfo_InsertDate] DEFAULT (getdate()) FOR [InsertDate]
GO
ALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_StartDate] DEFAULT (getdate()) FOR [StartDate]
GO
ALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_FinishDate] DEFAULT (getdate()) FOR [FinishDate]
GO
ALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_Count] DEFAULT ((1)) FOR [Count]
GO
ALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_UpdateDate] DEFAULT (getdate()) FOR [UpdateDate]
GO
ALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_IsRealTime] DEFAULT ((0)) FOR [IsRealTime]
GO
ALTER TABLE [srv].[ErrorInfoArchive] ADD CONSTRAINT [DF_ErrorInfoArchive_InsertUTCDate] DEFAULT (getutcdate()) FOR [InsertUTCDate]
GO
Эта информация нужна для истории. Но также данную таблицу нужно чистить от очень старых данных (например, старее месяца).
6. Создадим хранимую процедуру, которая регистрирует новое сообщение в очередь сообщений:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [srv].[ErrorInfoIncUpd]
@ERROR_TITLE nvarchar(max),
@ERROR_PRED_MESSAGE nvarchar(max),
@ERROR_NUMBER nvarchar(max),
@ERROR_MESSAGE nvarchar(max),
@ERROR_LINE nvarchar(max),
@ERROR_PROCEDURE nvarchar(max),
@ERROR_POST_MESSAGE nvarchar(max),
@RECIPIENTS nvarchar(max),
@StartDate datetime=null,
@FinishDate datetime=null,
@IsRealTime bit = 0
AS
BEGIN
/*
регистрация ошибки в таблицу ошибок на отправление по почте
если уже в таблице есть запись с одинаковым заголовком, содержанием и отправителем
, то изменится конечная дата ошибки, дата обновления записи, а также количество ошибок
*/
SET NOCOUNT ON;
declare @ErrorInfo_GUID uniqueidentifier;
select top 1
@ErrorInfo_GUID=ErrorInfo_GUID
from srv.ErrorInfo
where (ERROR_TITLE=@ERROR_TITLE or @ERROR_TITLE is null)
and RECIPIENTS=@RECIPIENTS
and (ERROR_MESSAGE=@ERROR_MESSAGE or @ERROR_MESSAGE is null)
and (ERROR_PRED_MESSAGE=@ERROR_PRED_MESSAGE or @ERROR_PRED_MESSAGE is null)
and (ERROR_POST_MESSAGE=@ERROR_POST_MESSAGE or @ERROR_POST_MESSAGE is null)
and (IsRealTime=@IsRealTime or @IsRealTime is null);
if(@ErrorInfo_GUID is null)
begin
insert into srv.ErrorInfo
(
ERROR_TITLE
,ERROR_PRED_MESSAGE
,ERROR_NUMBER
,ERROR_MESSAGE
,ERROR_LINE
,ERROR_PROCEDURE
,ERROR_POST_MESSAGE
,RECIPIENTS
,IsRealTime
,StartDate
,FinishDate
)
select
@ERROR_TITLE
,@ERROR_PRED_MESSAGE
,@ERROR_NUMBER
,@ERROR_MESSAGE
,@ERROR_LINE
,@ERROR_PROCEDURE
,@ERROR_POST_MESSAGE
,@RECIPIENTS
,@IsRealTime
,isnull(@StartDate, getdate())
,isnull(@FinishDate,getdate())
end
else
begin
update srv.ErrorInfo
set FinishDate=getdate(),
[Count]=[Count]+1,
UpdateDate=getdate()
where ErrorInfo_GUID=@ErrorInfo_GUID;
end
END
GO
7. Создадим хранимую процедуру, которая возвращает строку из адресов по коду или основному почтовому адресу получателя:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [srv].[GetRecipients]
@Recipient_Name nvarchar(255)=NULL,
@Recipient_Code nvarchar(10)=NULL,
@Recipients nvarchar(max) out
/*
Процедура составления почтовых адресов уведомлений
*/
AS
BEGIN
SET NOCOUNT ON;
set @Recipients='';
select @Recipients=@Recipients+d.[Address]+';'
from srv.Recipient as r
inner join srv.[Address] as d on r.Recipient_GUID=d.Recipient_GUID
where (r.Recipient_Name=@Recipient_Name or @Recipient_Name IS NULL)
and (r.Recipient_Code=@Recipient_Code or @Recipient_Code IS NULL)
and r.IsDeleted=0
and d.IsDeleted=0;
--order by r.InsertUTCDate desc, d.InsertUTCDate desc;
if(len(@Recipients)>0) set @Recipients=substring(@Recipients,1,len(@Recipients)-1);
END
GO
8. Создадим необходимые функции для работы с датой и временем:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [rep].[GetDateFormat]
(
@dt datetime, -- входная дата
@format int=0 -- заданный формат
)
RETURNS nvarchar(255)
AS
/*
Возвращает дату в виде строки по заданному формату и входной дате
Проставляет необходимые нули:
формат входная дата результат
0 17.4.2014 "17.04.2014"
1 17.4.2014 "04.2014"
1 8.11.2014 "11.2014"
2 17.04.2014 "2014"
*/
BEGIN
DECLARE @res nvarchar(255);
DECLARE @day int=DAY(@dt);
DECLARE @month int=MONTH(@dt);
DECLARE @year int=YEAR(@dt);
if(@format=0)
begin
set @res=IIF(@day<10,'0'+cast(@day as nvarchar(1)), cast(@day as nvarchar(2)))+'.';
set @res=@res+IIF(@month<10,'0'+cast(@month as nvarchar(1)), cast(@month as nvarchar(2)))+'.';
set @res=@res+cast(@year as nvarchar(255));
end
else if(@format=1)
begin
set @res=IIF(@month<10,'0'+cast(@month as nvarchar(1)), cast(@month as nvarchar(2)))+'.';
set @res=@res+cast(@year as nvarchar(255));
end
else if(@format=2)
begin
set @res=cast(@year as nvarchar(255));
end
RETURN @res;
END
GO
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [rep].[GetTimeFormat]
(
@dt datetime, -- входное время
@format int=0 -- заданный формат
)
RETURNS nvarchar(255)
AS
/*
Возвращает время в виде строки по заданному формату и входному времени
Проставляет необходимые нули:
формат входное время результат
0 17:04 "17:04:00"
1 17:04 "17:04"
1 8:04 "08:04"
2 17:04 "17"
*/
BEGIN
DECLARE @res nvarchar(255);
DECLARE @hour int=DATEPART(HOUR, @dt);
DECLARE @min int=DATEPART(MINUTE, @dt);
DECLARE @sec int=DATEPART(SECOND, @dt);
if(@format=0)
begin
set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2)))+':';
set @res=@res+IIF(@min<10,'0'+cast(@min as nvarchar(1)), cast(@min as nvarchar(2)))+':';
set @res=@res+IIF(@sec<10,'0'+cast(@sec as nvarchar(1)), cast(@sec as nvarchar(2)));
end
else if(@format=1)
begin
set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2)))+':';
set @res=@res+IIF(@min<10,'0'+cast(@min as nvarchar(1)), cast(@min as nvarchar(2)));
end
else if(@format=2)
begin
set @res=IIF(@hour<10,'0'+cast(@hour as nvarchar(1)), cast(@hour as nvarchar(2)));
end
RETURN @res;
END
GO
9. Создадим хранимую процедуру, которая создает HTML-отчет в виде таблицы по сообщениям:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [srv].[GetHTMLTable]
@recipients nvarchar(max)
,@dt datetime -- по какое число читать
AS
BEGIN
/*
формирует HTML-код для таблицы
*/
SET NOCOUNT ON;
declare @body nvarchar(max);
declare @tbl table(ID int identity(1,1)
,[ERROR_TITLE] nvarchar(max)
,[ERROR_PRED_MESSAGE] nvarchar(max)
,[ERROR_NUMBER] nvarchar(max)
,[ERROR_MESSAGE] nvarchar(max)
,[ERROR_LINE] nvarchar(max)
,[ERROR_PROCEDURE] nvarchar(max)
,[ERROR_POST_MESSAGE] nvarchar(max)
,[InsertDate] datetime
,[StartDate] datetime
,[FinishDate] datetime
,[Count] int
);
declare
@ID int
,@ERROR_TITLE nvarchar(max)
,@ERROR_PRED_MESSAGE nvarchar(max)
,@ERROR_NUMBER nvarchar(max)
,@ERROR_MESSAGE nvarchar(max)
,@ERROR_LINE nvarchar(max)
,@ERROR_PROCEDURE nvarchar(max)
,@ERROR_POST_MESSAGE nvarchar(max)
,@InsertDate datetime
,@StartDate datetime
,@FinishDate datetime
,@Count int
insert into @tbl(
[ERROR_TITLE]
,[ERROR_PRED_MESSAGE]
,[ERROR_NUMBER]
,[ERROR_MESSAGE]
,[ERROR_LINE]
,[ERROR_PROCEDURE]
,[ERROR_POST_MESSAGE]
,[InsertDate]
,[StartDate]
,[FinishDate]
,[Count]
)
select top 100
[ERROR_TITLE]
,[ERROR_PRED_MESSAGE]
,[ERROR_NUMBER]
,[ERROR_MESSAGE]
,[ERROR_LINE]
,[ERROR_PROCEDURE]
,[ERROR_POST_MESSAGE]
,[InsertDate]
,[StartDate]
,[FinishDate]
,[Count]
from [srv].[ErrorInfo]
where ([RECIPIENTS]=@recipients) or (@recipients IS NULL)
and InsertDate<=@dt
--order by InsertDate asc;
set @body='<TABLE BORDER=5>';
set @body=@body+'<TR>';
set @body=@body+'<TD>';
set @body=@body+'№ п/п';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'ДАТА';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'ОШИБКА';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'ОПИСАНИЕ';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'КОД ОШИБКИ';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'СООБЩЕНИЕ';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'НАЧАЛО';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'ОКОНЧАНИЕ';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'КОЛИЧЕСТВО';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'НОМЕР СТРОКИ';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'ПРОЦЕДУРА';
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+'ПРИМЕЧАНИЕ';
set @body=@body+'</TD>';
set @body=@body+'</TR>';
while((select top 1 1 from @tbl)>0)
begin
set @body=@body+'<TR>';
select top 1
@ID =[ID]
,@ERROR_TITLE =[ERROR_TITLE]
,@ERROR_PRED_MESSAGE=[ERROR_PRED_MESSAGE]
,@ERROR_NUMBER =[ERROR_NUMBER]
,@ERROR_MESSAGE =[ERROR_MESSAGE]
,@ERROR_LINE =[ERROR_LINE]
,@ERROR_PROCEDURE =[ERROR_PROCEDURE]
,@ERROR_POST_MESSAGE=[ERROR_POST_MESSAGE]
,@InsertDate =[InsertDate]
,@StartDate =[StartDate]
,@FinishDate =[FinishDate]
,@Count =[Count]
from @tbl
order by InsertDate asc;
set @body=@body+'<TD>';
set @body=@body+cast(@ID as nvarchar(max));
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+rep.GetDateFormat(@InsertDate, default)+' '+rep.GetTimeFormat(@InsertDate, default);--cast(@InsertDate as nvarchar(max));
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+isnull(@ERROR_TITLE,'');
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+isnull(@ERROR_PRED_MESSAGE,'');
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+isnull(@ERROR_NUMBER,'');
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+isnull(@ERROR_MESSAGE,'');
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+rep.GetDateFormat(@StartDate, default)+' '+rep.GetTimeFormat(@StartDate, default);--cast(@StartDate as nvarchar(max));
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+rep.GetDateFormat(@FinishDate, default)+' '+rep.GetTimeFormat(@FinishDate, default);--cast(@FinishDate as nvarchar(max));
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+cast(@Count as nvarchar(max));
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+isnull(@ERROR_LINE,'');
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+isnull(@ERROR_PROCEDURE,'');
set @body=@body+'</TD>';
set @body=@body+'<TD>';
set @body=@body+isnull(@ERROR_POST_MESSAGE,'');
set @body=@body+'</TD>';
delete from @tbl
where ID=@ID;
set @body=@body+'</TR>';
end
set @body=@body+'</TABLE>';
select @body;
END
GO
10. Создадим хранимую процедуру, которая отправляет сообщения:
Код
USE [ИМЯ_БАЗЫ_ДАННЫХ]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [srv].[RunErrorInfoProc]
@IsRealTime bit =0 -- режим отправки (1-реального времени)
AS
BEGIN
/*
выполнить отправку уведомлений об ошибках с указанным режимом
*/
SET NOCOUNT ON;
declare @dt datetime=getdate();
declare @tbl table(Recipients nvarchar(max));
declare @recipients nvarchar(max);
declare @recipient nvarchar(255);
declare @result nvarchar(max)='';
declare @recp nvarchar(max);
declare @ind int;
declare @recipients_key nvarchar(max);
--получаем все необходимые сообщения
insert into @tbl(Recipients)
select [RECIPIENTS]
from srv.ErrorInfo
where InsertDate<=@dt and IsRealTime=@IsRealTime
group by [RECIPIENTS];
declare @rec_body table(Body nvarchar(max));
declare @body nvarchar(max);
declare @query nvarchar(max);
--пробегаем по каждому сообщению
while((select top 1 1 from @tbl)>0)
begin
--получаем получателей
select top (1)
@recipients=Recipients
from @tbl;
set @recipients_key=@recipients;
set @result='';
--для каждого получателя
while(len(@recipients)>0)
begin
set @ind=CHARINDEX(';', @recipients);
if(@ind>0)
begin
set @recipient=substring(@recipients,1, @ind-1);
set @recipients=substring(@recipients,@ind+1,len(@recipients)-@ind);
end
else
begin
set @recipient=@recipients;
set @recipients='';
end;
--получаем адреса получателя
exec [srv].[GetRecipients]
@Recipient_Code=@recipient,
@Recipients=@recp out;
if(len(@recp)=0)
begin
exec [srv].[GetRecipients]
@Recipient_Name=@recipient,
@Recipients=@recp out;
if(len(@recp)=0) set @recp=@recipient;
end
--разделенные символом ';'
set @result=@result+@recp+';';
end
set @result=substring(@result,1,len(@result)-1);
set @recipients=@result;
--получить HTML-отчет с указанными получателями и датой
insert into @rec_body(Body)
exec srv.GetHTMLTable @recipients=@recipients_key, @dt=@dt;
--получить HTML-отчет
select top (1)
@body=Body
from @rec_body;
--непосредственно сама отправка
EXEC msdb.dbo.sp_send_dbmail
-- Созданный нами профиль администратора почтовых рассылок
@profile_name = 'ALARM',
-- Адрес получателя
@recipients = @recipients,
-- Текст письма
@body = @body,
-- Тема
@subject = N'ИНФОРМАЦИЯ ПО ОШИБКАМ ВЫПОЛНЕНИЯ',
@body_format='HTML'--,
-- Для примера добавим к письму результаты произвольного SQL-запроса
--@query = @query--'SELECT TOP 10 name FROM sys.objects';
delete from @tbl
where Recipients=@recipients_key;
delete from @rec_body;
end
--помещаем в архив отправленные сообщения
INSERT INTO [srv].[ErrorInfoArchive]
([ErrorInfo_GUID]
,[ERROR_TITLE]
,[ERROR_PRED_MESSAGE]
,[ERROR_NUMBER]
,[ERROR_MESSAGE]
,[ERROR_LINE]
,[ERROR_PROCEDURE]
,[ERROR_POST_MESSAGE]
,[RECIPIENTS]
,[StartDate]
,[FinishDate]
,[Count]
,IsRealTime
)
SELECT
[ErrorInfo_GUID]
,[ERROR_TITLE]
,[ERROR_PRED_MESSAGE]
,[ERROR_NUMBER]
,[ERROR_MESSAGE]
,[ERROR_LINE]
,[ERROR_PROCEDURE]
,[ERROR_POST_MESSAGE]
,[RECIPIENTS]
,[StartDate]
,[FinishDate]
,[Count]
,IsRealTime
FROM [srv].[ErrorInfo]
where IsRealTime=@IsRealTime
and InsertDate<=@dt
--order by InsertDate;
--удаляем отправленные сообщения из очереди сообщений
delete from [srv].[ErrorInfo]
where IsRealTime=@IsRealTime
and InsertDate<=@dt;
END
GO
Данная хранимая процедура берет каждое сообщение из очереди сообщений и обертывает его в HTML-отчет в виде таблицы. Для получателей по их коду или основному почтовому адресу создает строку, состоящую из почтовых адресов. Именно на эти адреса и отправляется сообщение. И так обрабатываются все выбранные сообщения. Здесь используется хранимая процедура msdb.dbo.sp_send_dbmail
11. Создадим два задания в Агенте (первое-для уведомлений реального времени (расписание-1 раз в минуту), второе-для простых уведомлений (расписание-1 раз в час)). В код задания нужно добавить следующее:
EXECUTE [ИМЯ_БАЗЫ_ДАННЫХ].[srv].[RunErrorInfoProc]
@IsRealTime=0; --0 для простых уведомлений и 1 для уведомлений реального времени
Приведем пример регистрации ошибки:
Код
begin try
exec [ИМЯ_БАЗЫ_ДАННЫХ].[srv].[KillFullOldConnect];
end try
begin catch
declare @str_mess nvarchar(max)=ERROR_MESSAGE(),
@str_num nvarchar(max)=cast(ERROR_NUMBER() as nvarchar(max)),
@str_line nvarchar(max)=cast(ERROR_LINE() as nvarchar(max)),
@str_proc nvarchar(max)=ERROR_PROCEDURE(),
@str_title nvarchar(max)='УДАЛЕНИЕ ЗАВИСШИХ ПРОЦЕССОВ НА СЕРВЕРЕ '+@@servername,
@str_pred_mess nvarchar(max)='НА '+@@servername+' СЕРВЕРЕ ВОЗНИКЛА ОШИБКА УДАЛЕНИЯ ЗАВИСШИХ ПРОЦЕССОВ';
exec [ИМЯ_БАЗЫ_ДАННЫХ].srv.ErrorInfoIncUpd
@ERROR_TITLE = @str_title,
@ERROR_PRED_MESSAGE = @str_pred_mess,
@ERROR_NUMBER = @str_num,
@ERROR_MESSAGE = @str_mess,
@ERROR_LINE = @str_line,
@ERROR_PROCEDURE = @str_proc,
@ERROR_POST_MESSAGE = NULL,
@RECIPIENTS = 'ПОЛУЧАТЕЛЬ1;ПОЛУЧАТЕЛЬ2;';
declare @err int=@@error;
raiserror(@str_mess,16,1);
end catch
Здесь используется хранимая процедура srv.KillFullOldConnect
Результат
В данной статье был рассмотрен пример расширения функционала обычного Database Mail, а также разобран пример как формировать уведомления в HTML-таблицы с последующей отправкой по почте администраторам. Данный подход позволяет уведомлять администраторов о разных проблемах в реальном времени или через какое-то определенное время. Таким образом, данный подход позволяет минимизировать в будущем наступления критической проблемы и остановки работы СУБД и сервера, что в свою очередь защищает производство от остановки рабочих процессов.
Источники:
» sp_send_dbmail
» Database Mail
» srv.KillFullOldConnect
Для того чтобы MSSQL сервер мог слать уведомления на почту, необходимо настроить Database Mail. Без уведомлений сложно администрировать SQL Server 2019.
Функционал этой фичи на самом деле гораздо богаче. Можно по почте слать SQL запросы и получать результаты. Мне это не требуется, но такой функционал возможен. К примеру, по почте можно с помощью SQL запроса получать какие-нибудь внутренние данные для мониторинга бизнес-системы. Естественно, такие данные не должны быть критичны, электронная почта — не самый быстрый способ получать данные из базы.
Заходим в Management и видим там Database Mail:
Правой кнопкой на Database Mail, выбираем Configure Database Mail:
Запускается мастер настройки Mail Configuration Wizard:
Кликаем Next. Выбираем View or change system parameters:
Кликаем Next.
Если ранее Database Mail не настраивали, то MSSQL может спросить, нужно ли включить фичу, тогда включаем. Yes.
В следующем окне настраиваем параметры.
- Logging Level ставим Normal, мне особо не нужно логировать сообщения.
- Account Retry Delay (seconds) меняю с 60 на 3600, мне не нужно, чтобы SQL сервер пытался раз в минуту достать письмо при падении почты. Пусть час подождёт, потом попробует снова.
- Остальные параметры не меняю.
Нажимаем Next.
Finish.
Success, параметры изменены. Close.
Повторяем, снова открываем окно конфигурации.
Теперь выбираем первый пункт Set up Database Mail by performing the following tasks. Next.
Указываем Profile name, например, postfix-sql. Добавляем SMTP аккаунт кнопкой Add…
Заполняем настройки SMTP сервера, через который будем слать почту. OK.
Next.
В следующем окне устанавливаем галку Public напротив созданного профиля и выбираем из списка Default Profile: Yes. Next.
Это мы уже настраивали, Next.
Finish.
Success, Close.
Попробуем отправить тестовое сообщение:
Дальше понятно, указываете свой ящик.
Send Test E-Mail.
Отправлено 1 письмо. Если письмо дошло, значит, всё настроено правильно.
Прочитано:
1 477
В сегодняшнем выпуске заметок я покажу какие действия нужно проделать, чтобы при запуске Плана обслуживания в который входит задача создания бекапа, после приходило уведомление на почту о состоянии данной запланированной задачи. Т.е. не просто был настроен ежедневный полный бекап базы данных, но и отчет на почту о статусе, времени начала и завершения и другой полезной технической информации. В таком отчете будет наглядная расшифровка если что-то пойдет не так, так на много лучше чем заступаю на смену заходить на каждый сервер и анализировать логи работы задания. Ранее я описывал, как сделать текущую задачу этой заметки для SQL Server 2008 R2, а в этот раз для новой редакции SQL Server 2014.
Считаю что все что используется на работе или дома в системном администрировании должно быть задокументировано, проанализировано дабы потом не было мучительно вспоминать в впопыхах , а как восстановить работу или настройку.
Итак текущие характеристики сервера под базу данных
- Server 2008 R2 SP1 Enterprise
- RAM = 8Gb
- CPU = 2, Cores = 2
- HDD = 50Gb (System), 100GB — Data (DATA,LOG,BACKUP)
- SQL Server 2014 (12.0.5000.0) установлен с использование двух пакетов:
- SQLServer2014SP1-FullSlipstream-x64-ENU
- SQLServer2014SP2-FullSlipstream-x64-ENU
Шаг №1: Запускаем оснастку SQL Server Management Studio (SQL Server 12.0.5000.0)
Start — All Programs — Microsoft SQL Server 2014 — SQL Server 2014 Management Studio, авторизуюсь, перехожу в меню Management — Database Mail — и через правый клик вызываю настройку: Configure Database Mail
Set up Database Mail by performing the following tasks → и нажимаем Next,
The Database Mail feature is not available: Would you like to enable this feature? — Yes
- Profile name: mssql-plan
SMTP accounts: — Add
- Account name: mssql-plan
Outgoing Mail Server (SMTP):
- E-mail address: mssql-plan@<mail_zimbra_server>
- Display name: mssql-plan
- Server name: 10.9.9.10
- Port number: 25
- SMTP Auhtentication: Basic authentication
- User name: mssql-plan@<mail_zimbra_server>
- Password: Aa1234567
- Confirm password: Aa1234567
И нажимаем OK
В итоге получаются настройки нового профиля mssql-plan:
Нажимаем Next, теперь нужно определить кому будет доступен данный профиль: либо публичный, либо приватный и какой из них назначен будет дефолтным, я выбираю для своих настроек Public Profiles
Нажимаем Next → Next — Finish, конфигурирование профиля под почтовый сервер Zimbra прошло успешно:
Шаг №2: После проверяем отправку тестового письма:
меню Management оснастки SQL Management Studio — Database Mail — и через правый клик вызываем меню: Send Test E-Mail…, заполняем поля кому придет тестовое письмо:
Database Mail Profile: mssql-plan
To: alexander.ollo@<mail_zimbra_server>
Subject: Database Mail Test
Body: This is a test e-mail from Database Mail on SRV-BD4
и нажимаю Send Test E-Mail
Проверяю свой почтовый ящик и вижу, что письмо успешно доставлено:
Шаг №3: После создаю кому нужно будет присылать отчет о результатах отработанной задачи: меню SQL Server Agent оснастки SQL Server Management Studio — Operators — New Operator… —
General:
- Name: backup
- Enabled: отмечено галочкой
- E-Mail name: alexander.ollo@<mail_zimbra_server>
Шаг №4: После переключаюсь на меню Management оснастки SQL Server Management Studio — Maintenance Plans — и через правый клик мышью вызываем меню Maintenance Plan Wizard:
- Name: Backup
- Run as: SQL Server Agent service account
- Single schedule for the entire plan or no schedule: отмечаю этот пункт
Schedule: → Change:
- Name: MaintenancePlanBackup
- Schedule type: Recuring
- Enable: отмечаю галочкой
- Frequency → Occurs: Daily
- Recurs every: 1 days
- Daily frequency: Occurs once at: 3:00:00 PM
После нажимаем OK, Next, выбираю задачу для этого плана → Back Up Database (Full), Next, Next: на вкладке General нужно указать какие базы нужно бекапировать полностью:
General:
- Database(s): BazaBuh
- Back up to: Disk
вкладка Options:
- Set backup compression: Compress backup
После всех настроек нажимаем Next и изменяем поведение опции отчета, мне нужно не в лог файл, а на почту:
Нажимаю Next, Finish, Close.
Шаг №5: После проверяю, как отработает план и что мне придет на почту.
Меню Management оснастки SQL Server Management Studio — Maintenance Plans — Backup — и через правый клик мышью вызываю меню Execute
Исполнение задачи в процессе…
Хотя когда план обслуживания отработал есть возможность в ручную отправить отчет по почте:
Но у меня все в автоматическом режиме, так что проверяю почту:
Итого отчет на почту успешно пришел о полном завершении бекапа с некоторой отладочной информацией для ознакомления.
Работает, как я смотрю на задокументированные шаги выше все просто или просто тому кто был заинтересован сделать это, а не отлынивал с отмазками, а чем можно заняться, мне нечего делать, мне не поручают ничего важного. Просто любое свободное время на работе нужно использовать с пользой повышая свою квалификацию, как делаю я описываю в шагах интересующие меня настройки и задачи. На этом всё, с уважением автор блога Олло Александр aka ekzorchik.
КВАДРО2
18.11.11
✎
10:55
Как сделать сообщение в MS SQL на емайл если не сделался бэкап?
MS SQL 2008 R2
rs_trade
18.11.11
✎
10:58
(0) там штатно все можно сделать в плане обслуживания. только сначала учетку почты надо настроить.
rs_trade
18.11.11
✎
11:01
Managment — Database mail настраиваешь учетку
rs_trade
18.11.11
✎
11:04
Потом в свойствах джоба бекапа — Notifactions. E-mail when the jobs fail. Как то так вроде
КВАДРО2
18.11.11
✎
11:26
Спасибо
MaxS
18.11.11
✎
12:00
Если сервер выключили на 2 дня, ежедневный бэкап не сделался, потом сервер включили. Письмо придёт?
rs_trade
18.11.11
✎
18:16
(5) врят ли. как я описал, это когда произошел фейл при создании бекапа. но можно сделать что бы и в описаном случае приходило.
Смотрящий от 1С
18.11.11
✎
18:24
(5) сделай от обратного, сообщение на суксесс и если два дня никто не пишет, начинай волноваться
V_V_V
18.11.11
✎
18:31
(7) Классный совет!
— Что такое одиночество?
— Это когда о тебе забыли даже спамеры…
shuhard
18.11.11
✎
18:35
(7) +1
у меня так и сделано еженочное проведение по партиям,
если к завтраку письма нет, лезу терминалкой разбираться
MaxS
18.11.11
✎
18:38
(7) если баз много, придётся где-то делать ещё один скрипт, который анализирует письма и присылает обобщенную информацию.
Всё ОК
или Все нормально, кроме: …
(8) завести твиттер, в который будут писать роботы. Другие роботы пусть анализируют и дают комментарии.
Если они перестали писать, значит дела совсем плохи
(9) у меня обмен так сделан. Если письма нет, значит либо оно не дошло, либо действительно есть проблема.
shuhard
18.11.11
✎
18:46
(10) угу
и такое делал,
крутился сборщик почты и будил оператора, если пришла почта не из всего списка
После настройки и введения в эксплуатацию MS SQL сервера обязательно потребуется настроить ряд регламентных заданий. Эти задания требуются для автоматического обслуживания развёрнутых баз (проверка баз данных, их резервное копирование, обслуживание индексов и т.д.). При долгосрочном использовании баз могут возникнуть ситуации, когда регламентные задачи могут отрабатываться с ошибками (нехватка места для резервных копий, критические ошибки в базах данных и другие).
Для оперативного оповещения об ошибках выполнения регламентных заданий MS SQL можно настроить специальный компонент оповещения Database Mail.
Настройка Компоненты Database Mail
Вначале необходимо настроить профиль Database Mail. Для этого нужно запустить мастер настройки.
В случае первоначальной настройки компонента нужно выбрать первый пункт «Установить компонент Database Mail». После этого подтвердить включение компонента Database Mail.
Далее нужно задать имя профиля и добавить учётную запись SMTP (адрес и настройки сервера отправки писем).
На следующем шаге мастера отметить созданный профиль, как «Открытый» и «Профиль по умолчанию».
Следующий шаг мастера изменений не требует.
После создания профиля желательно выполнить проверку, отправив тестовое письмо.
Добавление оператора оповещений
Теперь требуется создать Операторов (пользователей, которым будут высылаться оповещения).
Для оператора достаточно указать Имя и адрес почты (куда будут высылаться оповещения)
Теперь нужно активировать профиль компонента Database Mail в настройках агента SQL.
Создание задач оповещения
Задача создаётся в виде дополнительного шага (Задача «Уведомление оператора») регламентного задания. Основным вариантом применения будет выполнение шага при неудачном выполнении одной из операций регламентного задания. В задаче уведомления требуется указать оператора, которому будет выслано оповещение, тему и содержание письма.
You can use a BackupRestore Event Notification to monitor backup events and this solution even works on Sql Express (where the Sql Agent doesn’t exist). This link shows you how to set up SQL Mail for SQL Server Express.
I created a database called Test.
I modified this example from Jonathan Kehayias, which was tracking autogrowth, to instead audit the backup/restore event.
Here is my example that was tweaked from Jonathan’s:
-- Using msdb prevents the need for certificate signing the
-- activation procedure to execute sp_send_dbmail across
-- databases
USE [msdb];
GO
-- Drop the notification if it exists
IF EXISTS (
SELECT *
FROM sys.server_event_notifications
WHERE NAME = N'CaptureDatabaseBackupEvent'
)
BEGIN
DROP EVENT NOTIFICATION CaptureDatabaseBackupEvent ON SERVER;
END
-- Drop the route if it exists
IF EXISTS (
SELECT *
FROM sys.routes
WHERE NAME = N'DatabaseBackupEventRoute'
)
BEGIN
DROP ROUTE DatabaseBackupEventRoute;
END
-- Drop the service if it exists
IF EXISTS (
SELECT *
FROM sys.services
WHERE NAME = N'DatabaseBackupEventService'
)
BEGIN
DROP SERVICE DatabaseBackupEventService;
END
-- Drop the queue if it exists
IF EXISTS (
SELECT *
FROM sys.service_queues
WHERE NAME = N'DatabaseBackupEventQueue'
)
BEGIN
DROP QUEUE DatabaseBackupEventQueue;
END
-- Create a service broker queue to hold the events
CREATE QUEUE [DatabaseBackupEventQueue]
WITH STATUS = ON;
GO
-- Create a service broker service receive the events
CREATE SERVICE [DatabaseBackupEventService] ON QUEUE [DatabaseBackupEventQueue] ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification]);
GO
-- Create a service broker route to the service
CREATE ROUTE [DatabaseBackupEventRoute]
WITH SERVICE_NAME = 'DatabaseBackupEventService'
,ADDRESS = 'LOCAL';
GO
-- Create the event notification to capture the events
CREATE EVENT NOTIFICATION [CaptureDatabaseBackupEvent] ON SERVER
WITH FAN_IN
FOR AUDIT_BACKUP_RESTORE_EVENT TO SERVICE 'DatabaseBackupEventService'
,'current database';
GO
-- Alter the queue to use the activation procedure
ALTER QUEUE [DatabaseBackupEventQueue]
WITH STATUS=ON,
ACTIVATION
(STATUS=ON,
PROCEDURE_NAME = [ProcessDatabaseBackupEvents],
MAX_QUEUE_READERS = 1,
EXECUTE AS OWNER);
GO
I then tweaked his example stored procedure that consumes the event.
Make sure you change this line in the stored procedure to be your email address
@recipients = ‘YourEmailAddress’
DROP PROCEDURE [dbo].[ProcessDatabaseBackupEvents];
GO
CREATE PROCEDURE [dbo].[ProcessDatabaseBackupEvents]
WITH EXECUTE AS OWNER
AS
DECLARE @message_body XML;
DECLARE @message_sequence_number INT;
DECLARE @dialog UNIQUEIDENTIFIER;
DECLARE @email_message NVARCHAR(MAX);
WHILE (1 = 1)
BEGIN
BEGIN TRANSACTION;
-- Receive the next available message FROM the queue
WAITFOR (
RECEIVE TOP (1) -- just handle one message at a time
@message_body = CAST(message_body AS XML) FROM dbo.DatabaseBackupEventQueue
)
,TIMEOUT 1000;-- if queue empty for 1 sec, give UPDATE AND GO away
-- If we didn't get anything, bail out
IF (@@ROWCOUNT = 0)
BEGIN
ROLLBACK TRANSACTION;
BREAK;
END
DECLARE @EventType VARCHAR(128);
DECLARE @ServerName VARCHAR(128);
DECLARE @PostTime VARCHAR(128);
DECLARE @DatabaseName VARCHAR(128);
DECLARE @TextData VARCHAR(max);
DECLARE @GrowthPages INT;
SELECT @EventType = @message_body.value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(128)')
,@TextData = @message_body.value('(/EVENT_INSTANCE/TextData)[1]', 'varchar(128)')
,@ServerName = @message_body.value('(/EVENT_INSTANCE/ServerName)[1]', 'varchar(128)')
,@PostTime = CAST(@message_body.value('(/EVENT_INSTANCE/PostTime)[1]', 'datetime') AS VARCHAR)
,@DatabaseName = @message_body.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(128)');
-- Generate formatted email message
SELECT @email_message = 'The following DatabaseBackup event occurred:' + CHAR(10) + CAST('ServerName: ' AS CHAR(25)) + @ServerName + CHAR(10) + CAST('PostTime: ' AS CHAR(25)) + @PostTime + CHAR(10) + CAST('DatabaseName: ' AS CHAR(25)) + @DatabaseName + @TextData
-- Send email using Database Mail
EXEC msdb.dbo.sp_send_dbmail @profile_name = 'SqlServerEmailProfile'
,
-- your defined email profile
@recipients = 'YourEmailAddress'
,-- your email
@subject = 'DatabaseBackup Event Notification'
,@body = @email_message;
-- Commit the transaction. At any point before this, we could roll
-- back. The received message would be back on the queue AND the
-- response wouldn't be sent.
COMMIT TRANSACTION;
END
GO
Then, I ran a simple backup
BACKUP DATABASE [Test] TO DISK = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup\test.bak'
WITH NOFORMAT
,INIT
,NAME = N'Test-Full Database Backup'
,SKIP
,NOREWIND
,NOUNLOAD
,STATS = 10
GO
After a minute or so, I received the email with the event data in it. You can modify the event consuming stored procedure to capture whatever you need and send that information along in the email.