2009-02-23 34 views
5

Me gustaría configurar una alerta de SQL Server 2008 para notificarme cuando un procedimiento se ejecuta durante 1 segundo o más (solo como ejemplo).Alerta SQL cuando el procedimiento almacenado se ejecuta durante demasiado tiempo

¿Alguna idea?

EDIT:

bien, parece que esto no es posible. Pero, para empujarlo en otra dirección, sé que hay tablas de estadísticas en la base de datos maestra que contienen recuentos de compilación, número de llamadas y otras estadísticas diversas. ¿Podría quizás consultarlos periódicamente y luego informar sobre ellos de alguna manera?

Respuesta

3

no, no hay notificaciones para esto. tendrá que configurar un seguimiento y sondearlo de vez en cuando.

+0

¿me puede dar un poco más detalles ? – muerte

2

Si se encuentra presente en sqlservercentral (probablemente de una versión anterior de SQL Server, pero aún podría ser relevante a 2008)

procedimiento de alerta de empleo de larga duración http://www.sqlservercentral.com/scripts/Lock+and+Connection+Management/30144/

texto a continuación si usted no puede acceder a él.

Para trabajos que se ejecutan periódicamente y que deben tomarse poco tiempo para ejecutarse, un DBA puede querer saber cuándo el trabajo ha estado funcionando durante un tiempo excesivo. En este caso, simplemente verificando si el trabajo se está ejecutando no funcionará; la capacidad de asegurarse de que no se ha estado ejecutando durante un período prolongado es necesaria. La coincidencia de la identificación del trabajo con una identificación del proceso en sysprocesses requiere una reorganización de la identificación del trabajo para hacer la coincidencia. Este script crea un procedimiento almacenado que aceptará un nombre de trabajo, el tiempo de ejecución máximo permitido y la dirección de correo electrónico para notificar. Luego usará el nombre del trabajo para volver a enhebrar el número del trabajo y verificar sysprocesses (basado en que el ID del proceso es parte del nombre del programa) para determinar la cantidad de tiempo que el trabajo ha estado ejecutándose y luego alertar si ese tiempo se ha terminado. parámetro "tiempo permitido".

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

Esto controlará el rendimiento laboral. Necesito verificar para cada procedimiento almacenado ejecutado en la base de datos (o el servidor entero). – muerte

0

Puede registrar consultas de ejecución lenta utilice el Analizador de SQL, pero eso no le ayudará con una alerta, específicamente. (Supongo que puede iniciar sesión en un archivo o en una tabla de base de datos, y hacer que otra cosa "escuche" y genere una alerta).

En caso de que no están familiarizados con el Analizador de SQL aquí están los pasos:

debería ejecutar SQL en algo más que el propio servidor.

de inicio con la plantilla SQLProfilerTSQL_Duration

Ajuste del filtro: Duración: "mayor que" a 1000 (milliseonds)

En los filtros que puede restringir la base de datos, inicio de sesión, o similares, si es necesario.

En los eventos se puede restringir a solo sprocs (por defecto también incluye sentencias SQL)

+0

Sí, eso es trabajo manual y no automático (sin alertas). – muerte

+0

¿Sería algo como ServersAlive? podría configurarse para ejecutar una consulta en una tabla de SQL Server para algo como "Cualquier nueva entrada de registro en los últimos N minutos". ServersAlive puede alertar mediante SMTP, SMS, buscapersonas, etc. www.woodstone.nu/salive Espero que SQL Agent pueda hacer algo similar. – Kristen

0

Si no está buscando una solución gratuita, se puede echar un vistazo a SQL Sentry. Hace lo que pide y más.

2

Me gustaría agregar a la respuesta correcta de Mladen Prajdic y mejorar la respuesta de kevchadders desde SQL Server Central. La solución que propongo a continuación utiliza DBMail en lugar de SQLMail (que es utilizada por la solución de SQLServerCentral a través de la llamada xp_sendmail).Esencialmente, SQLMail usa MAPI y es más difícil de configurar y DBMail usa SMTP y es más fácil de configurar. Aquí está more information sobre la diferencia entre los dos.

no pude conseguir la solución de SQL Server central para trabajar en SQL 2005 y la solución a continuación sólo se ha probado en mi instalación de SQL 2005 - Tu caso es distinto dependiendo de la versión.

En primer lugar, se necesita un nuevo UDF, lo que se traducirá el ID de trabajo en el identificador de proceso para una combinación:

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 

Y entonces el 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 

Esto puede sproc se puede programar fácilmente como un trabajo del Agente SQL Server o cualquier otro método necesario. No requiere ninguna acción si el trabajo no se está ejecutando o si se está ejecutando dentro de los parámetros especificados. Envía el correo electrónico si el trabajo se ha ejecutado más de lo especificado.

p. Ej.

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

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

2

Se puede usar un software de monitoreo como Nagios periódicamente para contar el número de consultas lentas en su base de datos.

Yo personalmente uso la siguiente consulta con el excelente PRTG. Me puse a enviar un correo electrónico cada vez que tengo más de 5 consultas con un plazo de ejecución superior a 3 segundos, o cuando la consulta más lento tarda más de 10 segundos cada uno:

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; 

responsabilidad: esta consulta se basa en https://stackoverflow.com/a/820252/638040

Ahora bien, si desea supervisar los procedimientos almacenados, a continuación, sólo tiene que utilizar sys.dm_exec_procedure_stats en lugar de sys.dm_exec_sql_text (también eliminar el campo creation_time de la selección y ajustar la subcadena en st.text)

Cuestiones relacionadas