Як я можу мати SQL Server надіслати електронною поштою інформацію про помилки, коли завдання не працює?


14

SQL Server дозволяє налаштувати завдання для надсилання сповіщень електронною поштою, коли воно не працює. Це простий та ефективний спосіб контролювати ваші робочі місця. Однак ці сповіщення не містять деталей - лише повідомлення про успіх чи помилку.

Якщо завдання не вдалося, виглядатиме типовий електронний лист попередження:

JOB RUN:        'DBA - Consistency Check Databases' was run on 8/14/2011 at 12:00:04 AM
DURATION:       0 hours, 0 minutes, 0 seconds
STATUS:         Failed
MESSAGES:       The job failed.  The Job was invoked by Schedule 2 (Nightly Before 
                Backup 12AM).  The last step to run was step 1 (Check Databases).

Щоб визначити причину відмови, вам потрібно перейти до екземпляра в SQL Server Management Studio, знайти завдання та переглянути історію його виконання. У великій обстановці може боліти постійно це робити.

Ідеальний електронний лист буде включати в себе причину відмови заздалегідь і дозволяє вам безпосередньо працювати над рішенням.

Мені знайоме вирішення цієї проблеми. Хтось має з цим досвід? Його недоліками є:

  1. ви повинні додати новий крок до кожної вашої роботи та
  2. ви повинні молитися, щоб ніхто не псував тривожну процедуру, spDBA_job_notification

Хтось придумав краще рішення?

Відповіді:


10

Щось ти можеш зробити, це просто думка, викидання ідей ...

Створіть єдине завдання, яке періодично перевіряє таблицю завдань у msdb, щоб побачити, чи якісь завдання показані як невдалі, це можна зробити за допомогою хорошого T-SQL запиту . Потім ви можете зайти в таблицю sysjobsteps і побачити, чи встановлений журнал виводу для завдання. Запропонуйте збереженій процедурі надіслати електронний лист, який додає цей файл до нього. Ви змогли б точно побачити, що робила робота від початку до відмови, не торкаючись сервера.

Тоді також може бути сценарій PowerShell перевірити журнал подій на наявність помилок. Це дозволяє відфільтрувати досить непоганий шматочок, щоб точно визначити, які типи повідомлень ви шукаєте. Ви можете встановити це завдання як SQL Agent, яке потрібно періодично виконувати. Потім у сценарії PowerShell використовуйте командлет електронної пошти, щоб надіслати повідомлення, якщо воно знайде.

Тут далеко не знайдені ідеї, лише про які я думав.


3

Я маю досвід роботи з вищезгаданою ідеєю . Це добре, але кращою ідеєю було б зробити щось так, як сказав Шон.

Що ми зробили, це зробити роботу, яка працює кожні 5 хвилин, і сканувати таблиці MSDB на предмет відмов. Для кожної роботи, яка мала помилку, ми запустили SP spDBA_job_notification зі своїм власним ідентифікатором, тому SP буде сканувати кроки історії MSDB на наявність помилок та надсилати їх по електронній пошті всім. З документації на SP: "Збережена процедура використовує ідентифікатор завдання для запиту таблиць агента msdb для останнього повідомлення про помилку для цього завдання."

Тож замість того, щоб просто міняти кожну роботу, краще створіть єдину, яка робить все ;-).

Інша ідея полягає в тому, щоб встановити всі завдання для запису в програму перегляду подій Windows у разі помилок / збоїв і прочитати звідти з розширеним proc xp_ReadErrorLog або автоматичним інструментом, якщо у вас це вже є у вашій мережі. Наприклад, ми використовували HPOV для перевірки будь-яких системних проблем і можемо налаштувати просте сповіщення про всі помилки переглядача подій (не потрібно ніякої спеціальної роботи чи процедури).


2

Спробуйте це і просто підключіть свої змінні, якщо потрібно в TSQL. Ключове значення полягає в тому, щоб це ставити як останній крок кожного окремого завдання агента SQL, але кожен крок завдання над ним потрібно перейти до НАЙКЛЮЧЕННЯ КРОКУ, будь то НЕПРАВНІСТЬ чи УСПІХ ... Працює для мене просто чудово здебільшого, але будь ласка повідомте про будь-які проблеми, з якими ви стикаєтесь. Ми на SQL Server 2008 R2, тому він використовується там, де я його зараз налаштував.

