前言
客户日常运维执行ALTER SYSTEM KILL SESSION ... IMMEDIATE强制终止会话后,遇到诡异现象:操作系统服务进程已经彻底消失,但gv$session中会话长期停留在KILLED状态:
滞留1 小时以上无法自动清理
一、问题处理
1. 定位 KILLED 僵尸会话
sql
SQL> select inst_id,sid,serial#,status,paddr from gv$session where sid=1052;
INST_ID SID SERIAL# STATUS PADDR
---------- ---------- ---------- -------- ----------------
2 1052 45193 KILLED 07000108A93FAFF0
查询该会话绑定的进程地址,v$process/gv$process均无匹配记录:
sql
SQL> select spid from gv$process where addr='07000108A93FAFF0';
no rows selected
核心特征:会话绑定的 OS 服务进程已消亡,仅会话元数据残留在 SGA。
2. 核查锁与事务资源
sql
-- 查询会话持有锁
SELECT inst_id,sid,type,lmode,request FROM gv$lock WHERE sid=1052 AND inst_id=2;
no rows selected
-- 查看事务指针TADDR
SELECT inst_id,sid,serial#,taddr FROM gv$session WHERE sid=1052 AND inst_id=2;
INST_ID SID SERIAL# TADDR
---------- ---------- ---------- ----------------
2 1052 45193
-
TADDR为空:当前会话无未提交本地事务,事务已全部回滚完成; -
gv$lock无记录:未持有任何对象锁、全局队列锁,无业务阻塞风险。
3. 执行跨实例强制断开命令
sql
ALTER SYSTEM DISCONNECT SESSION '1052,45193,@2' IMMEDIATE;
System altered.
命令执行成功,原有的KILLED会话已经清除;新连接会复用 SID=1052,生成全新SERIAL#与进程地址PADDR,极易被误判为会话复活:
sql
INST_ID SID SERIAL# STATUS PADDR
---------- ---------- ---------- -------- ----------------
2 1052 45195 INACTIVE 07000108F91C0038
1 1052 64521 INACTIVE 07000108B921E110
说明:新旧 SID 相同,但进程、事务上下文完全独立,不存在复活逻辑。
二、KILLED 会话不会即时清除的根本原因
-
KILL SESSION / DISCONNECT SESSION IMMEDIATE仅做状态标记 ,不会同步删除gv$session内存记录; -
事务回滚、锁释放、PGA 内存回收、会话条目删除全部由后台
PMON进程异步周期性执行; -
正常场景:PMON 数秒~数十秒完成清理,会话自动消失;
-
判断异常:如果超过 1 小时仍残留 KILLED 会话,不属于正常延迟,存在资源阻塞、内存异常或分布式事务分支未清理问题。
三、KILLED 会话 1 小时以上无法清理的原因
1. 分布式 / XA 全局事务多分支阻塞(MOS KB151805 核心根因)
这是 Oracle 官方文档明确收录的高频故障场景,OS 进程消失、数据库会话长期 KILLED的现象。

MOS 文档原文核心逻辑
-
使用 DBLINK、JTA XA 分布式事务时,一个全局事务会拆分多条分支会话;
-
事务资源归属全局事务本身,而非单条会话;仅 Kill 其中一条分支,无法释放全局事务资源;
-
只要同一全局事务下其余分支会话仍存活(INACTIVE/KILLED),PMON 不会彻底清理已被杀分支;
-
即便 OS 层
kill -9强制销毁服务进程,全局事务未全部分支销毁时,会话元数据会永久残留; -
诊断 SQL:
sql
select taddr, status, sid, serial#, LAST_CALL_ET
from v$session
where taddr in ( select taddr from v$session where status='KILLED')
order by 1,2 desc ,3;
查询结果中多条会话共享同一个TADDR,即为同一全局分布式事务多分支阻塞。
本次案例说明
当前僵尸会话TADDR为空,代表本条分支本地事务已完成,但集群内该全局事务其他分支未完全清理,依然会造成本条会话长期滞留。
2. RAC 集群 GES 全局资源同步阻塞(RAC 环境最高发)
PMON 清理跨实例会话时,依赖 GES 全局队列服务完成集群状态广播、资源同步。 触发条件:
-
节点私网 Interconnect 抖动、拥塞、丢包;
-
LMS 后台进程满载、全局资源队列积压; 现象:本地锁、本地事务已全部释放,但集群层面状态同步卡住,PMON 无法执行最后一步删除会话内存记录,会话永久僵死。
3. PMON 后台进程自身被 Latch、资源争用阻塞
PMON 清理会话需要竞争共享池、library cache latch,若 PMON 长期卡在异常等待事件,全局 KILLED 会话清理队列停滞堆积。 排查 SQL:
sql
select inst_id, sid, program, event, state, seconds_in_wait
from gv$session
where program like '%PMON%';
4. SGA 内存悬空指针损坏
OS 进程异常崩溃后,会话内存对象与服务进程对象指针断裂。Oracle 为避免实例宕机、内存越界,PMON 会主动跳过该会话清理流程,形成无锁、无事务、无进程的纯脏记录僵尸会话。
5. Oracle 官方 Bug
11gR2、12cR1 版本出现内部 Bug:执行KILL SESSION IMMEDIATE强杀后,OS 进程销毁,但会话元数据无法被 PMON 回收,特征与本次故障完全吻合。
重点提醒:本次故障的僵尸会话不会阻塞业务 ,无锁、无回滚段占用、不消耗 PGA,仅gv$session视图存在一条历史残留记录。
四、全套可直接复制的排查 SQL 脚本
sql
-- 1. 筛选所有孤儿僵尸KILLED会话(对应进程已消失)
SELECT s.inst_id,s.sid,s.serial#,s.status,s.paddr,s.username,s.last_call_et
FROM gv$session s
WHERE s.status='KILLED'
AND NOT EXISTS (SELECT 1 FROM gv$process p WHERE p.addr=s.paddr AND p.inst_id=s.inst_id);
-- 2. 检查PMON后台进程等待事件,判断是否阻塞
select inst_id, sid, program, event, state, seconds_in_wait
from gv$session
where program like '%PMON%';
-- 3. 检测RAC私网健康,判断GES同步是否异常
select inst_id,name,value from gv$sysstat where name like 'gc%lost';
-- 4. MOS KB151805核心SQL:查找分布式事务多分支会话
SELECT inst_id,sid,serial#,status,taddr,machine,program
FROM gv$session
WHERE taddr IN (SELECT taddr FROM gv$session WHERE status='KILLED');
-- 5. 查看KILLED会话事务指针TADDR
select inst_id,sid,serial#,taddr from gv$session where status='KILLED';
五、运维总结
-
KILLED仅为会话状态标记,资源回收由 PMON 异步执行,短时残留属于 Oracle 正常机制; -
进程消失、TADDR 为空、无锁、滞留超 1 小时的僵尸会话,两大核心诱因:RAC 集群 GES 全局同步阻塞 / XA 分布式事务多分支未全部清理(MOS KB151805);
-
MOS 文档关键结论:分布式事务仅 Kill 单一分支无法释放全局资源,必须清理同一事务下全部分支会话,PMON 才能完成回收;
-
区分风险:TADDR 为空、无锁的孤儿僵尸会话无业务阻塞,无需紧急处置;
-
RAC 运维规范:Kill 跨实例会话必须携带
@inst_id指定实例,避免操作错误节点会话; -
排查顺序:先核查分布式事务分支 → 检查 PMON 状态 → 验证集群私网,最后再考虑重启实例。