Uygulama "bir şey yavaş" diyor, ama CPU boş, disk boş. Klasik tablo: bir session bir satırı kilitledi, COMMIT atmadı, geri kalan herkes onun arkasında bekliyor. Oracle'da bu zinciri bulmak için üçüncü parti araca gerek yok — v$session sana kimin kimi beklettiğini doğrudan söyler.
blocking_session: kim engelliyor?
v$session içindeki blocking_session kolonu, bir session'ı bekleten session'ın SID'sini verir. Bekleyenleri ve engelleyeni tek sorguda çıkar:
SELECT s.sid,
s.serial#,
s.username,
s.status,
s.blocking_session AS engelleyen_sid,
s.event AS bekleme_olayi,
s.seconds_in_wait AS bekleme_sn
FROM v$session s
WHERE s.blocking_session IS NOT NULL
ORDER BY s.seconds_in_wait DESC;
event genelde enq: TX - row lock contention olur — satır kilidi. engelleyen_sid ise topun kimde olduğunu söyler.
Engelleyen ne yapıyor?
Engelleyen SID'yi bulduktan sonra onun çalıştırdığı (ya da son çalıştırdığı) SQL'e bak — çoğu zaman "commit unutulmuş bir transaction" ya da "elle açık kalmış bir oturum" çıkar:
SELECT s.sid, s.serial#, s.username, s.machine, s.program,
q.sql_text
FROM v$session s
LEFT JOIN v$sql q ON q.sql_id = s.prev_sql_id
WHERE s.sid = &engelleyen_sid;
Kilit zincirini ağaç halinde görmek istersen v$lock yerine hazır görünüm dba_blockers / dba_waiters de vardır; ama blocking_session çoğu vakayı tek sorguda çözer.
Engelleyen session'ı ALTER SYSTEM KILL SESSION 'sid,serial#' ile öldürmek, o session'ın açık transaction'ını geri alır (rollback) — dakikalarca sürebilir ve iş kaybına yol açabilir. Öldürmeden önce kök nedeni anla: uygulama commit'i mi unutuyor, bir batch mi uzun tutuyor, yoksa biri SQL Developer'da SELECT ... FOR UPDATE açıp öğle yemeğine mi gitti? Kör "kill" semptomu susturur, sebebi değil.
RAC'taysan: gv$ kullan
Tek instance'ta v$session yeter. Real Application Clusters'ta kilit başka bir node'daki session'dan gelebilir; o yüzden global görünümleri kullan:
SELECT inst_id, sid, serial#, blocking_session, blocking_instance, event
FROM gv$session
WHERE blocking_session IS NOT NULL;
Hızlı karar tablosu
| Belirti | Bak | Anlamı |
|---|---|---|
| Sorgular bekliyor, CPU boş | v$session.blocking_session | Satır/tablo kilidi zinciri |
| event = enq: TX - row lock | Engelleyenin prev_sql_id'si | Commit'siz bir transaction |
| Çok node (RAC) | gv$session + blocking_instance | Kilit başka instance'ta |
| Engelleyen INACTIVE | Uygulama/pool bağlantısı | Açık kalmış oturum, commit yok |
Özet
Oracle'da "bir şey kilitli" belirsizliğini v$session.blocking_session netleştirir: bekleyenleri listele, engelleyeni bul, onun son SQL'ine bak. Neredeyse her zaman kök neden commit unutan bir transaction ya da elle açık kalmış bir oturumdur. Session'ı öldürmeden önce sebebi anla — rollback maliyeti gerçek. RAC'ta gv$session'a geçmeyi unutma.