Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Средство мониторинга блокировок, как бы эффективней получить скрипт приведший к блокировке.  [new]
МуМу
Member

Откуда:
Сообщений: 1120
Вообщем реализовано у меня следующим образом. С периодичностью раз в 15 секунд сканируется сервер на предмет блокировок. Затем если есть заблокировавший процесс то запускается конструкция типа dbcc inputbuffer(63) с помощьюк которой получается скрипт приведший к блокировке.
Не нравится то что сканировать чаще не хочется с точки зрения производительности а с другой стороны инофрмацию(скрипты приведшие к блокировкам) по блокировкам нужна а так достоверную статистику можно будет собирать только по процессам которые блокируются не менее 15 сек(интервал сканирования)...

Есть другой подход. Я включаю трейс в который записываю как минимум T-SQL bath starting и т.п. плюс евенты класса Lock с фильтром по duration.
Потом просто парсю этот трейс приблизительно по следующему алгоритму - нахожу lock и иду по процессу(spid) выше него - самый первый скрипт это и есть тот скрипт который ожидет разблокировки ресурса. Но в это случае остается вопрос а как получить тот скрипт который заблокировал ресурсы?
Сложный парсинг писать практически нереально...


Вообщем вопроса несколько.

Как во втором подходе определить скрипт заблокировавший ресурс?(хотя может это и нафиг не нужно? Ведь по сути два скрипта блокирующие один и тот же ресурс будут блокировать друг друга независимо от порядка вызова а следовательно если предположить что вероятность вызова их одинакова и нет четкой хронологической последовательности в их вызове то мы между ними можем поставить знак равенства)

Какие есть минусы в первойц и второй реализации?

Какие вы посоветуете еще технологии?
6 окт 04, 13:02    [1012352]     Ответить | Цитировать Сообщить модератору
 Re: Средство мониторинга блокировок, как бы эффективней получить скрипт приведший к блокировке.  [new]
Mong
Guest
Если я правильно понял суть проблемы, то она именно в поиске ошибок в коде, приведшем к deadlock-у?

На боевой системе имхо лучше реализовать проверку на уровень выше.
Т.е. ловить и обрабатывать исключения, связанные с deadlock-ом в вызывающем коде. Подход не идеальный, но он по крайней мере не наносит вреда производительности.
15 окт 04, 12:58    [1036975]     Ответить | Цитировать Сообщить модератору
 Re: Средство мониторинга блокировок, как бы эффективней получить скрипт приведший к блокировке.  [new]
МуМу
Member

Откуда:
Сообщений: 1120
Не всегда есть возможность изменять код клиента.
15 окт 04, 12:59    [1036988]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Средство мониторинга блокировок, как бы эффективней получить скрипт приведший к блокировке.  [new]
Granata005
Member

Откуда:
Сообщений: 401
SELECT
CONVERT(char(12),master..sysprocesses.hostname),
CONVERT(char(12),master..sysprocesses.program_name), 
CONVERT(char(12),master..sysdatabases.NAME), 
COUNT(*)
FROM
master..syslockinfo, master..sysprocesses, master..sysdatabases
WHERE
master..syslockinfo.req_spid = master..sysprocesses.spid AND
master..syslockinfo.req_ownertype=1 AND
master..sysdatabases.dbid = master..syslockinfo.rsc_dbid AND
master..syslockinfo.rsc_dbid > 2
GROUP BY master..sysdatabases.NAME, master..sysprocesses.program_name, master..sysprocesses.hostname
1 ноя 07, 12:52    [4864625]     Ответить | Цитировать Сообщить модератору
 Re: Средство мониторинга блокировок, как бы эффективней получить скрипт приведший к блокировке.  [new]
Call
Member

Откуда: SFBA
Сообщений: 481
Запустите трэйс
Lock:Timeout 
Lock:Deadlock Chain
Lock:Deadlock
Которая записывает в таблицу на том же сервере. На таблицу повесте тригер на вставку. Тригер может вытаскивать SPID процессов участвкющих в блокировке из TextData и далее DBCC INPUTBUFFER пишет все что клинит в другую таблицу. Или же тригер опрашивает системные таблицы и инфу вставляет куда нужно. В этом случае ничего не пропукаем и куем железо не отходя от кассы.
1 ноя 07, 23:54    [4867935]     Ответить | Цитировать Сообщить модератору
 Re: Средство мониторинга блокировок, как бы эффективней получить скрипт приведший к блокировке.  [new]
