Предупреждение SQL, когда хранимая процедура выполняется слишком долго - PullRequest
5 голосов
/ 23 февраля 2009

Я хотел бы настроить оповещение SQL Server 2008, чтобы уведомлять меня, когда какая-либо процедура выполняется в течение 1 секунды или дольше (просто пример).

Есть идеи?

EDIT:

Хорошо, кажется, это невозможно. Но для того, чтобы подтолкнуть вас в другом направлении, я знаю, что в основной базе данных есть таблицы статистики, которые содержат счетчики компиляции, количество вызовов и другую различную статистику. Могу ли я периодически запрашивать их, а затем как-нибудь сообщать об этом?

Ответы [ 6 ]

3 голосов
/ 23 февраля 2009

нет для этого нет уведомлений. вам придется настраивать трассировку и опрашивать ее время от времени.

2 голосов
/ 18 февраля 2014

Вы можете использовать программное обеспечение для мониторинга, такое как Nagios , чтобы периодически подсчитывать количество медленных запросов в вашей базе данных.

Я лично использую следующий запрос с превосходным PRTG . Я настроил его на отправку мне электронного письма каждый раз, когда у меня более 5 запросов со временем выполнения более 3 секунд каждый, или когда самый медленный запрос занимает более 10 секунд:

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 из выделения и настройте SUBSTRING на st.text)

2 голосов
/ 01 декабря 2011

Я хотел бы добавить к правильному ответу Младена Прайдика и улучшить ответ кевчеддеров из SQL Server Central. Решение, которое я предлагаю ниже, использует DBMail вместо SQLMail (который используется решением SQLServerCentral посредством вызова xp_sendmail). По сути, SQLMail использует MAPI и сложнее в настройке, а DBMail использует SMTP и проще в настройке. Вот дополнительная информация о разнице между ними.

Я не смог заставить решение SQL Server Central работать в SQL 2005, и приведенное ниже решение было протестировано только на моей установке SQL 2005 - YMMV на основе версии.

Во-первых, вам понадобится новый UDF, который переведет идентификатор задания в идентификатор процесса для 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

А потом спрок:

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

Это sproc может быть легко запланировано как задание агента SQL Server или любой другой необходимый метод. Он не предпринимает никаких действий, если задание не выполняется или выполняется в указанных параметрах. Он отправляет электронное письмо, если задание было выполнено дольше указанного.

, например

EXEC sp_check_job_running 'JobNameGoesHere', 5, 'admin@mycompany.com'

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

2 голосов
/ 23 февраля 2009

Если найдено это на sqlservercentral (вероятно, для более старой версии SQL Server, но все еще может иметь отношение к 2008)

Процедура оповещения для длительной работы http://www.sqlservercentral.com/scripts/Lock+and+Connection+Management/30144/

Текст ниже, если вы не можете получить к нему доступ.

Для заданий, которые запускаются периодически и для их выполнения требуется непродолжительное время, администратор БД может захотеть узнать, когда задание выполнялось слишком долго. В этом случае просто проверить, работает ли задание, не получится; необходима возможность убедиться, что он не работал долгое время. Сопоставление идентификатора задания с идентификатором процесса в sysprocesses требует некоторой реорганизации идентификатора задания для сопоставления. Этот сценарий создает хранимую процедуру, которая будет принимать имя задания, максимально допустимое время выполнения и адрес электронной почты для уведомления. Затем он будет использовать имя задания для изменения номера задания и проверки системных процессов (на основе идентификатора процесса, являющегося частью имени программы), чтобы определить количество времени выполнения задания, а затем предупредит, если это время истекло. параметр «время разрешено».

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'
0 голосов
/ 23 февраля 2009

Если вы не ищете бесплатное решение, вы можете взглянуть на SQL Sentry . Он делает то, что вы просите и многое другое.

0 голосов
/ 23 февраля 2009

Вы можете регистрировать медленно выполняющиеся запросы, используя SQL Profiler, но это не поможет вам, в частности, с предупреждением. (Я полагаю, вы могли бы войти в файл или таблицу базы данных, и что-то еще «прослушать» и выдать предупреждение).

Если вы не знакомы с SQL Profiler, выполните следующие действия:

Вы должны запускать SQL Profiler на чем-то отличном от самого сервера.

Начните с шаблона SQLProfilerTSQL_Duration

Установите фильтр: Длительность: «Больше чем» на 1000 (миллисекунды)

В фильтрах вы можете ограничить базу данных, логин и т. П. При необходимости.

В событиях вы можете ограничиться только SProcs (по умолчанию также включены операторы SQL)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...