ora-03113/ora-03137幽灵会话因sql*net未探测断连而残留active状态,需配置sqlnet.expire_time、tcp.connect_timeout等参数并统一rac各节点,必要时kill -9 spid强制清理。
ora-03113/ora-03137:连接断开后会话仍卡在active状态
oracle rac中,客户端异常断连(如网络闪断、应用崩溃、防火墙kill空闲连接)后,v$session里常残留大量status = 'active'但实际已无客户端通信的会话。这些“幽灵会话”不响应alter system kill session,也不计入idle_time限制,持续占用pga、锁和全局队列资源,尤其在rac环境下可能引发gc等待加剧。
根本原因不是数据库没检测到断连,而是SQL*Net层未主动探测或超时触发清理——默认配置下,TCP keepalive由OS控制(Linux默认2小时),远超业务容忍范围。
- 检查当前无效会话:
SELECT sid, serial#, username, status, server, program, sql_id, last_call_et FROM v$session WHERE status = 'ACTIVE' AND last_call_et > 300 AND username IS NOT NULL;
- 确认是否真无响应:对疑似会话执行
SELECT * FROM v$session_wait WHERE sid = <sid></sid>,若event为SQL*Net message from client且state = 'WAITING'但seconds_in_wait持续增长,基本可判定客户端已失联 - RAC特有风险:这类会话在实例间迁移或GC资源争用时,可能被其他节点反复尝试同步状态,放大集群开销
sqlnet.ora里必须配的3个超时参数
仅靠数据库resource_limit=TRUE和idle_time无法清理这类连接,必须在$ORACLE_HOME/network/admin/sqlnet.ora中显式启用SQL*Net级探测。三个参数缺一不可,且需注意生效范围:
-
SQLNET.EXPIRE_TIME = 10:每10分钟向客户端发送一个probe包(空数据包)。注意这不是“断开超时”,只是探测;若客户端无响应,下次探测失败后才真正关闭连接 -
TCP.CONNECT_TIMEOUT = 60:仅影响新连接建立阶段(如tnsping或首次登录),与已建立连接无关,但建议设为合理值避免连接风暴阻塞监听器 -
TCP.VALIDNODE_CHECKING = YES+TCP.INVITED_NODES = (your_app_subnet):虽非超时相关,但能防止恶意扫描维持虚假连接,间接减少无效连接数量
⚠️ 关键坑:SQLNET.EXPIRE_TIME在RAC中**必须所有节点配置一致**,否则某节点探测失败断连后,客户端重连到另一节点可能复用旧连接句柄,导致会话状态混乱。修改后无需重启DB,但需重启lsnrctl使监听器加载新配置。
ALTER SYSTEM KILL SESSION不生效?直接查SPID杀OS进程
当v$session中会话STATUS = 'KILLED'却长期不释放(常见于RAC中跨实例锁等待),说明PMON尚未完成清理。此时不应等待,而应定位对应OS进程强制终止:
- 查SPID:
SELECT s.sid, s.serial#, s.status, p.spid, s.program FROM v$session s, v$process p WHERE s.paddr = p.addr AND s.sid = <sid>;</sid>
- 在对应RAC节点上执行:
kill -9 <spid></spid>(Linux)或orakill <inst_name><spid></spid></inst_name>(Windows) - 验证是否清除:
SELECT count(*) FROM v$process WHERE spid = '<spid>';</spid>返回0即成功
注意:KILL SESSION本身只打标记,真实清理依赖PMON周期扫描(默认每3秒一次)。若会话正持有DML锁或处于两阶段提交中,PMON可能延迟数分钟才释放——此时强杀SPID是唯一有效手段,但需确保该会话无未提交事务(通过v$transaction确认)。
监听器日志里看真实断连时间点
数据库视图只能反映“何时被标记为失效”,要确认网络层实际断开时刻,得查$ORACLE_HOME/network/log/listener.log:
- 搜索关键字:
TNS-12535(TNS timeout)、TNS-12608(send timeout)、Failed to accept a connection - 典型记录:
TNS-12535: TNS:operation timed out TNS-12608: TNS:send timeout ns secondary err code: 12535 nt main err code: 0
- 结合时间戳与客户端IP,可反推是应用侧心跳缺失,还是中间设备(如F5、云LB)主动回收连接。若同一IP高频出现
TNS-12535,大概率是应用未正确关闭连接或连接池配置过长
真正棘手的是那些既没进监听器日志、又没被SQLNET.EXPIRE_TIME捕获的连接——它们往往卡在TCP FIN_WAIT2状态,需从OS层面用netstat -an | grep :1521 | grep FIN_WAIT2排查,这时通常要调整内核参数net.ipv4.tcp_fin_timeout,而非数据库配置。










