基礎會話查詢
-- 所有會話核心信息
SELECT sid, serial#, username, machine, status, logon_time, program
FROM v$session
WHERE username IS NOT NULL
ORDER BY logon_time;
-- 統計各用戶/主機會話數
SELECT username, machine, COUNT(*) sessions
FROM v$session
GROUP BY username, machine
ORDER BY sessions DESC;
優雅終止:ALTER SYSTEM KILL SESSION
-- 單會話終止(立即生效,回滾未提交事務)
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
-- 示例:終止用戶PCNSH003的會話
SELECT sid, serial# FROM v$session WHERE username = 'PCNSH003';
-- 假設返回 369,1745
ALTER SYSTEM KILL SESSION '369,1745' IMMEDIATE;
注意:KILL SESSION只標記會話為「待終止」,需等待PMON進程清理。會話在再次發起請求前仍可見於V$SESSION(STATUS=KILLED)。
強力終止:OS層面殺進程(謹慎使用)
-- 1. 定位OS進程號(SPID)
SELECT p.spid
FROM v$session s, v$process p
WHERE p.addr = s.paddr
AND s.sid = 518
AND s.serial# = 41831;
-- 返回如 16782
-- 2. OS命令行殺進程
# Unix/Linux
kill -9 16782
# Windows (需PID對應)
taskkill /PID 16782 /F
風險:可能導致數據塊損壞、事務不一致、實例崩潰。僅在會話完全無響應且KILL SESSION無效時作為最後手段,事後建議執行DB_VERIFY檢查數據文件完整性。
批量終止存儲過程:按用戶名清理所有會話
CREATE OR REPLACE PROCEDURE kill_user_sessions(p_username IN VARCHAR2) AS
v_sql VARCHAR2(500);
v_count NUMBER := 0;
BEGIN
FOR r IN (SELECT sid, serial# FROM v$session WHERE username = UPPER(p_username)) LOOP
v_sql := 'ALTER SYSTEM KILL SESSION ''' || r.sid || ',' || r.serial# || ''' IMMEDIATE';
EXECUTE IMMEDIATE v_sql;
v_count := v_count + 1;
END LOOP;
IF v_count = 0 THEN
RAISE_APPLICATION_ERROR(-20001, 'User ' || p_username || ' has no active sessions.');
ELSE
DBMS_OUTPUT.PUT_LINE('Killed ' || v_count || ' session(s) for user ' || p_username);
END IF;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20002, 'Kill failed: ' || SQLERRM);
END;
/
-- 調用示例
EXEC kill_user_sessions('SCOTT');
實戰場景建議
| 場景 | 推薦方案 |
| 單用戶異常佔用資源 | KILL SESSION ... IMMEDIATE |
| 應用連接池洩漏導致大量INACTIVE會話 | 調用kill_user_sessions批量清理 |
| 會話卡死無響應(長事務、死鎖) | 先KILL SESSION,超時無效再OSkill -9 |
| 計劃性維護窗口清理所有業務會話 | 腳本循環KILL SESSION + 監控V$SESSION歸零 |