Александр Гладченко
Member

Откуда:
Сообщений: 10716
Блог
Решение определяет цель :) Что в данном случае преследуется?

ИМХО, 15 сек - это дороговато, хотя может оказаться не так накладно, как трассировка но вот inputbuffer - это же чёрный ящик :(, лучше без него...

Если же нужно просто оценить, какие блокировки возникают и накопить некоторую статистику для разбора, хватает и поминутных запросов в задании по расписанию.
Например, когда возникают жалобы, я запускаю представленный ниже скрипт а результаты шлю себе на мыло:

SELECT	SPID  = CAST(p.spid AS nvarchar) + '|' + CAST(p.ecid AS nvarchar) + N' (' + RTRIM(LEFT(CAST(p.loginame AS nvarchar), 25)) + N')', 
		Blocked = CAST(p.blocked AS nvarchar) + ISNULL((SELECT TOP 1 N'|' + CAST(p1.ecid AS nvarchar) + N' (' + RTRIM(CAST(p1.loginame AS nvarchar)) + N')' FROM master..sysprocesses AS p1 WITH(NOLOCK) WHERE p1.spid = p.blocked),''), 
		Wait = CASE WHEN p.waittype = 0x THEN CAST ('-' AS nvarchar) ELSE CAST(p.lastwaittype AS nvarchar)END, WaitTime = CAST(p.waittime AS NVARCHAR),
		BlockedWait = RTRIM(ISNULL((SELECT TOP 1 CASE WHEN (p2.waittype = 0x OR p2.waittype IS NULL) THEN CAST ('0' AS nvarchar) ELSE CAST(ISNULL (p2.lastwaittype, '-') AS nvarchar) END AS Wait FROM master..sysprocesses AS p2 WITH(NOLOCK) WHERE p2.spid = p.blocked),'-')),
		WaitResource = CASE WHEN p.waitresource = '' OR p.waitresource IS NULL THEN N'-' ELSE RTRIM(CAST(p.waitresource AS nvarchar))END, 
		BlockedWaitResource = ISNULL((SELECT TOP 1 CASE WHEN p6.waitresource = '' OR p6.waitresource IS NULL THEN N'-' ELSE RTRIM(CAST(p6.waitresource AS nvarchar))END FROM master..sysprocesses AS p6 WITH(NOLOCK) WHERE p6.spid = p.blocked),'-'), 
		Command = CASE WHEN p.cmd = '' THEN N'-' ELSE RTRIM(CAST(p.cmd AS nvarchar))END,
		BlockedCommand = RTRIM(ISNULL((SELECT TOP 1 CASE WHEN p3.cmd = '' THEN N'NONE' ELSE RTRIM(CAST(p3.cmd AS nvarchar))END FROM master..sysprocesses AS p3 WITH(NOLOCK) WHERE p3.spid = p.blocked),'-')), 
		Status = RTRIM(ISNULL(CAST(p.status AS nvarchar),'-')),
		BlockedStatus = RTRIM(ISNULL((SELECT TOP 1 CAST(p4.status AS nvarchar) FROM master..sysprocesses AS p4 WITH(NOLOCK) WHERE p4.spid = p.blocked),'-')),
		Hostname = RTRIM(LEFT(p.hostname, 12)),
		BlockedHostname = RTRIM(ISNULL((SELECT TOP 1 CAST(p5.hostname AS nvarchar) FROM master..sysprocesses AS p5 WITH(NOLOCK) WHERE p5.spid = p.blocked),'-'))
FROM master..sysprocesses AS p WITH(NOLOCK)
WHERE p.waittime > 0
AND p.dbid = DB_ID()
--AND p.wait <> '0'
--AND p.wait NOT LIKE 'WRITELOG%'
--AND p.spid <> p.blocked
--AND p.spid > 50
--AND p.blocked <> 0
2 ноя 07, 10:17    [4868710]     Ответить | Цитировать Сообщить модератору
 Re: Средство мониторинга блокировок, как бы эффективней получить скрипт приведший к блокировке.  [new]
МуМу
Member

Откуда:
Сообщений: 1120
Много воды с тех пор утекло:) Теперь этот вопрос не актуален.
2 ноя 07, 12:38    [4869877]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить