Oracle 19c要求SCAN域名必须解析出3个不同IPv4地址,DNS需返回≥2个独立A记录,/etc/hosts不可重复,tnsnames.ora须显式列出全部SCAN地址并启用LOAD_BALANCE=on,JDBC需ojdbc8+及loadBalance=true&failover=true参数,且实例须配置REMOTE_LISTENER并执行ALTER SYSTEM REGISTER。
SCAN域名必须解析出3个不同IPv4地址
oracle 19c强制要求scan域名(如rac-scan.example.com)在dns中返回2–3个**互不相同的a记录**,只配1个ip会导致srvctl start scan静默失败或scan监听器未绑定全部vip。这不是可选配置,而是grid infrastructure启动时通过getaddrinfo()做的硬校验——它必须拿到≥2个af_inet地址才继续。
常见错误包括:
- /etc/hosts里写三行相同IP → 无效,必须是三个不同IP
- DNS返回CNAME → 19c不递归解析,只认最终A记录
- /etc/nsswitch.conf中
hosts: files dns但files排在dns前 → 优先查/etc/hosts,绕过DNS
验证命令:nslookup rac-scan.example.com或dig rac-scan.example.com A +short,输出必须是三行独立IPv4地址(如10.10.10.25、10.10.10.26、10.10.10.27)。
tnsnames.ora里必须显式列出全部3个SCAN地址+LOAD_BALANCE=on
Oracle客户端(含JDBC Thin)**不会自动DNS轮询**,它只按你在tnsnames.ora里写的顺序连接。哪怕DNS返回3个IP,如果你只写了一个ADDRESS,连接就永远打到第一个节点。
正确结构必须满足三项:
-
ADDRESS_LIST包裹全部3个ADDRESS,不能拆成3个独立DESCRIPTION -
LOAD_BALANCE = on(小写on,写成yes、true或ON均被静默忽略) -
HOST字段填DNS可解析的SCAN域名(如rac-scan1.example.com),不能填IP或VIP
示例:
(ORCL_SCAN =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan1.example.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan2.example.com)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan3.example.com)(PORT = 1521))
)
(CONNECT_DATA = (SERVICE_NAME = orcl))
(LOAD_BALANCE = on)
)
)
JDBC URL必须带loadBalance=true且用ojdbc8+
仅靠tnsnames.ora里的LOAD_BALANCE = on对Java应用无效。JDBC驱动需要显式参数控制行为,且只在ojdbc8.jar及以上版本完整支持。
关键点:
- URL参数名必须小写:
loadBalance=true,不是LOAD_BALANCE=on - 必须同时加
failover=true(SCAN自身有故障转移能力,但JDBC需此参数激活) - Spring Boot中不能只配
spring.datasource.hikari.jdbc-url,要把整个TNS描述和参数拼进URL字符串 -
TNS_ADMIN环境变量必须指向包含tnsnames.ora的**目录路径**(如/etc/oracle/network),不是文件路径
完整URL示例:
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=rac-scan1.example.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=rac-scan2.example.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=rac-scan3.example.com)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=orcl))(LOAD_BALANCE=on))?loadBalance=true&failover=true
REMOTE_LISTENER和ALTER SYSTEM REGISTER缺一不可
Client-side的随机选地址只是第一步,真正决定连接落到哪个实例的,是SCAN Listener能否拿到各节点实时负载数据。这依赖两个动作:
- 每个实例的
REMOTE_LISTENER参数必须指向SCAN地址(如scan.example.com:1521),不是VIP或localhost;若用GNS,则必须指向GNS VIP - 修改
REMOTE_LISTENER后,必须立即在每个实例执行ALTER SYSTEM REGISTER;,否则PMON可能延迟数分钟才上报新负载
验证是否生效:
-
lsnrctl status LISTENER_SCAN1 | grep -A 10 "Service \"orcl\"",输出中必须出现load=xx字段 -
SELECT current_load FROM gv$servicemetric WHERE service_name='orcl';,多实例结果应有差异
最容易被忽略的是:改完REMOTE_LISTENER不执行ALTER SYSTEM REGISTER;,或者误以为srvctl status service显示running就代表负载均衡已生效——其实只是服务启了,负载数据没注册上去。











