Alerta SQL quando armazenado executa procedimento por muito tempo
-
05-09-2019 - |
Pergunta
Gostaria de configurar um alerta SQL Server 2008 para notificar-me quando nenhum executa procedimentos para 1 segundo ou mais (apenas um exemplo).
Todas as idéias?
EDIT:
Ok, parece que este não é possível. Mas, só para cutucá-los em outra direção, eu sei que há estatísticas tabelas no banco de dados mestre que mantêm a contagem de compilação, o número de chamadas e outras várias estatísticas. Eu poderia talvez periodicamente consultá-los e, em seguida, relatórios sobre ele, de alguma forma?
Solução
Não Não há notificações para isso. você terá que configurar um traço e tosquia-lo de vez em quando.
Outras dicas
Eu gostaria de adicionar à resposta correta do Mladen Prajdic e melhorar a resposta kevchadders do SQL Server Central. A solução que proponho abaixo usa dbmail vez de SQLMail (que é usado pela solução da SQLServerCentral por meio da chamada xp_sendmail). Essencialmente, SQLMail usa MAPI e é mais difícil de configurar e dbmail usa SMTP e é mais fácil de configurar. Aqui está mais informações sobre a diferença entre os dois.
Eu não poderia obter a solução da SQL Server Central para o trabalho no SQL 2005 e a solução abaixo só foi testado em minha instalação do SQL 2005 -. YMMV baseado na versão
Primeiro, você precisa de um novo UDF, que vai traduzir o ID de trabalho para o ID de processo para um 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 então o 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
Esta sproc pode ser facilmente programado como um trabalho SQL Server Agent ou qualquer outro método necessário. Ele não toma nenhuma providência se o trabalho não está em execução ou ele está sendo executado dentro de parâmetros especificados. Ele envia o e-mail se o trabalho foi executado mais do que o especificado.
por exemplo.
EXEC sp_check_job_running 'JobNameGoesHere', 5, 'admin@mycompany.com'
HT: http: //www.sqlserverspecialists. co.uk/blog/_archives/2008/11/26/3996346.html
Se achei essa mensagem em sqlservercentral (provavelmente para uma versão anterior do SQL Server, mas ainda pode ser relevante a 2008)
Procedimento de alerta para Long-execução Job http://www.sqlservercentral.com/scripts/Lock+and + Conexão + Gestão / 30144 /
O texto abaixo se você não pode acessá-lo.
Para os trabalhos que são executados periodicamente e deve levar apenas um curto período de tempo para ser executado, um DBA pode querer saber quando o trabalho foi executado por um tempo excessivo. Neste caso, basta verificar se o trabalho está sendo executado não vai fazer; é necessária a capacidade para se certificar de que não foi executado por um longo período. Igualando o ID de trabalho para a identificação do processo em sysprocesses requer algum re-arranjando da ID de trabalho para fazer o jogo. Este script cria um procedimento armazenado que aceita um nome de trabalho, tempo de execução máximo permitido, e endereço de e-mail para notificar. Será, então, usar o nome do trabalho de re-Cadeia O número e verificação sysprocesses de trabalho (com base na identificação do processo de fazer parte do nome do programa) para determinar a quantidade de tempo que o trabalho foi runing, então alerta se que o tempo é sobre o "tempo permitido" parâmetro.
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,
'DBAdmin@mycompany.com'
Você pode usar um software de monitoramento como Nagios contar periodicamente o número de consultas lentas em seu banco de dados.
Eu, pessoalmente usar a seguinte consulta com o excelente PRTG . Eu defini-lo para me enviar um e-mail cada vez que eu tiver mais de 5 consultas com um maior tempo de execução de 3 segundos cada um, ou quando a consulta mais lento demora mais do que 10 segundos:
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;
Disclaimer: esta consulta é baseada em https://stackoverflow.com/a/820252/638040
Agora, se você deseja monitorar os procedimentos armazenados, então é só usar sys.dm_exec_procedure_stats
vez de sys.dm_exec_sql_text
(também remover o creation_time
campo da seleção e ajustar o SUBSTRING em st.text
)
Você pode fazer logon lenta a execução de consultas usar o SQL Profiler, mas isso não vai ajudá-lo com um alerta, especificamente. (Eu suponho que você poderia registrar em um arquivo ou a uma tabela de banco de dados, e tem algo mais "ouvir" e levantar um alerta).
No caso de você não estiver familiarizado com SQL Profiler aqui estão os passos:
Você deve executar SQL Profiler em algo diferente do que o próprio servidor.
Comece com o SQLProfilerTSQL_Duration template
Defina o filtro: Duração: "Maior que" para 1000 (milliseonds)
Nos filtros que você pode restringir o Banco de Dados, Login, ou similar, se necessário.
Nos eventos você pode restringir a apenas Sprocs (padrão também inclui instruções SQL)
Se você não está procurando uma solução gratuita, você poderia dar uma olhada SQL Sentry . Ele faz o que você pedir e muito mais.