用戶反饋「卡住不動」、「無法更新某行」、應用報ORA-00054: resource busy。核心任務:定位阻塞鏈 → 識別持有者/等待者 → 決策殺會話/等待提交。
-- 經典阻塞鏈查詢(含鎖模式、對象名、SQL文本)
SELECT
s.sid, s.serial#, s.username, s.status, s.logon_time,
l.type, l.lmode, l.request, l.id1, l.id2,
o.object_name, o.object_type,
sq.sql_text
FROM v$session s
JOIN v$lock l ON s.sid = l.sid
LEFT JOIN dba_objects o ON l.id1 = o.object_id
LEFT JOIN v$sql sq ON s.sql_id = sq.sql_id
WHERE l.request > 0 -- 等待者
OR (l.request = 0 AND l.lmode > 0 AND EXISTS (
SELECT 1 FROM v$lock l2 WHERE l2.id1 = l.id1 AND l2.id2 = l.id2 AND l2.request > 0
)) -- 持有者且被等待
ORDER BY s.logon_time;
-- 僅顯示被阻塞會話及阻塞者
SELECT
blocking.sid block_sid, blocking.serial# block_serial,
blocked.sid wait_sid, blocked.serial# wait_serial,
blocking.username block_user, blocked.username wait_user,
o.object_name, l.type, l.lmode, l.request
FROM v$lock l
JOIN v$session blocked ON l.sid = blocked.sid AND l.request > 0
JOIN v$lock l2 ON l.id1 = l2.id1 AND l.id2 = l2.id2 AND l2.request = 0
JOIN v$session blocking ON l2.sid = blocking.sid
LEFT JOIN dba_objects o ON l.id1 = o.object_id
WHERE l.type IN ('TM','TX','UL');
| LMODE/REQUEST | 名稱 | 含義 | 典型場景 |
|---|---|---|---|
| 0 | None | 無鎖 | - |
| 1 | Null | 空鎖,僅標識關注 | DDL解析階段 |
| 2 | Row-S (SS) | 行共享 | SELECT FOR UPDATE, LOCK ROW SHARE |
| 3 | Row-X (SX) | 行排他 | INSERT/UPDATE/DELETE(最常見) |
| 4 | Share (S) | 共享 | LOCK TABLE ... IN SHARE MODE, 索引創建 |
| 5 | S/Row-X (SSX) | 共享行排他 | LOCK TABLE ... IN SHARE ROW EXCLUSIVE |
| 6 | Exclusive (X) | 排他 | DROP TABLE, ALTER TABLE, LOCK TABLE ... EXCLUSIVE |
ALTER SYSTEM KILL SESSION 'sid,serial#'; → 標記為KILLED,會話下次檢查點退出,事務回滾。ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; → 立即回滾並釋放資源,PMON清理。kill -9 spid(從V$PROCESS.SPID獲取)→ 實例可能崩潰,需實例恢復,**嚴禁常規使用**。-- 1. 發現阻塞
SELECT * FROM v$session WHERE blocking_session IS NOT NULL;
-- 2. 定位持有者
SELECT sid, serial#, username, sql_id, blocking_session
FROM v$session WHERE sid = 146; -- 假設阻塞者SID=146
-- 3. 優雅殺會話
ALTER SYSTEM KILL SESSION '146,21177';
-- 4. 驗證釋放
SELECT * FROM v$lock WHERE request > 0; -- 應無記錄
NULL AND FALSE -> FALSE
NULL AND TRUE -> NULL
NULL OR FALSE -> NULL
NULL OR TRUE -> TRUE
SELECT SUM(sal) FROM emp; -- NULL不參與計算
-- 排序時 NULL 最大(ASC最後,DESC最前),且無法建立B*Tree索引
MERGE INTO target t
USING source s ON (t.id = s.id)
WHEN MATCHED THEN UPDATE SET t.val = s.val
DELETE WHERE (s.flag = 'D') -- 10g新增:匹配後再過濾刪除
WHEN NOT MATCHED THEN INSERT (id, val) VALUES (s.id, s.val);
WITH dept_cost AS (
SELECT dname, SUM(sal) dept_total
FROM emp e JOIN dept d ON e.deptno = d.deptno
GROUP BY dname
)
SELECT dname, dept_total
FROM dept_cost
WHERE dept_total > (SELECT SUM(dept_total)/3 FROM dept_cost);
CREATE GLOBAL TEMPORARY TABLE temp_session (
id NUMBER, data VARCHAR2(100)
) ON COMMIT PRESERVE ROWS; -- 會話級保留
-- 或 ON COMMIT DELETE ROWS; -- 事務級保留
-- 特性:結構持久,數據隔離,提交/結束自動清理,統計信息共享(12c+可私有)
NVL(expr1, expr2) -- expr1為NULL返回expr2,否則expr1
NVL2(expr1, e2, e3) -- expr1非NULL返回e2,NULL返回e3
NULLIF(expr1, expr2) -- 相等返回NULL,不等返回expr1
鎖定排查核心:V$LOCK + V$SESSION + DBA_OBJECTS 三表聯查。Kill Session首選IMMEDIATE避免長時間回滾阻塞其他會話。建立「阻塞告警 → 自動收集現場 → 人工決策 → 執行Kill → 驗證恢復」標準化流程,將MTTR壓縮至分鐘級。