Ошибка взаимоблокировки не возвращает тупиковый SQL

13

Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

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

Я попытаюсь отладить сам тупик как отдельную проблему, так как это мой главный вопрос на данный момент.

Я использую SQL Server 2008 Standard Edition.

webnoob
источник
Вы можете перезапустить сервис? Если вы можете отказаться от службы, вы можете добавить флаг трассировки 1204 в параметры запуска, чтобы записать сведения о взаимоблокировке в журнал SQL Server. > 1204: Возвращает ресурсы и типы блокировок, участвующих в взаимоблокировке, а также текущую затронутую команду. >> Область применения: только для всего мира
Tevo D
1
Используйте менеджер конфигурации. В SQL Server Services щелкните правой кнопкой мыши и откройте свойства. Перейдите на вкладку «Дополнительно», параметры запуска. У вас будут записи для расположения файлов основной базы данных и тому подобное. Добавьте ;-T1204флаг трассировки для завершения и перезапустите службу.
Tevo D
4
Зачем перезапускать сервис? DBCC TRACEON (1204, -1)
Марк Стори-Смит
От msdn.microsoft.com/en-us/library/ms188396.aspx : Изменения поведения: В SQL Server 2000 простой DBCC TRACEON (1204) достаточно для включения отчетов о взаимоблокировках в журнал ошибок. В SQL Server 2008 этот флаг необходимо включить глобально, поскольку флаг уровня сеанса невидим для потока монитора взаимоблокировок.
Tevo D
2
@TevoD - -1параметр, DBCC TRACEONобозначающий глобальный.
Мартин Смит

Ответы:

25

Необходимые данные записываются в расширенную трассировку событий по умолчанию.

DECLARE @xml XML

SELECT @xml = target_data
FROM   sys.dm_xe_session_targets
       JOIN sys.dm_xe_sessions
         ON event_session_address = address
WHERE  name = 'system_health'
       AND target_name = 'ring_buffer'

SELECT   
             XEventData.XEvent.query('(data/value/deadlock)[1]')  AS DeadlockGraph,
             CAST(XEventData.XEvent.value('(data/value)[1]', 'varchar(max)') AS XML) AS DeadlockGraph,
              XEventData.XEvent.value('(./@timestamp)[1]', 'DATETIME2') AS [DateTime]
FROM   (SELECT @xml AS TargetData) AS Data
       CROSS APPLY 
       TargetData.nodes ('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData (XEvent) 
ORDER BY [DateTime] DESC

Хотя этого больше не будет, если вы перезапустили сервис -eg, чтобы применить флаг трассировки, или если буфер зациклился за это время.

Вы можете настроить собственную расширенную трассировку событий, в которой график взаимоблокировки сохраняется в целевом файле для постоянного энергонезависимого хранилища. Пример кода здесь . Лично я считаю, что XML-код тупика более удобен, чем вывод флага трассировки.

редактировать

  1. @MartinC указывает в комментариях, что на экземплярах SQL Server, которые не имеют всех обновлений, может возникнуть проблема с генерированием недопустимого XML. Исправление для этого - выполнить поиск, заменить и использовать CAST(REPLACE(REPLACE(XEventData.XEvent.value('(data/value)[1]', 'varchar(max)'), '<victim-list>', '<deadlock><victim-list>'), '<process-list>', '</victim-list><process-list>') AS XML) AS DeadlockGraphв SELECTсписке, как описано здесь .
  2. Уэйн Шеффилд опубликовал полезный скрипт измельчать тупиковый граф XML в табличный формат здесь .
Мартин Смит
источник
К сожалению, EE не фиксирует все тупики и, похоже, является ошибкой: connect.microsoft.com/SQLServer/feedback/details/754115/…
Мэтт
3

Общепринятый ответ не работает для меня последовательно. Известно, что кольцевой буфер отбрасывает события при определенных обстоятельствах.

ConnectItem

Проблемы кольцевого буфера

Файлы событий журнала system_health могут быть проанализированы (из этого ответа ):

with XmlDeadlockReports as
(
  select convert(xml, event_data) as EventData
  from sys.fn_xe_file_target_read_file(N'system_health*.xel', NULL, NULL, NULL)
  where substring(event_data, 1, 50) like '%"xml_deadlock_report"%'  
) 
select EventData.value('(event/@timestamp)[1]', 'datetime2(7)') as TimeStamp,
       EventData.query('event/data/value/deadlock') as XdlFile
  from XmlDeadlockReports
 order by TimeStamp desc

Поле XdlFile можно сохранить в файл .xdl и прочитать в SSMS. Протестировано в Sql Server 2012.

crokusek
источник