DBAtlas · Database operations atlas

Blocking & lock crisis

Symptom

Queries hang, 'lock wait timeout', many sessions waiting but CPU is low.

1. Find the head of the blocking chain (root blocker)

Work out who is blocking whom; the real culprit is the session that waits on nothing itself but makes others wait. Focus on the session at the top of the chain.

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. Understand what the root blocker is doing

Is it an open but uncommitted transaction? Did the application leave it 'idle in transaction'? Is it a long batch? Understand what it is before killing it blindly — it may be about to finish.

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. Decide: wait, resolve from the application, or kill

If it is about to finish, wait. If the application can commit/roll back, trigger that. Otherwise, if business is stalled, terminate the root blocker. Before killing, consider the impact (rollback time, data).

4. Terminate the root blocker if necessary

Kill only the session at the head of the chain; the sessions below it are released automatically.

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. Fix the root cause

A missing index may cause wide locks; the application may hold transactions open too long; the isolation level may be wrong. Add indexes, shorten transactions, set an 'idle in transaction' timeout and choose an appropriate isolation level.

Open in DBAtlas →