DBAtlas · Veritabanı operasyon atlası

Bloklama & lock krizi

Belirti

Sorgular takılı kalıyor, 'lock wait timeout', birçok oturum bekliyor ama CPU düşük.

1. Bloklama zincirinin başını (root blocker) bul

Kimin kimi bloklağını çıkar; asıl suçlu, kendisi hiçbir şey beklemeyen ama başkalarını bekleten oturumdur. Zincirin en tepesindeki oturuma odaklan.

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. Root blocker ne yapıyor anla

Açık ama commit edilmemiş bir transaction mı? Uygulama 'idle in transaction' durumunda mı bıraktı? Uzun bir batch mi? Kör kill etmeden önce ne olduğunu anla — belki bitmek üzeredir.

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. Karar: bekle, uygulamadan çöz, ya da kill

Bitmek üzereyse bekle. Uygulama commit/rollback yapabilecekse onu tetikle. Aksi halde ve iş duruyorsa root blocker'ı sonlandır. Kill etmeden önce etkisini (rollback süresi, veri) düşün.

4. Gerekirse root blocker'ı sonlandır

Yalnızca zincirin başındaki oturumu kill et; alttakiler otomatik serbest kalır.

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. Kök nedeni çöz

Eksik index geniş lock'lara yol açıyor olabilir; uygulama transaction'ları çok uzun tutuyor olabilir; yanlış izolasyon seviyesi. Index ekle, transaction'ları kısalt, 'idle in transaction timeout' ayarla, uygun izolasyon seç.

DBAtlas'ta aç →