Erro de deadlock não está retornando o SQL de deadlock

13

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

Estou recebendo esse erro aleatoriamente quando um dos meus sites fica ocupado. Eu sei aproximadamente em quais conjuntos de tabelas está acontecendo, mas na minha experiência com outros programas, normalmente recebo o SQL retornado onde o impasse está acontecendo. Existe uma bandeira que eu devo ativar para permitir que isso aconteça?

Vou tentar depurar o impasse em si como um problema separado, pois esta é a minha principal questão por enquanto.

Estou usando o SQL Server 2008 Standard Edition.

webnoob
fonte
Você é capaz de reiniciar o serviço? Se você conseguir devolver o serviço, poderá adicionar o sinalizador de rastreamento 1204 aos parâmetros de inicialização para registrar os detalhes do conflito no log do SQL Server. > 1204: Retorna os recursos e tipos de bloqueios que participam de um conflito e também o comando atual afetado. >> Escopo: somente global
Tevo D 13/01/12
1
Use o gerenciador de configuração. Em Serviços do SQL Server, clique com o botão direito do mouse e abra propriedades. Vá para a guia Avançado, parâmetros de inicialização. Você terá entradas para a localização dos arquivos do banco de dados mestre e outros. Inclua ;-T1204o sinalizador de rastreamento para finalizar e reiniciar o serviço.
precisa saber é
4
Por que reiniciar o serviço? DBCC TRACEON (1204, -1)
Mark Storey-Smith
De msdn.microsoft.com/en-us/library/ms188396.aspx : Alterações de comportamento: No SQL Server 2000, um simples DBCC TRACEON (1204) é suficiente para permitir relatórios de deadlock no log de erros. No SQL Server 2008, você deve habilitar o sinalizador globalmente porque o sinalizador no nível da sessão não está visível para o encadeamento do monitor de conflito.
Tevo D
2
@TevoD - O -1parâmetro para DBCC TRACEONsignifica global.
Martin Smith

Respostas:

25

Os dados necessários são registrados no rastreamento padrão de eventos estendidos.

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

Embora não exista mais se você tiver reiniciado o serviço -eg para aplicar um sinalizador de rastreamento ou se o buffer tiver alternado enquanto isso.

Você pode configurar seu próprio rastreamento de eventos estendidos que armazena o gráfico de deadlock em um destino de arquivo para armazenamento não volátil persistente. Exemplo de código aqui . Pessoalmente, acho o XML do gráfico de conflito mais amigável do que a saída do sinalizador de rastreamento.

Editar

  1. O @MartinC aponta nos comentários que, nas instâncias do SQL Server que não possuem todas as atualizações, pode haver um problema com a geração de XML inválido. A correção para isso é fazer alguma pesquisa, substituição e uso 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 DeadlockGraphna SELECTlista, conforme descrito aqui .
  2. Wayne Sheffield postou um script útil para destruir o XML do gráfico de deadlock em formato tabular aqui .
Martin Smith
fonte
Infelizmente, EE não captura todos os impasses e parece ser um erro: connect.microsoft.com/SQLServer/feedback/details/754115/...
Matt
3

A resposta aceita não funcionou para mim consistentemente. O buffer de anel aparentemente é conhecido por descartar eventos em determinadas circunstâncias.

ConnectItem

Problemas do buffer de anel

Os arquivos de eventos de log system_health podem ser analisados ​​(a partir desta resposta ):

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

O campo XdlFile pode ser salvo em um arquivo .xdl e lido no SSMS. Testado no Sql Server 2012.

crokusek
fonte