DBAtlas · Atlas für Datenbankbetrieb

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.

In DBAtlas öffnen →