Blockierungs- und Lock-Krise
Symptom
Abfragen hängen, 'lock wait timeout', viele Sessions warten, aber die CPU-Last ist niedrig.
1. Den Anfang der Blockierungskette finden (Root Blocker)
Ermittle, wer wen blockiert; der eigentliche Verursacher ist die Session, die selbst auf nichts wartet, andere aber warten lässt. Konzentriere dich auf die Session an der Spitze der Kette.
Oracle
SELECT blocking_session, sid, serial#, username, seconds_in_wait, sql_id FROM v$session WHERE blocking_session IS NOT NULL ORDER BY seconds_in_wait DESC;PostgreSQL
SELECT pid, usename, pg_blocking_pids(pid) blocked_by, state, query FROM pg_stat_activity WHERE cardinality(pg_blocking_pids(pid))>0;MySQL
SELECT waiting_pid, waiting_query, blocking_pid, blocking_query FROM sys.innodb_lock_waits;SQL Server
SELECT session_id, blocking_session_id, wait_type, wait_resource FROM sys.dm_exec_requests WHERE blocking_session_id<>0;MongoDB
db.currentOp({ waitingForLock: true })2. Verstehen, was der Root Blocker tut
Ist es eine offene, nicht committete Transaktion? Hat die Anwendung sie 'idle in transaction' hinterlassen? Ist es ein langer Batch? Verstehe, worum es sich handelt, bevor du blind beendest – vielleicht ist er gleich fertig.
Oracle
SELECT s.sid, s.prev_sql_id, t.start_time, t.used_ublk FROM v$transaction t JOIN v$session s ON t.ses_addr=s.saddr;PostgreSQL
SELECT pid, state, xact_start, now()-xact_start age, query FROM pg_stat_activity WHERE pid=<root_pid>;3. Entscheiden: warten, über die Anwendung lösen oder beenden
Ist er gleich fertig, warte. Kann die Anwendung committen/zurückrollen, löse das aus. Steht der Betrieb still, beende andernfalls den Root Blocker. Bedenke vor dem Beenden die Auswirkungen (Rollback-Dauer, Daten).
4. Root Blocker bei Bedarf beenden
Beende nur die Session an der Spitze der Kette; die darunter liegenden Sessions werden automatisch freigegeben.
Oracle
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;PostgreSQL
SELECT pg_terminate_backend(<root_pid>);MySQL
KILL <root_id>;SQL Server
KILL <root_session_id>;MongoDB
db.killOp(<opid>)5. Ursache beheben
Ein fehlender Index kann breite Sperren verursachen; die Anwendung hält Transaktionen eventuell zu lange offen; die Isolationsstufe ist vielleicht falsch. Lege Indizes an, verkürze Transaktionen, setze einen Timeout für 'idle in transaction' und wähle eine passende Isolationsstufe.