RAC数据库OS进程消失,GV$SESSION长期残留KILLED僵尸会话处理

前言

客户日常运维执行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 会话不会即时清除的根本原因

  1. KILL SESSION / DISCONNECT SESSION IMMEDIATE仅做状态标记 ,不会同步删除gv$session内存记录;

  2. 事务回滚、锁释放、PGA 内存回收、会话条目删除全部由后台PMON进程异步周期性执行;

  3. 正常场景:PMON 数秒~数十秒完成清理,会话自动消失;

  4. 判断异常:如果超过 1 小时仍残留 KILLED 会话,不属于正常延迟,存在资源阻塞、内存异常或分布式事务分支未清理问题。

三、KILLED 会话 1 小时以上无法清理的原因

1. 分布式 / XA 全局事务多分支阻塞(MOS KB151805 核心根因)

这是 Oracle 官方文档明确收录的高频故障场景,OS 进程消失、数据库会话长期 KILLED的现象。

MOS 文档原文核心逻辑
  1. 使用 DBLINK、JTA XA 分布式事务时,一个全局事务会拆分多条分支会话

  2. 事务资源归属全局事务本身,而非单条会话;仅 Kill 其中一条分支,无法释放全局事务资源;

  3. 只要同一全局事务下其余分支会话仍存活(INACTIVE/KILLED),PMON 不会彻底清理已被杀分支;

  4. 即便 OS 层kill -9强制销毁服务进程,全局事务未全部分支销毁时,会话元数据会永久残留;

  5. 诊断 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';

五、运维总结

  1. KILLED仅为会话状态标记,资源回收由 PMON 异步执行,短时残留属于 Oracle 正常机制;

  2. 进程消失、TADDR 为空、无锁、滞留超 1 小时的僵尸会话,两大核心诱因:RAC 集群 GES 全局同步阻塞 / XA 分布式事务多分支未全部清理(MOS KB151805);

  3. MOS 文档关键结论:分布式事务仅 Kill 单一分支无法释放全局资源,必须清理同一事务下全部分支会话,PMON 才能完成回收;

  4. 区分风险:TADDR 为空、无锁的孤儿僵尸会话无业务阻塞,无需紧急处置;

  5. RAC 运维规范:Kill 跨实例会话必须携带@inst_id指定实例,避免操作错误节点会话;

  6. 排查顺序:先核查分布式事务分支 → 检查 PMON 状态 → 验证集群私网,最后再考虑重启实例。

相关推荐
小龙报2 小时前
【优选算法】1. 水果成蓝 2.找到字符串中所有字母的异位词
java·c语言·数据结构·数据库·c++·redis·算法
宇宙第一小趴菜2 小时前
六、Oracle 目录结构
数据库·oracle
IvorySQL2 小时前
PG 日报|修复高 IO 并发场景,解决预读机制耗尽本地缓冲区缺陷
数据库·人工智能·sql·postgresql·区块链
TiDB 社区干货传送门2 小时前
TiDB 8.5.7 发版|六项实用功能上线
数据库·mysql·tidb
在繁华处3 小时前
MySQL 学习笔记 01:从概念到约束,搭好库表骨架
数据库·oracle
三言老师3 小时前
CentOS7.9:Redis 数据持久化结构化实战教程
数据库·redis·缓存
鸽芷咕3 小时前
KingbaseES 优化器底层逻辑:等价变换如何改写 SQL,条件调度如何驱动运行时
数据库
Vect__4 小时前
MySQL 内连接和外连接:从匹配关系到业务查询
数据库·mysql
qq_150841994 小时前
SQL的insert和update二合一指令
java·数据库·sql