SELECT  step_name, message
FROM    msdb.dbo.sysjobhistory
WHERE   instance_id > COALESCE((SELECT MAX(instance_id) FROM msdb.dbo.sysjobhistory
                                WHERE job_id = $(ESCAPE_SQUOTE(JOBID)) AND step_id = 0), 0)
        AND job_id = $(ESCAPE_SQUOTE(JOBID))
        AND run_status <> 1 -- success

IF      @@ROWCOUNT <> 0
BEGIN
        RAISERROR('*** SQL Agent Job Prior Step Failure Occurred ***', 16, 1)

DECLARE @job_name NVARCHAR(256) = (SELECT name FROM msdb.dbo.sysjobs WHERE job_id = $(ESCAPE_SQUOTE(JOBID)))
DECLARE @email_profile NVARCHAR(256) = 'SQLServer Alerts'
DECLARE @emailrecipients NVARCHAR(500) = 'EmailAddr@email.com'
DECLARE @subject NVARCHAR(MAX) = 'SQL Server Agent Job Failure Report: ' + @@SERVERNAME
DECLARE @msgbodynontable NVARCHAR(MAX) = 'SQL Server Agent Job Failure Report For: "' + @job_name + '"'

--Dump report data to a temp table to be put into XML formatted HTML table to email out
SELECT sjh.[server]
    ,sj.NAME
    ,sjh.step_id
    ,sjh.[message]
    ,sjh.run_date
    ,sjh.run_time
INTO #TempJobFailRpt
FROM msdb..sysjobhistory sjh
INNER JOIN msdb..sysjobs sj ON (sj.job_id = sjh.job_id)
WHERE run_date = convert(INT, convert(VARCHAR(8), getdate(), 112))
    AND run_status != 4 -- Do not show status of 4 meaning in progress steps
    AND run_status != 1 -- Do not show status of 1 meaning success
    AND NAME = @job_name
ORDER BY run_date

IF EXISTS (
        SELECT *
        FROM #TempJobFailRpt
        )
BEGIN

-----Build report to HTML formatted email using FOR XML PATH
DECLARE @tableHTML NVARCHAR(MAX) = '
<html>
<body>
    <H1>' + @msgbodynontable + '</H1>
        <table border="1" style=
        "background-color: #C0C0C0; border-collapse: collapse">
        <caption style="font-weight: bold">
            ****** 
            Failure occurred in the SQL Agent job named: ''' + @job_name + ''' in at least one of the steps. 
            Below is the job failure history detail for ALL runs of this job today without needing to connect to SSMS to check.
            ******
        </caption>

<tr>
    <th style="width:25%; text-decoration: underline">SQL Instance</th>
    <th style="text-decoration: underline">Job Name</th>
    <th style="text-decoration: underline">Step</th>
    <th style="text-decoration: underline">Message Text</th>
    <th style="text-decoration: underline">Job Run Date</th>
    <th style="text-decoration: underline">Job Run Time</th>
</tr>' + CAST((
            SELECT td = [server]
                ,''
                ,td = NAME
                ,''
                ,td = step_id
                ,''
                ,td = [message]
                ,''
                ,td = run_date
                ,''
                ,td = run_time
            FROM #TempJobFailRpt a
            ORDER BY run_date
            FOR XML PATH('tr')
                ,TYPE
                ,ELEMENTS XSINIL
            ) AS NVARCHAR(MAX)) + '
    </table>
</body>
</html>';

EXEC msdb.dbo.sp_send_dbmail @profile_name = @email_profile
    ,@recipients = @emailrecipients
    ,@subject = @subject
    ,@body = @tableHTML
    ,@body_format = 'HTML'

--Drop Temp table
    DROP TABLE #TempJobFailRpt
END
ELSE
BEGIN
    PRINT '*** No Records Generated ***' 
    DROP TABLE #TempJobFailRpt
END
END

Я знаю, що це стара тема, але рішення від @ Crazy Ivan працює в пригоді - я можу підтвердити, що він працює на SQL Server 2012
Michael
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.