DBAtlas · Atlas für Datenbankbetrieb

Deadlock-Analyse

Symptom

'deadlock detected', 'ORA-00060', 'chosen as deadlock victim' – Transaktionen sperren sich gegenseitig, und eine wird abgebrochen.

1. Deadlocks sind normal, sollten aber nicht häufig sein

Die DB erkennt den Deadlock und löst ihn, indem sie ein Opfer wählt – das ist so vorgesehen. Ziel ist, die Häufigkeit zu senken. Die Anwendung sollte die Opfertransaktion wiederholen. Erfasse zuerst den Deadlock-Graphen.

2. Deadlock-Graph/-Details abrufen

Welche zwei (oder mehr) Sessions, welche Ressourcen und welche Lock-Modi sind kollidiert?

Oracle

-- Check the trace file referenced in the alert log (deadlock graph). Also:
SELECT * FROM dba_hist_active_sess_history WHERE event LIKE 'enq: TX%' ORDER BY sample_time DESC;

PostgreSQL

-- log_lock_waits=on; deadlock details are in postgresql.log. Check the deadlock_timeout setting.

MySQL

SHOW ENGINE INNODB STATUS\G  -- LATEST DETECTED DEADLOCK section

SQL Server

-- Deadlock XML in the system_health Extended Events session (ring_buffer, recent events):
SELECT x.ev.value('@timestamp','datetime2') AS event_time, x.ev.query('.') AS deadlock_xml
FROM (SELECT CAST(t.target_data AS XML) td FROM sys.dm_xe_session_targets t
      JOIN sys.dm_xe_sessions s ON s.address = t.event_session_address
      WHERE s.name = N'system_health' AND t.target_name = N'ring_buffer') r
CROSS APPLY r.td.nodes('//RingBufferTarget/event[@name="xml_deadlock_report"]') AS x(ev);
-- For longer history, the event_file target:
-- SELECT CAST(event_data AS XML) FROM sys.fn_xe_file_target_read_file(N'system_health*.xel', NULL, NULL, NULL) WHERE object_name = N'xml_deadlock_report';

3. Das Konfliktmuster auflösen

Häufigste Ursache: Zwei Transaktionen greifen in UMGEKEHRTER Reihenfolge auf Ressourcen zu. Greife in allen Codepfaden in DERSELBEN Reihenfolge auf Ressourcen zu. Zweithäufigste Ursache: breite Bereichssperren wegen eines fehlenden Index – lege den benötigten Index an.

4. Dauer und Umfang der Sperren verringern

Halte Transaktionen kurz (keine Benutzerinteraktion innerhalb einer Transaktion). Wähle eine passende Isolationsstufe. Setze bei Bedarf Zeilensperren frühzeitig (SELECT ... FOR UPDATE mit deterministischer Reihenfolge).

5. Retry in der Anwendung ist Pflicht

Deadlocks lassen sich nicht vollständig vermeiden; implementiere für die Opfertransaktion eine automatische Wiederholung (Exponential Backoff). So sieht der Benutzer keinen Fehler.

In DBAtlas öffnen →