L'errore di deadlock non restituisce il deadlock SQL


13

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

Ricevo questo errore in modo casuale quando uno dei miei siti Web è occupato. So più o meno su quali set di tabelle sta accadendo, ma nella mia esperienza con altri programmi di solito ottengo l'SQL restituito dove sta accadendo il deadlock. C'è una bandiera che dovrei attivare per consentire che ciò accada?

Proverò a eseguire il debug dello deadlock stesso come un problema separato poiché questa è la mia domanda principale per ora.

Sto usando SQL Server 2008 Standard Edition.


Sei in grado di riavviare il servizio? Se è possibile eseguire il bounce del servizio, è possibile aggiungere il flag di traccia 1204 ai parametri di avvio per registrare i dettagli del deadlock nel registro di SQL Server. > 1204: restituisce le risorse e i tipi di blocchi che partecipano a un deadlock e anche il comando corrente interessato. >> Ambito: solo globale
Tevo D

1
Usa il gestore della configurazione. In SQL Server Services, fare clic con il tasto destro e aprire le proprietà. Vai alla scheda Avanzate, parametri di avvio. Avrai voci per l'ubicazione dei file del database master e simili. Aggiungi ;-T1204per terminare il flag di traccia e riavviare il servizio.
Tevo D,

4
Perché riavviare il servizio? DBCC TRACEON (1204, -1)
Mark Storey-Smith

Da msdn.microsoft.com/en-us/library/ms188396.aspx : Modifiche al comportamento: in SQL Server 2000 è sufficiente un semplice DBCC TRACEON (1204) per abilitare la segnalazione di deadlock nel registro errori. In SQL Server 2008, è necessario abilitare il flag a livello globale perché il flag a livello di sessione non è visibile al thread di monitoraggio deadlock.
Tevo D,

2
@TevoD - Il -1parametro da DBCC TRACEONindicare globale.
Martin Smith,

Risposte:


25

I dati necessari sono registrati nella traccia predefinita degli eventi estesi.

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

Anche se non ci sarà più se hai riavviato il servizio -eg per applicare un flag di traccia o se nel frattempo il buffer è andato in bicicletta.

È possibile impostare la propria traccia degli eventi estesi che memorizza il grafico del deadlock in una destinazione file per l'archiviazione persistente non volatile. Codice di esempio qui . Personalmente trovo il grafico XML deadlock più amichevole dell'output del flag di traccia.

modificare

  1. @MartinC sottolinea nei commenti che su istanze di SQL Server che non hanno tutti gli aggiornamenti potrebbe esserci un problema con la generazione di XML non valido. La correzione per questo è di fare qualche ricerca e sostituzione e utilizzare 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 DeadlockGraphnella SELECTlista come descritto qui .
  2. Wayne Sheffield ha pubblicato un utile script per distruggere il grafico XML deadlock in formato tabulare qui .

Purtroppo, EE non cattura tutti i deadlock e sembra essere un bug: connect.microsoft.com/SQLServer/feedback/details/754115/…
Matt

3

La risposta accettata non ha funzionato per me in modo coerente. Apparentemente è noto che il buffer dell'anello rilascia eventi in determinate circostanze.

ConnectItem

Problemi di Ring Buffer

I file degli eventi del registro system_health possono essere analizzati (da questa risposta ):

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

Il campo XdlFile può essere salvato in un file .xdl e letto in SSMS. Testato in SQL Server 2012.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.