Bir iş başarısız olduğunda SQL Server'ın hata ayrıntılarını bana e-postayla nasıl gönderebilirim?


14

SQL Server, bir işi başarısız olduğunda e-posta uyarıları gönderecek şekilde yapılandırmanıza olanak tanır. Bu, işlerinizi izlemenin basit ve etkili bir yoludur. Ancak, bu uyarılar herhangi bir ayrıntı içermez - sadece bir başarı veya başarısızlık bildirimi.

Bir iş başarısız olursa, tipik bir uyarı e-postası aşağıdaki gibi olacaktır:

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

Hatanın nedenini belirlemek için SQL Server Management Studio'daki örneğe gitmeniz, işi bulmanız ve yürütme geçmişini görüntülemeniz gerekir. Geniş bir ortamda, bunu sürekli yapmak bir acı olabilir.

İdeal uyarı e-postası, hata nedenini önceden içerir ve doğrudan çözüm üzerinde çalışmaya başlamanıza izin verir.

Bu sorunun çözümüne aşinayım . Bununla ilgili herhangi bir deneyimi olan var mı? Dezavantajları:

  1. sahip olduğunuz her işe yeni bir adım eklemelisiniz ve
  2. Hiç kimsenin uyarı sürecini bozmaması için dua etmelisin, spDBA_job_notification

Daha iyi bir çözüm bulan var mı?

Yanıtlar:


10

Yapabileceğiniz bir şey sadece bir fikirdir, fikirleri dışarı atar ...

İyi bir T-SQL sorgusu ile yapılabilecek herhangi bir işin başarısız olarak gösterilip gösterilmediğini görmek için msdb'deki iş tablosunu düzenli olarak kontrol eden tek bir iş oluşturun . Sonra sysjobsteps tablosuna gidip iş için bir çıkış günlüğü ayarlanıp ayarlanmadığını görebilirsiniz. Saklı bir yordamın bu dosyayı ekleyen bir e-posta göndermesini sağlayın. Sunucuya dokunmadan işin başlangıcından başarısızlığa kadar ne yaptığını tam olarak görebileceksiniz.

Daha sonra olay günlüğünde hatalar için PowerShell betiğini kontrol edebilir. Tam olarak aradığınız mesaj türlerini elde etmek için oldukça iyi bir bit filtrelemenizi sağlar. Bunu düzenli olarak çalışacak şekilde bir SQL Agent işi olarak ayarlayabilirsiniz. Ardından PowerShell betiğinde, buluyorsa iletiyi göndermek için cmdlet e-postasını kullanın.

Buraya çok fikir getirdim, sadece düşündüğüm bir kısmı.


3

Sözü edilen fikir konusunda deneyimim var . Güzel, ama Shawn'un dediği gibi bir şey yapmak daha iyi bir fikir olurdu.

Yaptığımız her 5 dakikada bir çalışan ve MSDB tablolarını iş hataları hakkında tarayan bir iş yapmaktı. Başarısız olan her iş için SP spDBA_job_notification uygulamasını kendi kimliğiyle çalıştırırız, böylece SP MSDB geçmiş adımlarını hatalar için tarar ve hepsini e-postayla gönderir . SP belgelerinden: "Saklı yordam, o işin en son hata iletisi için msdb aracı tablolarını sorgulamak için iş kimliğini kullanır."

Yani her işi değiştirmek yerine, her şeyi yapan tek bir tane yaratmak daha iyi ;-).

Başka bir fikir, hata / arıza durumunda tüm işleri Windows Olay Görüntüleyicisi'ne yazacak ve oradan ağınızda zaten varsa genişletilmiş pro xp_ReadErrorLog veya otomatik bir araçla okunacak şekilde ayarlamaktır . Örneğin, sistem sorunlarını kontrol etmek için HPOV kullandık ve tüm olay görüntüleyici hataları için basit bir uyarı yapılandırabiliriz (herhangi bir özel işe veya prosedüre gerek yoktur).


2

Bunu deneyin ve değişkenlerinizi TSQL'de gerektiği gibi takın. Buradaki anahtar, bunu her bir SQL aracısı işinin en son adımı olarak koymaktır, ancak yukarıdaki her iş adımı, ARIZA veya BAŞARI olsun, SONRAKİ ADIM'a gitmelidir ... Benim için işe yarıyor çoğunlukla iyi ama lütfen karşılaştığınız sorunları bildirin. SQL Server 2008 R2 kullanıyoruz, bu yüzden şu anda kurduğum yer burada kullanılıyor.

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

Bu eski bir iş parçacığı olduğunu biliyorum, ama @Crazy Ivan tarafından bir tedavi çalışıyor - SQL Server 2012
Michael
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.