Bagaimana saya bisa meminta SQL Server mengirimi saya email rincian kesalahan saat pekerjaan gagal?


14

SQL Server memungkinkan Anda mengkonfigurasi pekerjaan untuk mengirim peringatan email ketika gagal. Ini adalah cara sederhana dan efektif untuk memantau pekerjaan Anda. Namun, lansiran ini tidak menyertakan detail apa pun - hanya pemberitahuan keberhasilan atau kegagalan.

Jika suatu pekerjaan gagal, seperti inilah tampilan email peringatan:

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).

Untuk menentukan penyebab kegagalan, Anda harus menavigasi ke contoh di SQL Server Management Studio, mencari pekerjaan, dan melihat riwayat pelaksanaannya. Dalam lingkungan yang besar itu bisa menjadi menyakitkan harus terus melakukan ini.

Email peringatan ideal akan menyertakan alasan kegagalan dimuka dan memungkinkan Anda langsung mengerjakan solusinya.

Saya kenal dengan solusi untuk masalah ini. Adakah yang punya pengalaman dengan itu? Kelemahannya adalah:

  1. Anda harus menambahkan langkah baru setiap pekerjaan yang Anda miliki, dan
  2. Anda harus berdoa agar tidak ada yang mengacaukan proc waspada, spDBA_job_notification

Adakah yang punya solusi yang lebih baik?

Jawaban:


10

Sesuatu yang mungkin Anda lakukan itu hanya sebuah pemikiran, membuang ide-ide ...

Buat satu pekerjaan yang secara berkala memeriksa tabel pekerjaan di msdb untuk melihat apakah ada pekerjaan yang gagal, yang dapat dilakukan dengan kueri T-SQL yang bagus . Kemudian Anda bisa masuk ke tabel sysjobsteps dan melihat apakah log keluaran diatur untuk pekerjaan itu. Suruh prosedur tersimpan mengirim email melampirkan file itu ke sana. Anda akan dapat melihat dengan tepat apa yang dilakukan pekerjaan itu dari awal hingga gagal tanpa harus menyentuh server.

Kemudian bisa juga memiliki skrip PowerShell memeriksa log peristiwa untuk kesalahan. Ini memungkinkan Anda untuk menyaring sedikit yang cukup bagus untuk mendapatkan jenis pesan apa yang Anda cari. Anda bisa mengatur itu sebagai pekerjaan SQL Agent untuk berjalan secara berkala. Kemudian dalam skrip PowerShell gunakan cmdlet email untuk mengirim pesan jika menemukannya.

Far mengambil ide di sini, hanya beberapa yang saya pikirkan.


3

Saya memiliki pengalaman dengan ide tersebut . Itu bagus, tetapi ide yang lebih baik adalah melakukan sesuatu seperti yang dikatakan Shawn.

Apa yang kami lakukan adalah membuat pekerjaan yang berjalan setiap 5 menit dan memindai tabel MSDB tentang kegagalan pekerjaan. Untuk setiap pekerjaan yang mengalami kegagalan, kami akan menjalankan SP spDBA_job_notification dengan ID itu sendiri, sehingga SP akan memindai langkah-langkah sejarah MSDB untuk mencari kesalahan dan mengirimkan email kepada mereka semua. Dari dokumentasi SP: "Prosedur tersimpan menggunakan ID pekerjaan untuk meminta tabel agen msdb untuk pesan kesalahan terbaru untuk pekerjaan itu."

Jadi, alih-alih hanya mengubah setiap pekerjaan, lebih baik buat satu pekerjaan saja ;-).

Gagasan lain adalah mengatur semua pekerjaan untuk menulis ke Windows Event Viewer jika terjadi kesalahan / kegagalan dan membaca dari sana dengan proc xp_ReadErrorLog yang diperluas atau alat otomatis, jika Anda sudah memilikinya di jaringan Anda. Sebagai contoh, kami menggunakan HPOV untuk memeriksa masalah sistem dan dapat mengkonfigurasi peringatan sederhana untuk semua kesalahan penampil acara (tidak perlu untuk pekerjaan atau prosedur khusus).


2

Cobalah ini dan cukup tancapkan variabel Anda sesuai kebutuhan di TSQL. Kuncinya di sini adalah untuk menempatkan ini sebagai langkah terakhir dari setiap pekerjaan agen SQL individu tetapi setiap langkah kerja di atasnya perlu menuju LANGKAH SELANJUTNYA apakah KEGAGALAN atau KEBERHASILAN ... Bekerja untuk saya baik-baik saja untuk sebagian besar tetapi tolong laporkan setiap masalah yang Anda alami. Kami menggunakan SQL Server 2008 R2, jadi ini digunakan di mana saya mengaturnya saat ini.

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

Saya tahu ini adalah utas lama, tetapi solusinya oleh @Crazy Ivan bekerja dengan baik - Saya dapat mengonfirmasi bahwa itu berfungsi pada SQL Server 2012
Michael
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.