Oracle RAC如何清理无效的数据库连接?调整SQLNET超时
ORA-03113/ORA-03137幽灵会话因SQL*Net未探测断连而残留ACTIVE状态,需配置SQLNET.EXPIRE_TIME、TCP.CONNECT_TIMEOUT等参数并统一RAC各节点,必要时kill -9 SPID强制清理。
ORA-03113/ORA-03137:连接断开后会话仍卡在ACTIVE状态
在Oracle RAC环境中,一个颇为恼人的现象是:客户端因为网络闪断、应用崩溃或者防火墙策略清理空闲连接而异常断开后,数据库的v$session视图里,却常常残留着一大批状态显示为‘ACTIVE’的会话。这些“幽灵会话”早已名存实亡,与客户端失去了联系,但它们既不响应常规的alter system kill session命令,也不受idle_time参数的限制。结果就是,它们持续占用着PGA内存、锁以及全局队列资源,在RAC这种共享架构下,极易引发全局缓存(GC)等待的连锁反应,拖累整个集群的性能。
免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈

问题的根源,往往不在于数据库层面没有检测能力,而在于SQL*Net网络层默认没有开启主动探测或超时清理机制。要知道,在默认配置下,TCP连接的保活(keepalive)是由操作系统控制的,比如Linux系统默认的2小时超时,这远远超出了绝大多数业务场景的容忍范围。
- 如何检查当前无效会话? 可以运行以下查询,找出那些状态为ACTIVE但最后一次调用已超过5分钟的会话:
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;
- 如何确认会话是否真的无响应? 对于可疑的会话ID,查询
v$session_wait视图。如果发现其等待事件(event)是‘SQL*Net message from client’,并且状态(state)为‘WAITING’,但等待时间(seconds_in_wait)却在持续累加,这基本就能断定客户端已经失联了。 - RAC环境下的特有风险: 这类幽灵会话在集群实例间进行状态同步或争用全局资源时,可能会被其他节点反复尝试处理,无形中放大了集群的内部通信开销,让问题雪上加霜。
sqlnet.ora里必须配的3个超时参数
单纯依赖数据库的resource_limit和idle_time参数,对这类连接是无能为力的。必须在$ORACLE_HOME/network/admin/sqlnet.ora文件中显式启用SQL*Net层的探测机制。这里有三个关键参数,可以说是缺一不可,而且需要注意它们的生效范围:
SQLNET.EXPIRE_TIME = 10:这是核心。它指示服务器每隔10分钟向空闲的客户端连接发送一个探测包(一个空的数据包)。需要明确的是,这并非“10分钟后断开连接”,而只是发起一次探测。只有当客户端对这次探测毫无响应时,连接才会在后续被真正关闭。TCP.CONNECT_TIMEOUT = 60:这个参数主要影响新连接的建立阶段,比如TNS ping或首次登录尝试。对于已经建立的连接,它不起作用。但将其设置为一个合理的值(如60秒),可以有效避免因网络问题导致的大量连接请求堆积,阻塞监听器进程。TCP.VALIDNODE_CHECKING = YES配合TCP.INVITED_NODES = (your_app_subnet):这组参数虽然不直接控制超时,但通过限制允许连接的主机,可以从源头上防止恶意扫描建立虚假连接,间接减少了无效连接产生的可能性。
⚠️ 一个关键的大坑: 在RAC环境中,SQLNET.EXPIRE_TIME这个参数必须在所有节点上保持配置一致。否则,可能出现一个节点因探测失败断开了连接,而客户端重连时被分配到另一个节点,却可能错误地复用了旧的连接句柄,导致会话状态陷入混乱。修改完sqlnet.ora后,数据库实例无需重启,但必须重启监听器(lsnrctl)以使新配置生效。
ALTER SYSTEM KILL SESSION不生效?直接查SPID杀OS进程
有时候,你会发现v$session中的会话状态已经变成了‘KILLED’,但它占用的资源却迟迟没有释放。这在RAC环境中尤其常见,可能因为会话涉及跨实例的锁等待。此时,干等着PMON进程来清理可不是好主意,更主动的做法是定位到对应的操作系统进程并强制终止。
- 第一步,查找操作系统进程ID(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 =
; - 第二步,在会话所在的RAC节点上执行强制终止: 在Linux系统上使用
kill -9;在Windows系统上则使用orakill。 - 第三步,验证清理结果: 执行
SELECT count(*) FROM v$process WHERE spid = ',如果返回结果为0,就说明进程已被成功清除。';
需要理解的是,ALTER SYSTEM KILL SESSION命令本身只是给会话打上一个“待清除”的标记,真正的清理工作是由后台进程PMON周期性地扫描来完成的(默认每3秒一次)。如果这个会话恰好持有未提交的DML锁,或者正卡在两阶段提交的中间状态,PMON的清理动作可能会被延迟数分钟甚至更久。在这种情况下,强制杀掉操作系统进程往往是唯一立竿见影的方法。当然,操作前最好通过v$transaction视图确认一下该会话是否还有未提交的事务,以评估强制终止的风险。
监听器日志里看真实断连时间点
数据库内部的视图只能告诉我们会话“何时被标记为失效”,如果想追踪网络层实际断开连接的确切时刻,就必须去查阅$ORACLE_HOME/network/log/listener.log这个监听器日志文件。
- 搜索关键错误码: 重点关注
TNS-12535(操作超时)、TNS-12608(发送超时)以及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、云负载均衡器)主动切断了连接。如果同一个IP地址频繁出现
TNS-12535错误,那么很大概率是应用程序没有正确关闭连接,或者连接池的超时配置设置得过长。
真正棘手的是那些“隐形”的连接——它们既没有在监听器日志中留下错误记录,也没有被SQLNET.EXPIRE_TIME机制捕获。这类连接往往卡在操作系统的TCP FIN_WAIT2状态。排查它们需要从操作系统层面入手,例如使用netstat -an | grep :1521 | grep FIN_WAIT2这样的命令。遇到这种情况,调整的焦点通常就不再是数据库参数了,而是操作系统的内核网络参数,比如net.ipv4.tcp_fin_timeout。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
Redis如何备份正在运行的实例_利用BGSAVE命令进行无阻塞快照
Redis BGSA VE:一个“不阻塞”但绝非“无影响”的快照命令 提到Redis的数据备份,BGSA VE命令几乎是绕不开的选项。它确实能在不中断服务的情况下为运行中的实例创建快照,但这里有个常见的认知误区需要澄清:“不阻塞主线程”绝不等于“毫无影响”。实际上,从fork子进程到最终落盘,整个过
怎样将数据库导出到另一台服务器_直接转移与同步方案
数据库迁移核心取决于数据库类型、停机容忍度、数据量及目标环境初始化情况;MySQL优先用mysqldump管道直传并加--single-transaction等参数,PostgreSQL推荐-Fc格式+pg_restore并行处理,不停机需主从或逻辑复制+数据一致性校验。 想把数据库搬到另一台服务器
如何为多服务器配置独立的慢查询报警阈值_性能监控差异化
MySQL 慢查询日志差异化阈值配置:从参数设置到监控告警的完整实践指南 MySQL 慢查询日志的 `long_query_time` 能否按实例独立设置? 完全可以实现,但关键在于明确您的MySQL版本与部署架构。自MySQL 5 7 21与8 0 14版本起,已支持在会话级别动态调整`long_
MySQL事务中如何处理异常回滚_使用try-catch与rollback机制
MySQL事务中如何处理异常回滚:使用try-catch与rollback机制 先明确一个核心事实:在MySQL的事务处理中,服务端本身并不支持try-catch语法。这个控制结构是应用层(如Ja va、Python、PHP)的专属。至于存储过程中的DECLARE HANDLER,其功能相当有限,完
如何在可视化界面隐藏特定字段_查询屏蔽与视图替代
为什么 display: none 在报表工具里常失效 在报表开发中,许多开发者习惯使用 CSS 的 display: none 来隐藏某些数据字段,但常常发现这一方法效果不佳:隐藏的元素可能在页面刷新后重新出现,或者虽然视觉上不可见,却仍在后台参与计算、影响数据筛选,甚至在导出时意外暴露。这背后的
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

