Oracle 19c RAC强制要求SCAN域名通过getaddrinfo()一次性返回≥2个独立IPv4地址,DNS轮询无效;若不满足,srvctl start scan静默失败或监听器绑定不全,须配置3个A记录并执行srvctl modify scan_listener -u生效。
oracle 19c rac 不支持仅靠 dns 轮询返回多个 ip 的 scan 域名配置——必须让 getaddrinfo() 实际返回 ≥2 个独立 ipv4 地址,否则 srvctl start scan 会静默失败或监听器绑定不全。
为什么 DNS 轮询不等于多 SCAN IP 生效
DNS 轮询(如每次 dig scan.example.com A 返回不同 IP)对 19c 无效。Grid Infrastructure 启动 SCAN 时调用 getaddrinfo() 获取全部解析结果,要求一次性返回至少两个 AF_INET 地址;轮询是客户端行为,服务端无法感知。常见错误现象:srvctl status scan 显示只有 scan1,ifconfig 确认其余 SCAN VIP 未绑定到网卡。
必须确保:
- DNS 响应中
dig scan.example.com A +short输出三行**不同**的 IPv4 地址(如10.10.10.25、10.10.10.26、10.10.10.27) - 所有节点的
/etc/resolv.conf指向该 DNS,且/etc/nsswitch.conf中hosts:行含dns,且files不能排在dns前面 - 禁用 CNAME:19c 不递归解析 CNAME,只认最终 A 记录
如何验证 DNS 解析是否被 Grid 正确识别
在任意集群节点上以 grid 用户执行:
getaddrinfo -f scan.example.com
输出必须包含至少两行 AF_INET 类型地址(非 AF_INET6)。若只出一行或报错,说明 Grid 启动时就会跳过剩余 IP。
常见干扰项:
-
nslookup或host显示多个 IP ≠getaddrinfo()返回多个 —— 它们不走同一套解析路径 - 本地
nscd缓存未清:执行systemctl restart nscd后再试 -
/etc/hosts优先级高于 DNS:检查/etc/nsswitch.conf是否误配files在前
添加新 SCAN IP 后必须执行 srvctl modify scan_listener -u
即使 DNS 已返回 3 个 IP,Grid 也不会自动创建对应数量的 LISTENER_SCAN2、LISTENER_SCAN3。不执行该命令会导致:
-
srvctl config scan_listener仍只显示LISTENER_SCAN1 -
srvctl status scan_listener只报告一个监听器运行,其余 SCAN VIP 无监听进程绑定 - 客户端连接可能成功,但负载无法分发到全部 SCAN IP
操作顺序严格为:
- 确认 DNS 已生效并被
getaddrinfo验证 srvctl stop scan_listener && srvctl stop scan-
srvctl modify scan -n scan.example.com(强制刷新 SCAN 名称与网络映射) -
srvctl modify scan_listener -u(关键!生成新监听器资源) srvctl start scan && srvctl start scan_listener
执行后检查:srvctl config scan 应列出 scan1~scan3,srvctl config scan_listener 应显示 LISTENER_SCAN1~LISTENER_SCAN3。
JDBC 连接池不能依赖 SCAN 域名解析
应用层 JDBC 驱动(C3P0/Druid)默认只解析并缓存 SCAN 域名的第一个 IP,后续节点宕机时连接建立直接失败,根本不会触发连接池重试逻辑。
必须改为显式地址列表:
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.10.25)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.10.26)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=10.10.10.27)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=orcl)))
同时加 JVM 参数禁用 DNS 缓存:-Dnetworkaddress.cache.ttl=0 -Dnetworkaddress.cache.negative.ttl=0。Druid 必须启用 test-on-borrow=true 并配 valid-connection-checker-class-name=com.alibaba.druid.pool.vendor.OracleValidConnectionChecker,否则坏连接会被直接返回。
真正容易被忽略的是:SCAN 域名在 19c 中已不是“可用即可”,而是启动阶段硬性校验项;DNS 配置正确 ≠ Grid 识别正确;应用连接字符串写域名 ≠ 客户端真能轮到三个 IP —— 这三者之间存在明确的断层,必须逐层验证。

















