2009-02-23 191 views
5

我想設置SQL Server 2008警報以在任何過程執行1秒或更長時間(僅舉例)時通知我。存儲過程執行時間過長時的SQL警報

任何想法?

編輯:

好吧,看來這是不可能的。但是,爲了向另一個方向推動你,我知道主數據庫中有統計表,它們包含編譯計數,調用次數和其他各種統計信息。我可以定期查詢它們,然後報告它,不知何故?

回答

3

不,這裏沒有通知。 你必須設置一個跟蹤並且隨時進行輪詢。

+0

你能給我多一點細節? – muerte 2009-02-23 15:41:59

2

如果發現這個對sqlservercentral(它可能是一個較舊版本的SQL Server,但仍適用於2008年)

告警過程對於長時間運行的工作 下面http://www.sqlservercentral.com/scripts/Lock+and+Connection+Management/30144/

文本,如果你不能訪問它。

對於定期運行並且只需很短時間運行的作業,DBA可能想知道作業何時運行時間過長。在這種情況下,只要檢查一下工作是否正在運行就行;有必要確保它沒有長期運行的能力。將作業ID匹配到sysprocesses中的進程ID需要重新安排作業ID來進行匹配。此腳本創建一個存儲過程,該存儲過程將接受作業名稱,允許的最長運行時間以及要通知的電子郵件地址。然後,它將使用作業名稱重新組合作業編號並檢查sysprocesses(基於作爲程序名稱一部分的進程ID)以確定作業運行的時間量,然後在該時間結束時發出警報「允許時間」參數。

CREATE proc sp_check_job_running 
    @job_name  char(50), 
    @minutes_allowed int, 
    @person_to_notify varchar(50) 
AS 

DECLARE @var1   char(1), 
    @process_id  char(8), 
    @job_id_char  char(8), 
    @minutes_running int, 
    @message_text  varchar(255) 

select @job_id_char = substring(CAST(job_id AS char(50)),1,8) 
from msdb..sysjobs 
where name = @job_name 

select @process_id = substring(@job_id_char,7,2) + 
      substring(@job_id_char,5,2) + 
      substring(@job_id_char,3,2) + 
      substring(@job_id_char,1,2) 


select @minutes_running = DATEDIFF(minute,last_batch, getdate()) 
from master..sysprocesses 
where program_name LIKE ('%0x' + @process_id +'%') 

if @minutes_running > @minutes_allowed 
    BEGIN 
    select @message_text = ('Job ' 
    + UPPER(SUBSTRING(@job_name,1,LEN(@job_name))) 
    + ' has been running for ' 
    + SUBSTRING(CAST(@minutes_running AS char(5)),1,LEN(CAST(@minutes_running AS char(5)))) 
    + ' minutes, which is over the allowed run time of ' 
    + SUBSTRING(CAST(@minutes_allowed AS char(5)),1,LEN(CAST(@minutes_allowed AS char(5)))) 
    + ' minutes.') 
    EXEC master..xp_sendmail 
    @recipients = @person_to_notify, 
    @message = @message_text, 
     @subject = 'Long-Running Job to Check' 
    END 

-- Typical job step syntax for job to do the checking 

execute sp_check_job_running 
     'JobThatSHouldBeDoneIn5Minutes', 
     5, 
     '[email protected]' 
+0

這將檢查工作表現。我需要檢查數據庫(或整個服務器)中執行的每個存儲過程。 – muerte 2009-02-23 15:38:26

0

您可以登錄運行較慢的查詢使用SQL事件探查器,但不會幫助你的警告,特別是。 (我想你可以登錄到一個文件或數據庫表,並有其他的東西「聽」,並提出警報)。

如果你不熟悉SQL事件探查器這裏的步驟:

您應該比服務器本身以外的東西上運行SQL事件探查器。

開始與SQLProfilerTSQL_Duration模板

設置過濾器:時間:1000(milliseonds)

在篩選器可以限制數據庫,登錄,或在必要時類似「大於」。

在可以限制只存儲過程的事件(默認還包括SQL語句)

+0

是的,這是手動工作,不自動(沒有警報)。 – muerte 2009-02-23 15:42:56

