/etc/hosts无法正确提供scan多ip解析,因为glibc解析器仅取首行匹配项,后续重复条目被忽略;oracle 19c强制要求getaddrinfo()返回≥2个af_inet地址,单ip导致srvctl start scan静默失败且scan监听器不绑定vip。

为什么 /etc/hosts 无法正确提供 SCAN 多 IP 解析
Oracle RAC 的 SCAN 机制依赖 DNS 返回多个 A 记录实现客户端轮询,而 /etc/hosts 文件本身不支持“一个主机名映射多个 IPv4 地址”的语义——glibc 解析器只取首行匹配项,后续重复条目被完全忽略。
即使你在 /etc/hosts 中写三行:
192.168.10.50 scan-rac.example.com 192.168.10.51 scan-rac.example.com 192.168.10.52 scan-rac.example.com
实际效果等同于只配置了第一行;nslookup scan-rac.example.com 或 getaddrinfo() 调用永远只返回 192.168.10.50。这不是 Oracle 的 bug,而是 POSIX 标准下 hosts 文件的设计限制。
-
dig和nslookup查不到多 IP,说明解析层根本没生效 - Oracle 19c Grid 启动时调用
getaddrinfo(),要求返回 ≥2 个AF_INET地址,单 IP 直接导致srvctl start scan静默失败 - 旧版 glibc(如 2.17 之前)遇到重复 hostname 可能报
Unknown host,连基本解析都失败
Oracle 19c 对 SCAN DNS 解析的硬性校验逻辑
从 19c 开始,Grid Infrastructure 在启动 ora.LISTENER_SCAN1.lsnr 前会主动执行 getaddrinfo("scan-rac.example.com", NULL, &hints, &result),并严格检查返回的 addrinfo 链表中 AF_INET 地址数量 —— 必须 ≥2,否则跳过绑定、监听器不监听任何 SCAN VIP。
这个校验发生在 CRS 启动早期,不依赖日志显式报错,但你会看到:
-
srvctl status scan_listener显示监听器运行中,但lsnrctl status LISTENER_SCAN1里没有(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=...)(PORT=1522)))绑定段 -
srvctl config scan输出仅显示 1 个 SCAN VIP,而ifconfig确认该 IP 并未实际绑定到网卡 - 即使手动
srvctl modify scan -n scan-rac.example.com,也无法绕过此校验
常见误配场景与验证方式
很多团队试图用 /etc/hosts “模拟” DNS 轮询,结果全军覆没。典型错误包括:
- 在
/etc/hosts写单行多 IP:192.168.10.50 192.168.10.51 192.168.10.52 scan-rac.example.com→ 解析失败,getaddrinfo()返回空 - 用 CNAME 指向另一个域名(如
scan-rac.example.com IN CNAME vip1.example.com)→ 19c 不接受,校验直接失败 - DNS 配置了 3 个 A 记录,但客户端
/etc/resolv.conf指向的 DNS 服务器未生效,或/etc/nsswitch.conf中hosts: files dns顺序错误,导致仍查/etc/hosts
验证是否合格,别信配置,看实际响应:
-
dig scan-rac.example.com A +short连续执行 10 次,必须稳定输出 3 行不同 IP,且顺序随机 -
dig scan-rac.example.com A +tcp +short必须返回相同 3 个 IP(SCAN 强制要求 TCP 回退可用) -
nslookup -debug scan-rac.example.com 192.168.10.1查看响应头中ANSWER: 3是否出现,且无REFUSED
为什么改完 DNS 后 srvctl start scan 仍不生效
Grid Infrastructure 不缓存 DNS 结果,每次 srvctl start scan 都重新调用 getaddrinfo(),所以 DNS 改完无需重启 GI —— 但前提是本地 DNS 缓存已清空。
常见遗漏点:
-
nscd正在运行:执行systemctl restart nscd或nscd -i hosts - 某些 Linux 发行版启用
systemd-resolved:需systemd-resolve --flush-caches - 集群节点间时间不同步:NTP 未校准可能导致 DNS 查询超时被丢弃
- 防火墙拦截了 UDP 53 或 TCP 53:尤其注意 TCP 回退路径,很多安全策略只放行 UDP
真正容易被忽略的是:DNS 响应必须包含全部 3 个 SCAN VIP,且不能有视图(view)或 ACL 按客户端 IP 过滤返回结果 —— 否则部分节点查出 3 个 IP,部分只查出 1 个,造成集群状态不一致。











