tnsping卡在“Attempting to contact”且耗时超3秒,说明DNS解析拖慢SCAN连接;需验证DNS返回≥2个独立A记录、sqlnet.ora中NAMES.DIRECTORY_PATH=(HOSTNAME,TNSNAMES,EZCONNECT)且HOSTNAME置首、/etc/hosts完整覆盖SCAN FQDN,Java应用须在JDBC URL中显式列出全部SCAN IP并启用LOAD_BALANCE=on。

tnsping卡在“Attempting to contact”就说明DNS解析拖慢了SCAN连接
tnsping输出里出现明显停顿、耗时远超500ms,且最终报ORA-12170或直接超时,基本可断定是DNS环节卡住——不是监听器没起来,也不是网络不通,而是客户端根本还没走到TCP建连那步。RAC中SCAN依赖多A记录轮询,一旦某次DNS查询慢或返回不全,整个连接流程就会阻塞。
实操建议:
- 在客户端执行
tnsping racscan,观察“Attempting to contact”之后是否卡顿;若卡3秒以上,立即暂停排查DNS - 同步运行
nslookup rac-scan.example.com和dig rac-scan.example.com +short,对比响应时间与结果数量:Oracle 12c要求至少返回2个独立IPv4 A记录,少于2个会导致SCAN感知失效 - 别信
ping rac-scan.example.com——它只查第一个IP,而SCAN必须拿到全部A记录才能轮询
sqlnet.ora里NAMES.DIRECTORY_PATH不含HOSTNAME,hosts文件就等于没写
很多用户把所有SCAN节点IP都加进了/etc/hosts,但连接还是慢,原因就是sqlnet.ora里没启用HOSTNAME解析路径。Oracle默认配置是NAMES.DIRECTORY_PATH=(TNSNAMES, EZCONNECT),它压根不查hosts,只走DNS。
实操建议:
- 确认
sqlnet.ora中存在且首项为NAMES.DIRECTORY_PATH=(HOSTNAME, TNSNAMES, EZCONNECT);顺序不能错,HOSTNAME必须排第一 -
/etc/hosts条目必须覆盖全部SCAN VIP对应的FQDN(如192.168.10.50 rac-scan.example.com),不能只写短名 - Linux/macOS下检查
/etc/nsswitch.conf中hosts: files dns是否生效;Windows客户端无此机制,hosts文件本身即有效
SCAN DNS返回单A记录或CNAME,12c客户端会静默跳过轮询逻辑
Oracle 12c开始对SCAN域名的DNS响应做校验:若dig rac-scan.example.com只返回1个A记录,或返回CNAME再查A,客户端会认为SCAN不可用,自动降级到节点VIP连接——这不仅失去负载均衡,还可能因VIP未注册导致ORA-12514。
实操建议:
- 用
dig rac-scan.example.com @<your-dns-server></your-dns-server>直连你配置的DNS服务器,确认返回≥2个不同IPv4地址 - 禁止在DNS中为SCAN名设置CNAME;必须是纯A记录,且3个SCAN VIP要分布在不同物理网卡或子网(避免单点故障)
- 如果用
/etc/hosts模拟多A,必须写三行,每行一个IP+相同FQDN,例如:192.168.10.50 rac-scan.example.com<br>192.168.10.51 rac-scan.example.com<br>192.168.10.52 rac-scan.example.com
Java应用不读sqlnet.ora,JDBC URL得手动补全SCAN IP列表
JDBC Thin驱动完全绕过Oracle Net配置,sqlnet.ora和tnsnames.ora对它无效。所以即使你在客户端配好了HOSTNAME优先,Java应用照样走系统DNS,照样卡。
实操建议:
- 改JDBC URL为带多个地址的SCAN格式:
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.10.50)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.10.51)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.10.52)(PORT=1521)))(LOAD_BALANCE=on)(FAILOVER=on)(CONNECT_DATA=(SERVICE_NAME=racdb))) - 不要用
jdbc:oracle:thin:@rac-scan.example.com:1521/racdb这种单地址写法,它不具备SCAN轮询能力 - Spring Boot项目可在
application.yml中用spring.datasource.hikari.connection-init-sql加探测SQL,提前暴露DNS失败,而非等到首次业务查询才崩
lsnrctl status LISTENER_SCAN1依然显示正常,srvctl status scan也返回ONLINE——因为监听器进程本身没挂,只是客户端发来的连接请求在解析阶段就被阻塞了。这时候看日志,$GRID_HOME/log/<node>/client/log/client.log里会出现大量TNS-12224或TNS-12545,但没人去看。


















