2009-02-23 18 views
5

Vorrei impostare un avviso di SQL Server 2008 per notificarmi quando una procedura viene eseguita per 1 secondo o più (solo un esempio).SQL Alert quando la stored procedure viene eseguita per troppo tempo

Qualche idea?

EDIT:

Va bene, a quanto pare questo non è possibile. Ma, solo per spingerti in un'altra direzione, so che ci sono delle tabelle statistiche nel database principale che contengono i conteggi della compilazione, il numero di chiamate e altre varie statistiche. Potrei forse interrogarli periodicamente e poi riferire in merito, in qualche modo?

risposta

3

no non ci sono notifiche per questo. dovrai impostare una traccia e interrogarla ogni tanto.

+0

Potete darmi un po 'maggiori dettagli ? – muerte

2

Se trovato questo su sqlservercentral (probabilmente per una versione precedente di SQL Server, ma ancora potrebbe essere rilevante al 2008)

procedura di allarme per il lungo corso Job http://www.sqlservercentral.com/scripts/Lock+and+Connection+Management/30144/

testo qui sotto se non puoi accedervi

Per i lavori eseguiti periodicamente e che richiedono solo un breve periodo di tempo, un DBA potrebbe voler sapere quando il lavoro è stato eseguito per un tempo eccessivo. In questo caso, solo il controllo per vedere se il lavoro è in esecuzione non lo farà; è necessaria la capacità di assicurarsi che non sia in esecuzione per un lungo periodo. La corrispondenza dell'id del lavoro con un id del processo in sysprocesses richiede una certa organizzazione dell'ID del lavoro per eseguire la corrispondenza. Questo script crea una stored procedure che accetterà il nome di un lavoro, il tempo massimo di esecuzione consentito e l'indirizzo e-mail da notificare. Utilizzerà quindi il nome del lavoro per ricodificare il numero del lavoro e controllare il sysprocesses (in base all'id del processo che fa parte del nome del programma) per determinare il tempo di esecuzione del lavoro, quindi avvisare se il tempo è scaduto. parametro "tempo consentito".

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

Verificherà le prestazioni del lavoro. Devo controllare ogni procedura memorizzata eseguita nel database (o nell'intero server). – muerte

0

È possibile eseguire il log delle query in esecuzione lenta utilizzando SQL Profiler, ma ciò non aiuta in particolare con un avviso. (Suppongo che tu possa accedere a un file o a una tabella di database e avere qualcos'altro "ascolta" e genera un avviso).

Nel caso in cui non si ha familiarità con SQL Profiler qui sono i passi:

è necessario eseguire SQL Profiler su qualcosa di diverso dal server stesso.

Inizia con il modello SQLProfilerTSQL_Duration

Impostare il filtro: durata: "Maggiore di" a 1000 (milliseonds)

Nei filtri è possibile limitare il database, Login, o simili, se necessario.

Negli eventi si può limitare ad appena sprocs (default include anche le istruzioni SQL)

+0

Sì, è un lavoro manuale e non automatizzato (nessun avviso). – muerte

+0

Farebbe qualcosa di simile a ServersAlive? potrebbe essere impostato per eseguire una query su una tabella di SQL Server per qualcosa come "Qualsiasi nuova voce di registro negli ultimi N minuti". ServersAlive può avvisare tramite SMTP, SMS, Pager, ecc. Www.woodstone.nu/salive Mi aspetto che SQL Agent possa fare qualcosa di simile. – Kristen

0

Se non siete alla ricerca di una soluzione gratuita, si può dare un'occhiata a SQL Sentry. Fa quello che chiedi e altro ancora.

2

Vorrei aggiungere alla risposta corretta di Mladen Prajdic e migliorare la risposta di kevchadders da SQL Server Central. La soluzione che propongo di seguito utilizza DBMail anziché SQLMail (che viene utilizzata dalla soluzione di SQLServerCentral tramite la chiamata xp_sendmail).In sostanza, SQLMail utilizza MAPI ed è più difficile da configurare e DBMail utilizza SMTP ed è più semplice da configurare. Ecco lo more information sulla differenza tra i due.

Non sono riuscito a far funzionare la soluzione di SQL Server Central in SQL 2005 e la soluzione riportata di seguito è stata testata solo durante l'installazione di SQL 2005 - YMMV in base alla versione.

In primo luogo, avrete bisogno di una nuova UDF, che si tradurrà l'ID del processo nel ID di processo per una JOIN:

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 

E poi lo sproc:

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 

Questo sproc può essere pianificato facilmente come un processo di SQL Server Agent o qualsiasi altro metodo necessario. Non intraprende alcuna azione se il lavoro non è in esecuzione o è in esecuzione all'interno di parametri specificati. Invia l'e-mail se il lavoro è stato eseguito più a lungo di quanto specificato.

ad es.

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

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

2

Si potrebbe utilizzare un software di monitoraggio come Nagios contare periodicamente il numero di query lente nel database.

Io personalmente uso la seguente query con l'eccellente PRTG. Ho impostato per inviarmi una e-mail ogni volta che ho più di 5 domande con un tempo di esecuzione maggiore di 3 secondi ciascuna, o quando la query più lenta richiede più di 10 secondi: DISCLAIMER

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; 

: si basa questa query su https://stackoverflow.com/a/820252/638040

Ora, se si desidera monitorare i tuoi stored procedure, poi basta usare sys.dm_exec_procedure_stats invece di sys.dm_exec_sql_text (rimuovere anche il campo creation_time dalla selezione e ottimizzare il SUBSTRING su st.text)