SQLNET.RECV_TIMEOUT是接收等待超时而非连接超时,仅控制已连状态下等待服务器响应的空闲时间;真正决定“连不上”的是TCP connect超时、JDBC的CONNECT_TIMEOUT或tnsnames.ora中的CONNECT_TIMEOUT参数。
SQLNET.RECV_TIMEOUT 不是连接超时,而是接收等待超时
sqlnet.recv_timeout 控制的是客户端已建立连接后,等待服务器返回数据的最长空闲时间(单位:秒)。它不参与 tcp 连接建立阶段,所以改它对“连不上 oracle”毫无帮助。常见错误是看到连接卡住或报 ora-12170: tns:connect timeout occurred 就去调这个参数——完全用错了地方。
典型误用场景:
• 客户端发起 sqlplus /@mydb 卡住 60 秒后报错,以为是 SQLNET.RECV_TIMEOUT 导致;
• 在 sqlnet.ora 里设成 5,结果连接还是等 60 秒才失败。
真正起作用的是:
• 客户端操作系统 TCP connect() 系统调用的默认超时(Linux 通常约 20–30 秒,Windows 更长)
• Oracle JDBC 的 oracle.net.CONNECT_TIMEOUT(仅 JDBC)
• Oracle Wallet 或连接描述符中显式指定的 (CONNECT_TIMEOUT=10)(12cR2+ 支持)
EXPIRE_TIME 是死连接探测,不是超时控制
EXPIRE_TIME 是服务端参数(在 sqlnet.ora 中设置),用于定期向客户端发送探测包,检测连接是否已异常中断(比如客户端断网没发 FIN)。它不控制任何“超时建立”或“查询等待”,只影响服务端何时清理僵尸连接。
容易踩的坑:
• 设成 EXPIRE_TIME=1 以为能“快速发现断连”,结果引发大量无效探测,加重网络和数据库负担
• 和 SQLNET.SEND_TIMEOUT 混淆,后者也仅作用于已建立连接的发送阶段
• 忘记该参数需重启监听器(lsnrctl reload)才生效,改完文件就以为 OK
合理值参考:
• 内网稳定环境:设为 0(禁用)更轻量
• 需要主动保活的公网/移动场景:10–30 分钟(单位是分钟,不是秒)
• 不建议低于 5 分钟,否则探测频率过高,可能被防火墙丢包
真正在配“连接超时”的地方:tnsnames.ora 或连接字符串
Oracle 官方从 12.2 开始支持在连接描述符中直接指定 CONNECT_TIMEOUT 和 RECEIVE_TIMEOUT,这才是控制“连不上就放弃”的正确位置。
示例(tnsnames.ora):
MYDB =<br> (DESCRIPTION =<br> (CONNECT_TIMEOUT=10)<br> (RETRY_COUNT=2)<br> (ADDRESS = (PROTOCOL = TCP)(HOST = db.example.com)(PORT = 1521))<br> (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = orcl))<br> )
关键点:
• CONNECT_TIMEOUT 是单次 TCP connect() 调用的上限,单位秒
• RETRY_COUNT 控制重试次数(非重试间隔),配合 CONNECT_TIMEOUT 才有效
• 旧版本(• JDBC 用户应优先用 URL 参数:jdbc:oracle:thin:@(DESCRIPTION=(CONNECT_TIMEOUT=10)(ADDRESS=(PROTOCOL=TCP)(HOST=db)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))
监听器日志和 sqlnet.log 是唯一能验证配置是否生效的依据
改完任何 sqlnet.ora 或 tnsnames.ora 后,不要靠“试试看连不连得上”来判断。Oracle 对无效或不支持的参数往往静默忽略。
必须检查:
• 监听器日志:$ORACLE_HOME/network/log/listener.log,搜索 TNS-12535 或 TNS-00505 可确认是否触发了超时
• 客户端 sqlnet.log(需在 sqlnet.ora 中启用:TRACE_LEVEL_CLIENT = 16),查看实际使用的连接参数和耗时
• tnsping MYDB 只测网络层连通性,不走 SQL*Net 超时逻辑,不能代替真实连接测试
最容易被忽略的一点:所有超时参数都依赖底层 TCP 栈行为。如果中间有 NAT 设备、防火墙或负载均衡器,它们自身的 idle timeout(如 AWS ALB 默认 4000 秒)会先于 Oracle 参数生效,此时调 Oracle 参数毫无意义。