0

如果你是不是在找一個免費的解決方案,你可以看看SQL Sentry。它做你的要求和更多。

2

我想添加到Mladen Prajdic的正確答案,並改進來自SQL Server Central的kevchadders的回答。我在下面提出的解決方案使用DBMail代替SQLMail(通過xp_sendmail調用由SQLServerCentral的解決方案使用)。實質上,SQLMail使用MAPI,而且安裝起來比較困難,DBMail使用SMTP並且更容易設置。這裏的more information關於兩者的區別。

我無法獲得SQL Server Central的解決方案在SQL 2005中工作,下面的解決方案僅在我安裝的基於版本的SQL 2005 - YMMV上進行了測試。

首先,你需要一個新的UDF,這將作業ID轉換成進程ID爲聯接:

CREATE FUNCTION dbo.udf_SysJobs_GetProcessid(@job_id uniqueidentifier) 
RETURNS VARCHAR(8) 
AS 
BEGIN 
    RETURN (substring(left(@job_id,8),7,2) + 
    substring(left(@job_id,8),5,2) + 
    substring(left(@job_id,8),3,2) + 
    substring(left(@job_id,8),1,2)) 
END 

然後是存儲過程:

CREATE PROC sp_check_job_running 
    @job_name char(50), 
    @minutes_allowed int, 
    @person_to_notify varchar(50) 

AS 

DECLARE @minutes_running int, 
    @message_text varchar(255) 

SELECT @minutes_running = isnull(DATEDIFF(mi, p.last_batch, getdate()), 0) 
FROM master..sysprocesses p 
JOIN msdb..sysjobs j ON dbo.udf_sysjobs_getprocessid(j.job_id) = substring(p.program_name,32,8) 
WHERE j.name = @job_name 

IF @minutes_running > @minutes_allowed 
    BEGIN 
     SELECT @message_text = ('Job ' + UPPER(SUBSTRING(@job_name,1,LEN(@job_name))) + ' has been running for ' + SUBSTRING(CAST(@minutes_running AS char(5)),1,LEN(CAST(@minutes_running AS char(5)))) + ' minutes, which is over the allowed run time of ' + SUBSTRING(CAST(@minutes_allowed AS char(5)),1,LEN(CAST(@minutes_allowed AS char(5)))) + ' minutes.') 
     EXEC msdb.dbo.sp_send_dbmail 
     @recipients = @person_to_notify, 
     @body = @message_text, 
     @subject = 'Long-Running Job to Check' 
    END 

此存儲過程可以可以輕鬆地安排爲SQL Server代理作業或任何其他必需的方法。如果作業未運行或它在指定參數內運行,則不採取任何操作。如果作業運行時間超過指定時間,它會發送電子郵件。

例如

EXEC sp_check_job_running 'JobNameGoesHere', 5, '[email protected]' 

HT:http://www.sqlserverspecialists.co.uk/blog/_archives/2008/11/26/3996346.html

2

你可以使用監控軟件像Nagios定期算在你的數據庫查詢速度慢的數量。

我個人使用以下查詢與優秀PRTG。我將它設置爲大於3秒內每次,或當最慢的查詢超過10秒需要更長的時間我有超過5個查詢與執行時間每次給我發電子郵件:

SELECT total_elapsed_time/execution_count/1000000 avg_elapsed_time, execution_count, creation_time, last_execution_time, 
SUBSTRING(st.text, (qs.statement_start_offset/2) + 1, ((CASE statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) + 1) AS statement_text 
FROM sys.dm_exec_query_stats AS qs 
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st 
WHERE total_elapsed_time/execution_count/1000000 >= 3 -- filter queries that takes > 3 seconds 
AND CHARINDEX('dm_exec_query_stats', st.text) = 0 -- In case this query is slow, we don't want it in the result set! 
ORDER BY total_elapsed_time/execution_count DESC; 

聲明:此查詢基於在https://stackoverflow.com/a/820252/638040

現在,如果你想監控你的存儲過程,那麼就使用sys.dm_exec_procedure_stats代替sys.dm_exec_sql_text(也從選擇刪除該字段creation_time和調整上st.text的子串)