業務報「應用卡住」,DBA 需在 30 秒內定位阻塞會話並釋放。本文提供生產級標準化查殺腳本,覆蓋鎖類型識別、阻塞鏈追蹤、安全殺會話、事務回滾預估。
COL blocking_sid FOR 99999
COL blocked_sid FOR 99999
COL lock_type FOR A20
COL mode_held FOR A12
COL mode_req FOR A12
COL sql_text FOR A80
SELECT
l1.sid AS blocking_sid,
s1.username AS blocker_user,
s1.machine AS blocker_machine,
s1.program AS blocker_program,
l1.type AS lock_type,
DECODE(l1.lmode, 0,'None',1,'Null',2,'Row-S (SS)',3,'Row-X (SX)',4,'Share',5,'S/Row-X (SSX)',6,'Exclusive',l1.lmode) AS mode_held,
l2.sid AS blocked_sid,
s2.username AS blocked_user,
s2.machine AS blocked_machine,
DECODE(l2.request, 0,'None',1,'Null',2,'Row-S (SS)',3,'Row-X (SX)',4,'Share',5,'S/Row-X (SSX)',6,'Exclusive',l2.request) AS mode_req,
sq.sql_text
FROM v$lock l1
JOIN v$session s1 ON l1.sid = s1.sid
JOIN v$lock l2 ON l1.id1 = l2.id1 AND l1.id2 = l2.id2
JOIN v$session s2 ON l2.sid = s2.sid
LEFT JOIN v$sql sq ON s2.sql_address = sq.address AND s2.sql_hash_value = sq.hash_value
WHERE l1.block = 1
AND l2.request > 0
AND l1.sid != l2.sid
ORDER BY l1.sid, l2.sid;
關鍵欄位解讀:
• BLOCKING_SID:持有鎖的會話(阻塞源)。
• BLOCKED_SID:等待鎖的會話(受害者)。
• LOCK_TYPE:TM (DML Enqueue)、TX (Transaction)、UL (User Lock)、DX (Distributed Transaction) 等。
• MODE_HELD/REQ:6=Exclusive (X) 最常見於行鎖衝突。
SELECT s.sid, s.serial#, s.username, s.schemaname, s.osuser, s.process, s.machine, s.terminal, s.logon_time, l.type
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
AND l.type IN ('TX','TM') -- 僅關注事務/DML 鎖
AND s.terminal = 'CHINA-C742905EE'; -- 可替換為 machine/osuser/program
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;IMMEDIATE 關鍵字(10g+)讓 PMON 立即回滾事務並釋放鎖,無需等待客戶端發現連接斷開。V$TRANSACTION 確認回滾完成。SELECT sid, start_time, used_ublk, used_urec FROM v$transaction WHERE used_ublk > 10000; 大事務殺掉回滾時間長,需權衡。BLOCKING_SID,被阻塞會話通常自動繼續。V$LOCK,若阻塞超過 5 分鐘且阻塞會話非核心批處理(可維護白名單表),自動 KILL SESSION IMMEDIATE 並發送企業微信/釘釘告警。TM 鎖模式 3/4/5/6 可能由未提交 DDL 或 LOCK TABLE 引起,殺會話前確認是否為維護窗口操作。-- 查詢被鎖會話(按終端過濾)
SELECT s.sid||','||s.serial#, s.username, s.machine, s.terminal, l.type
FROM v$session s, v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
AND s.terminal = 'CHINA-C742905EE';
-- 殺掉具體會話(假設查得 SID=383, SERIAL#=32773)
ALTER SYSTEM KILL SESSION '383,32773' IMMEDIATE;
建立「查鎖→評估→殺會話→驗證→記錄」標準化 SOP,納入值班手冊,讓初級 DBA 也能在壓力下精準、安全地處理鎖衝突事件。