Deadlock-Fehler gibt die Deadlock-SQL nicht zurück

13

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

Ich erhalte diesen Fehler zufällig, wenn eine meiner Websites ausgelastet ist. Ich weiß ungefähr, auf welchen Tabellengruppen es sich befindet, aber nach meiner Erfahrung mit anderen Programmen erhalte ich normalerweise die SQL zurück, wenn der Deadlock auftritt. Gibt es eine Flagge, die ich einschalten sollte, damit dies geschehen kann?

Ich werde versuchen, den Deadlock selbst als separates Problem zu debuggen, da dies meine Hauptfrage ist.

Ich verwende SQL Server 2008 Standard Edition.

webnoob
quelle
Können Sie den Dienst neu starten? Wenn Sie den Dienst bouncen können, können Sie Ihren Startparametern das Ablaufverfolgungsflag 1204 hinzufügen, um die Details des Deadlocks im SQL Server-Protokoll zu protokollieren. > 1204: Gibt die an einem Deadlock beteiligten Ressourcen und Sperrentypen sowie den aktuellen betroffenen Befehl zurück.
>>
1
Verwenden Sie den Konfigurationsmanager. Klicken Sie mit der rechten Maustaste unter SQL Server-Dienste, und öffnen Sie Eigenschaften. Gehen Sie zur Registerkarte Erweitert, Startparameter. Sie haben Einträge für den Speicherort der Master-Datenbankdateien und dergleichen. Fügen Sie ;-T1204für das Ablaufverfolgungsflag hinzu, um den Dienst zu beenden und neu zu starten.
Tevo D
4
Warum den Dienst neu starten? DBCC TRACEON (1204, -1)
Mark Storey-Smith
Von msdn.microsoft.com/de-de/library/ms188396.aspx : Verhaltensänderungen: In SQL Server 2000 ist ein einfaches DBCC-TRACEON (1204) ausreichend, um Deadlock-Berichte im Fehlerprotokoll zu aktivieren. In SQL Server 2008 müssen Sie das Flag global aktivieren, da das Flag auf Sitzungsebene für den Deadlock-Monitor-Thread nicht sichtbar ist.
Tevo D
2
@TevoD - Der -1Parameter, der DBCC TRACEONglobal bezeichnet.
Martin Smith

Antworten:

25

Die von Ihnen benötigten Daten werden im erweiterten Standardereignis-Trace aufgezeichnet.

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

Es ist jedoch nicht mehr vorhanden, wenn Sie den Dienst neu gestartet haben, z. B. um ein Ablaufverfolgungsflag anzuwenden, oder wenn der Puffer zwischenzeitlich gewechselt ist.

Sie können eine eigene Ablaufverfolgung für erweiterte Ereignisse einrichten, in der das Deadlock-Diagramm in einem Dateiziel für einen dauerhaften nichtflüchtigen Speicher gespeichert wird. Beispielcode hier . Ich persönlich finde das Deadlock-Diagramm XML freundlicher als die Ausgabe des Trace-Flags.

Bearbeiten

  1. @MartinC weist in den Kommentaren darauf hin, dass bei Instanzen von SQL Server, bei denen nicht alle Aktualisierungen vorhanden sind, möglicherweise ein Problem mit der Generierung von ungültigem XML vorliegt. Das Problem lässt sich beheben, indem Sie wie hier beschrieben suchen, ersetzen und 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 DeadlockGraphin der SELECTListe verwenden .
  2. Wayne Sheffield hat ein nützliches Skript geschrieben , um den Deadlock Graph XML in tabellarischer Form zerkleinern hier .
Martin Smith
quelle
Leider erfasst EE nicht alle Deadlocks und scheint ein Fehler zu sein: connect.microsoft.com/SQLServer/feedback/details/754115/…
Matt
3

Die akzeptierte Antwort hat bei mir nicht durchgehend funktioniert. Es ist anscheinend bekannt, dass der Ringpuffer Ereignisse unter bestimmten Umständen löscht.

ConnectItem

Probleme mit dem Ringpuffer

Die Ereignisdateien des system_health-Protokolls können analysiert werden (anhand dieser Antwort ):

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

Das XdlFile-Feld kann in einer .xdl-Datei gespeichert und in SSMS eingelesen werden. Getestet in SQL Server 2012.

crokusek
quelle