5

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

Любые идеи?

EDIT:

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

ответ

3

no нет никаких уведомлений. вам нужно будет настроить трассировку и опросить ее время от времени.

+0

Можете ли вы дать мне немного больше информации ? – muerte

2

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

Процедура оповещения для долгоиграющих Job http://www.sqlservercentral.com/scripts/Lock+and+Connection+Management/30144/

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

Для выполнения заданий, которые периодически выполняются, и для выполнения всего лишь короткого промежутка времени, администратор баз данных может захотеть узнать, когда работа была запущена слишком долго. В этом случае просто проверка, чтобы видеть, ЕСЛИ работа выполняется, не будет; необходимость в том, чтобы она не работала в течение длительного периода времени. Согласование идентификатора задания с идентификатором процесса в sysprocesses требует некоторой повторной настройки идентификатора задания для выполнения соответствия. Этот скрипт создает хранимую процедуру, которая будет принимать имя задания, максимальное допустимое время выполнения и адрес электронной почты для уведомления. Затем он будет использовать имя задания для повторного ввода номера задания и проверки 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, 
     '[email protected]' 
+0

Это позволит проверить эффективность работы. Мне нужно проверить каждую хранимую процедуру, выполняемую в базе данных (или всего сервера). – muerte

0

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

В случае, если вы не знакомы с SQL Profiler вот шаги:

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

Старт с шаблоном SQLProfilerTSQL_Duration

Установить фильтр: Продолжительность: «Больше чем» до 1000 (milliseonds)

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

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

+0

Да, это ручная работа, а не автоматическая (без предупреждений). – muerte

+0

Будет что-то вроде ServersAlive? он может быть настроен для запуска запроса к таблице SQL Server для чего-то типа «Любая новая запись в журнале за последние N минут». ServersAlive может сигнализировать SMTP, SMS, пейджер и т. Д. Www.woodstone.nu/salive Я ожидаю, что агент SQL может сделать что-то подобное. – Kristen

0

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

2

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

Я не мог получить решение 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 

И тогда 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 

Это sproc может легко планироваться как задание агента 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. Я поставил его, чтобы отправить мне по электронной почте каждый раз, когда у меня есть более чем 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)