Oracle运维常见崩溃场景:监控显示异常空闲会话,执行Kill命令报错ORA-00030(会话ID不存在),OS层强杀进程后,GV$SESSION仍有“鬼影”会话,状态为KILLED却无法消失。

本文结合真实故障,分享精准排查+解决方法,所有命令可直接复制,生产环境亲测有效,帮大家快速避坑!

一、诡异现象:Kill会话报错,查得到却杀不掉

在节后巡检时发现Oracle RAC集群中,一个会话运行了500多天

用脚本查看,确定是运行了很久

SELECT     s.inst_id,    s.sid,    s.serial#,    s.username,    s.machine,    s.program,    s.sql_id,    s.last_call_et AS exec_seconds,  -- 已执行时间(秒)    ROUND(s.last_call_et/60, 2) AS exec_minutes,    t.sql_text,    s.event,    s.stateFROM     gv$session s    LEFT JOIN gv$sqltext t ON s.sql_id = t.sql_id         AND s.inst_id = t.inst_id        AND t.piece = 0WHERE     s.type = 'USER'    AND s.status = 'ACTIVE'    -- AND s.sql_id IS NOT NULL    AND s.last_call_et > 1000  -- 执行超过1000秒
ORDER BY     s.last_call_et DESC;

该会话一直占用资源,查询GV$SESSION获取SID、SERIAL#、INST_ID后,执行标准终止命令:

ALTER SYSTEM KILL SESSION 'sid,serial#,@inst_id';

直接报错:

ORA-00030: User session ID does not exist.

核心矛盾:GV$SESSION中会话信息存在,但命令执行时会话已处于“生命周期中间态”。

重点提醒:RAC环境Kill会话必须加@inst_id,否则默认操作当前实例,易找错会话。

对于该现象,通常有如下2种常见原因:

  •  瞬间消亡:会话因客户端超时、网络闪断或连接池回收,在Kill命令执行前已被自然清理,视图未及时刷新

  • 状态延迟:PMON进程未完成会话内存清理,导致视图残留会话信息,但实际会话已失效

重新确认会话信息、用RAC专用命令重试,报错依旧,需换思路解决。

二、釜底抽薪:OS强杀

数据库层面杀不掉,直接强杀操作系统进程(SPID),步骤如下:

1. 关联视图查询SPID

SELECT s.inst_id, s.sid, s.serial#, p.spidFROM gv$session s, gv$process pWHERE s.paddr = p.addr  AND s.sid = :your_sid  AND s.serial# = :your_serial#;

查询结果如下:

2. 登录对应服务器强杀进程

登录到节点1上,进行杀进程操作

kill -9 目标SPID

进程消失后,通常很快就会发现GV$SESSION中对于的会话会释放。如下图所示,已经查不到之前的会话。

但是有时候会出现GV$SESSION中会话仍存在,状态变为KILLED,无法释放资源。

那么就会有个关键解惑:进程已死,会话为何残留?这通常有如下原因:

  • PMON清理延迟:强杀进程后,PMON需回滚事务、释放资源,系统负载高或资源有争用时,清理会延迟

  •  状态未同步:OS杀进程仅移除执行实体,数据库元数据清理由PMON异步完成,存在时间差

以上方法无效且影响生产时,重启会话所在RAC实例(中断该实例所有连接,需在变更窗口操作)。

重要警告:重启实例影响业务,提前备份并通知相关人员,非紧急不使用。

三、防患于未然:4步杜绝“僵尸会话”

1. 优化连接池配置

重点配置两个参数(HikariCP、DBCP等通用):

  • - idleTimeout:10-30分钟,避免空闲连接长期占用资源。

  • - maxLifetime:1-2小时,强制回收老化连接。

2. 配置SQLNET心跳

sqlnet.ora中添加配置,主动探测死连接:

SQLNET.EXPIRE_TIME=10

每10分钟探测一次,无响应则自动断开连接。

3. 设置数据库资源限额

创建Profile限制会话空闲时间,自动终止空闲会话:

-- 创建ProfileCREATE PROFILE SESSION_LIMIT LIMIT IDLE_TIME 30; -- 空闲30分钟自动终止
-- 赋予用户ALTER USER 用户名 PROFILE SESSION_LIMIT;

4. 建立巡检与监控

监控空闲超过1小时的会话,定期清理,推荐查询:

SELECT inst_id, sid, serial#, username, last_call_et/3600 AS idle_hoursFROM gv$sessionWHERE type = 'USER'  AND last_call_et > 3600;

四、 结语

解决“僵尸会话”,核心是理解PMON清理机制,遵循“查询状态→等待清理→推动PMON→解阻塞→重启实例”的渐进思路。

提前规范配置、做好巡检,才能从根源杜绝问题,保障数据库稳定运行。而且生产环境操作前,需在测试环境充分验证。

关注【数据库干货铺】,获取更多数据库实战技巧、故障排查指南。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