oracle 19c rac 的 scan 连接需手动配置全部三个 scan 域名地址于同一 address_list 下并设 load_balance=on(小写),jdbc 需显式指定 loadbalance=true&failover=true,且服务端 remote_listener 必须指向 scan 地址并执行 alter system register。

Oracle 19c RAC 的 SCAN 连接不自动做 DNS 轮询,客户端必须显式列出全部 3 个 SCAN 地址并配 LOAD_BALANCE=on,否则永远只连第一个 IP。
tnsnames.ora 必须手动写全三个 SCAN 地址
Oracle 客户端(包括 JDBC Thin)不会主动查 DNS 获取 SCAN 的多个 A 记录,它只按你在 tnsnames.ora 里写的 ADDRESS 顺序尝试连接。漏掉任意一个 SCAN VIP,负载均衡逻辑就失效。
-
HOST字段必须填可被 DNS 解析的 SCAN 域名(如rac-scan.example.com),不能填 IP 或节点 VIP - 三个 SCAN 地址必须包在同一个
ADDRESS_LIST下,不能拆成多个独立DESCRIPTION -
LOAD_BALANCE=on必须小写,写成ON、yes或true都会被静默忽略 - 不要加
FAILOVER=on—— SCAN 监听器自身已具备故障转移能力,额外启用反而干扰分发
(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
即使 tnsnames.ora 配对了,JDBC Thin 驱动也不会读取它里面的 LOAD_BALANCE=on —— 它只认 URL 参数。ojdbc6 及更早版本会完全忽略该参数,必须用 ojdbc8+。
- URL 中必须带
loadBalance=true&failover=true,缺一不可 - 不能依赖
TNS_ADMIN自动加载tnsnames.ora来触发轮询 - 如果用 URL 写法(非 tnsnames),
HOST仍要指向 SCAN 域名,且需确保 DNS 能返回三行Address: - 验证 DNS:运行
nslookup rac-scan.example.com,确认输出含三个独立 IPv4 地址
Server-side 必须让 SCAN Listener 看到各节点实时负载
客户端随机选地址只是第一步;真正决定请求落到哪个实例的,是 SCAN Listener 是否能拿到各节点的 load 值。没这个值,所有连接都会被转发到第一个注册的实例。
- 每个实例的
REMOTE_LISTENER必须设为 SCAN 地址(如scan.example.com:1521),不是 VIP、localhost 或 GNS VIP(除非真用了 GNS) - 改完
REMOTE_LISTENER后,立刻在每个实例执行ALTER SYSTEM REGISTER;,否则可能延迟数分钟才上报 - 检查是否生效:
lsnrctl status LISTENER_SCAN1 | grep -A 10 "Service \"orcl\"",输出中必须出现load=xx字段 - 若
/etc/hosts里有 SCAN 条目,19c 会拒绝启动 SCAN 监听器,报错"SCAN name resolves to single IP"
最容易被忽略的是:DNS 返回三个 A 记录 ≠ 客户端用了三个地址。JVM 和 Oracle 客户端都缓存 DNS 结果,且只解析一次。你得亲手把三个 SCAN 域名全写进 ADDRESS_LIST,再配对小写的 on 和服务端注册,少一步,负载就塌在第一个节点上。











