首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle KILL SESSION 深度研究:PADDR 變更、OS 層面強制終止與 PMON 清理機制

     編輯:Oracle 資料庫相關知識

基本語法與行為


ALTER SYSTEM KILL SESSION 'sid,serial#' [IMMEDIATE];
  • **標準模式**:Session 狀態標記 KILLED,**下一次資料庫呼叫 (Next Call)** 時終止、PMON 清理。
  • IMMEDIATE (10g+):立即中斷正在執行的 SQL、回滾交易、釋放鎖、PMON 同步清理,**不等待 Next Call**。

現象觀察:PADDR 變更與多 Session 合併


-- Kill 前
SID  SERIAL#  PADDR       USERNAME  STATUS
11   314      542B70E8    EYGLE     INACTIVE

-- Kill 後
SID  SERIAL#  PADDR       USERNAME  STATUS
11   314      542D6BD4    EYGLE     KILLED   -- PADDR 變更!

-- 再 Kill 另一 Session
SID  SERIAL#  PADDR       USERNAME  STATUS
14   397      542D6BD4    EQSP      KILLED   -- 同一 PADDR!
**關鍵發現**:被 Kill 的 Session **PADDR 被修改為同一虛擬地址**,導致 V$SESSION.PADDR = V$PROCESS.ADDR 關聯失效,**無法透過 V$PROCESS 找到 SPID** 進行 OS 層 Kill。

突破口:X$KSUPR 找回真實 Process Address


SELECT s.username, s.status,
       x.addr, x.ksllapsc, x.ksllapsn, x.ksllaspo, x.ksllid1r,
       DECODE(BITAND(x.ksuprflg,2),0,NULL,1) killed_flag
FROM   x$ksupr x, v$session s
WHERE  s.paddr(+) = x.addr
AND    BITAND(x.ksspaflg,1) != 0;

輸出中 KILLED_FLAG = 1 且 ADDR 為 **原始 Process Address** (如 542B70E8、542B7498)。

簡化查詢:找出被 Kill 但 Process 仍存活的進程


SELECT p.addr
FROM   v$process p
WHERE  p.pid != 1  -- 排除 PMON
MINUS
SELECT s.paddr
FROM   v$session s;
-- 結果即為被 Kill 但 OS Process 尚未退出的進程位址

完整 OS 層強制終止流程

  1. 取得上述 ADDR。
  2. 查 V$PROCESS 獲取 SPID (OS Process ID)。
  3. OS 層終止:
    • Linux/Unix: kill -9
    • Windows: orakill (Oracle 提供工具,避免 kill 整個 oracle.exe)

機制推測與 PMON 行為

  1. ALTER SYSTEM KILL SESSION → 修改 Session 狀態為 KILLED,**PADTR 指向共用虛擬地址** → Session 與 Process 邏輯解耦。
  2. Session 下次呼叫 (或 IMMEDIATE 立即) → 發現 KILLED 旗標 → **主動斷開與 Process 連結** → Process 變為「孤兒」。
  3. Process 嘗試繼續執行 → 捕獲中斷異常 → **主動退出** → **觸發 PMON 清理 Session 狀態、釋放鎖、回滾交易**。
  4. 若 Process 長時間不退出 (卡在 I/O、外部呼叫) → **OS Kill 強制終止** → PMON 偵測 Process 死亡 → **異常清理路徑**,速度較快。

最佳實踐建議

  1. 優先用 IMMEDIATE:ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; 縮短等待。
  2. 建立標準化 Kill 腳本:自動查詢 X$KSUPR → 取得 SPID → OS Kill → 記錄審計日誌。
  3. 監控 KILLED Session 堆積:
    
    SELECT COUNT(*) FROM v$session WHERE status = 'KILLED';
    -- > 10 立即告警,檢查 PMON 是否卡住
            
  4. 避免濫用 Kill:先嘗試應用層優雅關閉 (Connection Pool Close)、ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' POST_TRANSACTION 等待交易結束。

結語

KILL SESSION 只是**邏輯標記**,真正清理由 **PMON 非同步執行**。**PADDR 變更導致 V$SESSION-V$PROCESS 關聯斷裂**,需透過 X$KSUPR 或 V$PROCESS MINUS V$SESSION 反查真實 Process。生產環境請建立 **自動化 Kill+OS終止腳本**,並監控 KILLED 狀態堆積,防止 PMON 成為瓶頸。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved