常見原因:會話執行不可中斷操作(網路 I/O、外部程式、長跑 PL/SQL)、PMON 清理延遲、分散式交易 Prepared 狀態待協調。
COL OBJECT_NAME FOR A30
COL MACHINE FOR A20
SELECT o.OBJECT_NAME, s.MACHINE, s.SID, s.SERIAL#
FROM V$LOCKED_OBJECT l
JOIN DBA_OBJECTS o ON o.OBJECT_ID = l.OBJECT_ID
JOIN V$SESSION s ON s.SID = l.SESSION_ID;
ALTER SYSTEM KILL SESSION 'sid,serial#';
批量產生指令(**人工核對後逐條執行**,嚴禁管道批量):
SELECT 'ALTER SYSTEM KILL SESSION ''' || s.SID || ',' || s.SERIAL# || ''';'
FROM V$LOCKED_OBJECT l
JOIN V$SESSION s ON s.SID = l.SESSION_ID;
SELECT p.SPID, s.OSUSER, s.PROGRAM
FROM V$SESSION s
JOIN V$PROCESS p ON p.ADDR = s.PADDR
WHERE s.SID = :target_sid;
| 平台 | 命令 | 權限 | 關鍵提醒 |
|---|---|---|---|
| Linux/Unix | kill -9 <SPID> | root / oracle | SPID = 進程 PID |
| Windows | orakill <ORACLE_SID> <SPID> | Administrator / ORA_DBA | SPID = 執行緒 ID,非 Task Manager PID |
範例:orakill ORCL 12345
CREATE OR REPLACE PROCEDURE kill_zombie_sessions(p_max_wait_sec IN NUMBER DEFAULT 300) AS
BEGIN
FOR r IN (
SELECT s.SID, s.SERIAL#, p.SPID
FROM V$SESSION s
JOIN V$PROCESS p ON p.ADDR = s.PADDR
WHERE s.STATUS = 'KILLED'
AND s.LAST_CALL_ET > p_max_wait_sec
AND s.TYPE != 'BACKGROUND' -- 保護核心背景進程
) LOOP
INSERT INTO kill_audit_log (sid, serial, spid, kill_time, action)
VALUES (r.SID, r.SERIAL#, r.SPID, SYSDATE, 'AUTO_KILL_ATTEMPT');
EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' || r.SID || ',' || r.SERIAL# || ''' IMMEDIATE';
DBMS_LOCK.SLEEP(10);
-- 此處不直接 OS kill,建議外部監控腳本讀取 audit_log 執行 orakill/kill -9
END LOOP;
COMMIT;
END;
/
風險控制**:
$ORACLE_HOME/network/admin/sqlnet.ora):
SQLNET.EXPIRE_TIME = 10 -- 分鐘,檢測死連接並主動清理
BEGIN
DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
plan => 'DAY_PLAN',
group_or_subplan => 'APP_GROUP',
max_idle_time => 1800, -- 30 分鐘閒置自動斷開
max_idle_blocker_time => 600 -- 阻塞他人時 10 分鐘
);
END;
/
ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = 'DAY_PLAN';
validationQuery=SELECT 1 FROM DUAL、testOnBorrow=true、minEvictableIdleTimeMillis、maxWait。DBMS_SCHEDULER、外部排程,避免佔用連接池長時間持有鎖。| 錯誤動作 | 後果 | 正確做法 |
|---|---|---|
直接 kill -9 未確認 SPID | 誤殺核心進程 → 資料庫 Crash | 必經 V$SESSION+V$PROCESS 確認 SPID |
| Windows 用 Task Manager PID | 殺錯執行緒、或殺不掉 | 必用 orakill SID SPID,SPID 來自 V$PROCESS |
| 批量管道執行 KILL SESSION | 誤殺關鍵會話、無審計 | 逐條人工核對、記錄審計 |
| 忽略分散式交易 Prepared 狀態 | 資料不一致、需人工干預 | 先查 DBA_2PC_PENDING,按協議提交/回滾 |
清除殭屍會話標準動作:**定位 → 優雅 KILL → 等待 PMON → OS 強殺 (orakill/kill -9)**。但**頻繁出現殭屍會話本身就是架構缺陷的症狀**。請優先落實 SQLNET.EXPIRE_TIME、Resource Manager 閒置清理、連接池驗證機制,從源頭杜絕「KILLED 卻不死」的會話。**DBA 的最高境界不是殺會話快,而是讓會話根本不需要被殺。**