生產環境常遇到 ALTER SYSTEM KILL SESSION 標記為 "KILLED" 但進程長時間不釋放鎖、不退出的殭屍進程。本文提供四步驟標準處理流程:識別鎖定對象 → SQL 層面 Kill → 驗證殘留 → OS 層面強制終止 (Linux kill -9 / Windows orakill),並附自動化腳本與風險控管建議。
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 l.object_id = o.object_id
JOIN v$session s ON l.session_id = s.sid;
輸出範例:
OBJECT_NAME MACHINE SID SERIAL#
-------------- ---------------- ---- -------
ORDERS APP-SERVER-01 42 21993
ORDER_ITEMS APP-SERVER-01 42 21993
ALTER SYSTEM KILL SESSION '42,21993';
狀態變為 KILLED,但進程可能因回滾大事務、等待 I/O、持有鎖等原因延遲退出。
SELECT 'ALTER SYSTEM KILL SESSION ''' || s.sid || ',' || s.serial# || ''';'
FROM v$locked_object l
JOIN dba_objects o ON l.object_id = o.object_id
JOIN v$session s ON l.session_id = s.sid;
若過段時間 (建議 5-10 分鐘) 進程仍存活,查詢對應 OS 執行緒:
SELECT p.spid, s.osuser, s.program
FROM v$session s
JOIN v$process p ON s.paddr = p.addr
WHERE s.sid = 42; -- 步驟 1 取得的 SID
輸出:SPID=12345, OSUSER=oracle, PROGRAM=oracle@db01 (TNS V1-V3)
# kill -9 12345
風險:kill -9 不允許進程清理 (釋放共享記憶體段、關閉檔案描述符、通知 PMON),可能導致:
- 共享記憶體段殘留 (需 ipcrm 清理)
- PMON 需額外時間清理進程資源
- 極端情況下資料庫不穩定需重啟
C:\> orakill ORCL 12345
ORCL:Oracle 實例名 (SID)12345:步驟 3 取得的 SPID (Windows 執行緒 ID)orakill.exe 位於 %ORACLE_HOME%\bin\優勢:orakill 通知 Oracle 內部結構清理,比純粹 TerminateThread 安全。
CREATE OR REPLACE PROCEDURE force_kill_locked_sessions AS
v_spid VARCHAR2(20);
v_cmd VARCHAR2(500);
BEGIN
FOR r IN (
SELECT s.sid, s.serial#, p.spid
FROM v$locked_object l
JOIN dba_objects o ON l.object_id = o.object_id
JOIN v$session s ON l.session_id = s.sid
JOIN v$process p ON s.paddr = p.addr
) LOOP
-- 1. SQL Kill
EXECUTE IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' || r.sid || ',' || r.serial# || '''';
-- 2. 等待 30 秒
DBMS_LOCK.SLEEP(30);
-- 3. 檢查是否仍存在
BEGIN
SELECT 1 INTO v_spid FROM v$session WHERE sid = r.sid;
-- 仍存在 → OS Kill
IF SYS_CONTEXT('USERENV', 'SERVER_HOST') LIKE '%Windows%' THEN
v_cmd := 'orakill ' || SYS_CONTEXT('USERENV', 'INSTANCE_NAME') || ' ' || r.spid;
ELSE
v_cmd := 'kill -9 ' || r.spid;
END IF;
-- 需外部程式執行 (DBMS_SCHEDULER 外部作業或 Java Stored Procedure)
-- 此處略過實際執行,僅記錄
INSERT INTO kill_audit (sid, serial, spid, action, cmd, ts)
VALUES (r.sid, r.serial#, r.spid, 'OS_KILL', v_cmd, SYSTIMESTAMP);
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL; -- 已正常退出
END;
END LOOP;
COMMIT;
END;
| 風險 | 緩解措施 |
|---|---|
| 誤殺正常進程 | 雙人複核 SID/SPID、記錄審計日誌、限制執行權限 |
| 資料庫不穩定 | 優先等待 PMON 清理、僅在業務受阻不可接受時執行 OS Kill |
| 共享記憶體殘留 | 事後檢查 ipcs -m、必要時 ipcrm |
| 資料不一致 | 殺掉進程等同強制回滾,確認應用有重試/冪等機制 |
V$TRANSACTION + V$SESSION_LONGOPS 告警DBMS_RESOURCE_MANAGER 限制會話 CPU/IO/執行時間STATUS='KILLED' 超過閾值的 Session「Kill Session 不死」是 Oracle DBA 必經的修煉。標準流程:SQL Kill → 耐心等待回滾 → 確認 SPID → OS 層面精準打擊 (Linux kill -9 / Windows orakill)。核心原則:能等則等,必殺則精,事後必查。建立自動化巡檢與審計機制,將人工介入降至最低,才是成熟運維的標誌。