☰
数据库集群运维之DNS:从Oracle RAC SCAN到SQL Server域控的解析与故障排查
2026/10/16 4:07:06 网站建设 项目流程

集群运维干了这么多年,有一类问题我每次遇到都会条件反射地去查DNS,而不是先看数据库监听、心跳网络之类的:就是Oracle RAC的SCAN IP解析异常,以及SQL Server故障转移集群在域控地址不可用时出现的诡异故障。说白了,两套主流数据库集群方案,一个用SCAN靠DNS做“前端导航”,一个用域控地址做“身份登记”,看起来八竿子打不着,实际命脉都攥在DNS手里。

这篇文章想把这两条线放在一起聊透:Oracle集群里的SCAN为什么绕不开DNS、SCAN域名该怎么解析才符合规范;SQL Server集群里域控地址到底承担什么角色、DNS动态更新出问题会导致什么后果。同时我会把实际维护过程中踩过的坑、排查路径和配置经验一起整理出来,适合正在做数据库集群运维、或者准备从单实例转向集群架构的DBA和基础设施工程师参考。

1. DNS在数据库集群里到底扮演什么角色

很多人对DNS的认知停留在“把域名解析成IP”,这个认知在单机时代没什么问题,但一旦进入集群环境,DNS承担的职责远不止翻译地址这么简单。集群里的DNS更像一个“注册中心”,不仅要告诉客户端服务在哪,还要告诉集群组件自己人是谁、该往哪走。

1.1 集群环境里DNS的三个身份

第一层身份是“入口导航”。Oracle RAC的SCAN域名就是典型,客户端只需要记住一个SCAN域名,DNS后端对应多个节点IP,应用层完全感知不到节点变化,做到了连接入口的虚拟化。第二层身份是“身份登记”,SQL Server故障转移集群依赖活动目录域环境,节点和集群角色要在域里注册计算机对象,这个注册过程靠的是DNS动态更新协议。第三层身份是“故障转移的通讯录”,当某节点宕机、集群角色漂移到其他节点时,虚拟IP和网络名称要重新注册到DNS,客户端才能在第一时间找到新的连接目标。

这三个身份里,任何一个环节出问题,都会引发“数据库连不上”“集群状态异常”这类看起来像是数据库本身故障的问题。

1.2 两套集群对DNS依赖的差异点

Oracle RAC的SCAN是强依赖DNS的架构设计,Oracle官方建议SCAN域名必须由DNS解析,而且解析结果应该返回1到3个IP地址,这组IP是SCAN监听器的载体。SQL Server集群则不一样,它的DNS依赖更像是“隐形的”:集群组件本身不直接通过DNS做负载均衡,但AD域环境中的DNS记录决定了客户端能否解析到故障转移后的虚拟名称,也决定了集群能否顺利完成节点角色切换。

两套方案的共同点在于,DNS一旦失效,表面症状都会表现为“数据库连不上”“服务不可用”,但根因往往藏在解析记录、DNS服务器配置、动态更新权限这些细节里。

1.3 运维视角的一句话总结

从运维角度,我可以把DNS在集群里的作用简化成一句话:DNS是集群的“通信录+导航系统”,数据库节点、监听器、虚拟IP、客户端都在这个系统里互相查找。通信录内容错了,导航就带错路;导航失效,客户端就找不到服务。理解了这一层,后面所有配置和排障逻辑都是顺理成章的。

2. Oracle RAC的SCAN:DNS就是它的命运线

SCAN全称是Single Client Access Name,也就是单客户端访问名称。Oracle设计它的初衷,是为了解决RAC环境下客户端连接配置复杂的问题。早期版本里,客户端要根据每个节点的VIP配置连接串,节点增删都要改客户端配置。SCAN出现之后,客户端只需要配一个域名,Oracle通过SCAN监听器把连接分发到后端实例,节点变化对客户端完全透明。

2.1 SCAN的解析规则:为什么必须用DNS

很多刚接触RAC的同事会问:SCAN能不能直接写hosts文件?我见过有人图省事在/etc/hosts里加了一条SCAN的解析记录,测试环境看着没问题,但一旦涉及到生产环境、扩展到多节点、或者配置了GNS,就会踩雷。

Oracle官方明确要求SCAN解析必须使用DNS,而且不建议在hosts文件里配置SCAN。原因有三点:第一,SCAN需要解析出1到3个IP地址,hosts文件虽然也能写多条,但它不具备DNS的轮询和容错机制,客户端解析行为不可控;第二,如果使用了GNS(Grid Naming Service),SCAN的IP记录是由DNS动态分配的,hosts文件完全无法配合;第三,Oracle集群健康检查和客户端连接工具对SCAN的解析行为有严格要求,hosts文件的解析方式在某些版本下会触发警告甚至导致连接异常。

实际生产配置中,SCAN域名解析出的IP数量有讲究:不能只配一个IP,否则SCAN监听器就成了单点;也不要配超过三个,Oracle的SCAN监听器设计中,超过三个SCAN IP没有额外收益,反而增加DNS解析和监听器管理的复杂度。

2.2 SCAN解析的推荐配置模式

我个人的配置习惯是这样的:在DNS服务器上创建正向查找区域,给SCAN域名添加A记录。假设集群有3个节点,通常我会给SCAN配3个IP,对应三个节点的公共网络地址。但要注意,SCAN IP不是VIP那种“绑定在某个固定网卡上”的地址,SCAN监听器会在3个SCAN IP上同时监听,客户端连接时通过DNS轮询随机获得其中一个IP,再由SCAN监听器将请求转发到当前负载合适的实例。

如果你使用了Oracle RAC的GNS组件,IP管理会更自动化。GNS本质上是一个动态DNS代理,它会监听集群节点注册的域名请求,自动生成对应的DNS记录。这种情况下,SCAN域名解析是由GNS配合外部DNS完成的,不再需要手动维护SCAN记录。

无论是否启用GNS,我都会在配置完成后做一个测试:用nslookup或dig解析SCAN域名,确认返回的IP数量和预期一致;再从客户端远程telnet SCAN IP的1521端口,确认SCAN监听器真实可用。

2.3 SCAN配置里最常见的三个坑

第一个坑是SCAN IP和节点业务IP混用。有的管理员图省事,直接把节点VIP拿来当SCAN IP,这会让监听器和节点IP产生冲突。正确的做法是SCAN IP必须独立,不参与集群私网通信,也不得分配给任何网卡作为本地IP。

第二个坑是DNS解析顺序不一致。客户端所在的DNS服务器如果先解析到外部域,再解析内部域,SCAN连接就可能被引到错误地址。这要求运维人员在客户端和服务器两端都检查DNS搜索后缀和解析顺序。

第三个坑是TTL值设得太长。集群节点变更或者GNS重新分配记录后,DNS缓存可能导致客户端长时间连到旧IP。生产环境里我会把SCAN记录的TTL设置成5分钟到10分钟,既能保障解析效率,又能兼顾变更后的快速收敛。

3. SQL Server集群里的“域控地址”:DNS是隐形的骨架

SQL Server的高可用方案,无论是故障转移集群实例(FCI)还是Always On可用性组,都和活动目录域环境绑定得很深。这里说的“域控地址”,既包括节点配置中填写的DNS服务器IP,也包括AD域控制器在整个集群运行中承担的角色。

3.1 为什么SQL Server集群离不开AD域环境

SQL Server集群之所以强依赖AD域,核心原因是Windows故障转移集群的仲裁机制和虚拟对象注册都需要AD。集群创建时会生成两个关键对象:一个是集群名称对象(CNO),一个是虚拟计算机对象(VCO)。这些对象本质上是AD里的计算机账号,只有拥有这些账号的权限,集群才能在节点故障时把虚拟IP和网络名称切换到其他节点,并完成DNS注册更新。

简单说,没有AD域,Windows故障转移集群连创建虚拟服务器名称这一步都过不去。域控地址如果配置错误或者DNS不可达,集群服务可能启动失败,或者出现“集群网络名称无法联机”的错误,SQL Server资源一直处于联机失败状态。

3.2 域控地址在集群运行中的动态注册机制

每台集群节点加入域之后,TCP/IP属性里都要填两个关键项:首选DNS服务器和备用DNS服务器。这个DNS服务器地址就是俗称的“域控地址”,因为AD域控制器一般都兼任DNS服务器,DNS区域里存着整个域的SRV记录、计算机记录和集群虚拟名称记录。

当SQL Server集群发生故障转移时,新的节点会接管虚拟名称和虚拟IP,同时向AD和DNS发起注册更新。这个过程依赖两件事:第一,节点和域控制器之间的网络是通的;第二,集群账号对DNS区域拥有创建和修改记录的权限。这两个条件任何一个不满足,故障转移后的客户端解析就会失败。

3.3 常见误解:DNS和NETBIOS别傻傻分不清

我在项目上经常遇到一种情况:集群内部功能看着正常,应用却连不上,排查一圈下来发现是客户端用NETBIOS名称解析,而不是标准的DNS解析。SQL Server的老版本兼容NETBIOS,但新版本和Always On场景下,建议所有连接都走DNS名称解析。

另外一个误区是,有些人觉得只要域控地址能ping通就行,不关心DNS动态更新权限。实际上,集群安装时如果账号权限不足,CNO和VCO的记录创建会失败,安装程序会提示错误,但在某些异常环境下,记录创建失败并不会立刻暴露,而是等到客户端解析才发现问题。所以运维SQL Server集群时,我建议把DNS动态更新权限、Kerberos认证支持和AD对象权限一起列为安装前的检查项。

4. 实操笔记:两套集群DNS配置的落地全过程

理论讲完了,下面直接给出我在操作环境里跑过的完整流程。我尽量把关键命令和验证方法都列出来,方便有需要的朋友直接参考。

4.1 Oracle RAC SCAN的DNS配置实操

假设我的集群有三个节点,公共网络网段是192.168.10.0/24,SCAN域名规划为scan-cluster.example.com,分配的SCAN IP为192.168.10.11、192.168.10.12、192.168.10.13。

第一步,到DNS服务器的正向查找区域里添加三条A记录:

scan-cluster.example.com. IN A 192.168.10.11 scan-cluster.example.com. IN A 192.168.10.12 scan-cluster.example.com. IN A 192.168.10.13

第二步,在集群节点上建议不要配置SCAN到hosts文件,而应确保节点的/etc/resolv.conf(Linux)或者TCP/IP DNS设置(Windows)指向了正确的DNS地址,并且DNS服务器能解析scan-cluster.example.com。若使用GNS,则无需手动添加记录,GNS会完成动态注册。

第三步,在DNS服务器上验证解析:

nslookup scan-cluster.example.com dig +short scan-cluster.example.com

正常情况下应该返回三个IP,顺序可能因为DNS轮询而不同,但数量必须是三个。

第四步,在数据库服务器上验证SCAN配置是否生效,用Oracle的srvctl命令:

srvctl config scan

输出里会显示SCAN名称和对应的IP列表。如果SCAN配置正常,还可以检查GNS:

srvctl config gns

这个命令在启用了GNS的环境下会显示GNS的域名和监听端口。

第五步,从客户端侧验证SCAN监听器:

telnet scan-cluster.example.com 1521

或者用Oracle自带的tnsping工具:

tnsping scan-cluster.example.com:1521

tnsping返回OK,同时能看到连接的是哪个IP,说明SCAN解析和监听器都正常。

4.2 SQL Server集群域控与DNS配置实操

SQL Server集群环境里,我一般按以下顺序配置DNS相关项。

第一项,确认节点已经加入到AD域。在每台集群节点上用系统属性查看“隶属于”一栏,确认域后缀正确。同时,写入TCP/IPv4设置里的DNS服务器地址必须能正常解析域控制器的SRV记录。

第二项,配置集群网络名称。在故障转移集群管理器中,创建或检查“客户端访问点”。这个访问点会生成一个新的虚拟计算机名称,比如sql-cluster.example.com,并自动在DNS区域中注册对应的A记录。

第三项,检查AD中的计算机对象。打开“Active Directory用户和计算机”,展开Computers容器,应该能看到集群名称对象(CNO)和虚拟计算机对象(VCO)。如果看不到,需要检查创建集群时的权限。

第四项,验证DNS注册:

Get-ClusterResource | Where-Object {$_.ResourceType -eq "Network Name"} | Get-ClusterResourceDependency

还可以用以下命令检查集群网络名称的DNS状态:

Resolve-DnsName sql-cluster.example.com

第五项,验证节点向域控的动态更新能力。我一般会在节点上强制刷新DNS注册:

ipconfig /registerdns

然后去DNS管理器看主机记录是否更新成功,时间戳是否刷新。

4.3 两套系统连接字符串配置的变化

DNS配置完成之后,应用侧的连接字符串也要跟着调整。

Oracle RAC环境下,传统的连接串写法是:

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=node1-vip)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=node2-vip)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=prod)))

使用SCAN之后,连接串可以简化为:

jdbc:oracle:thin:@scan-cluster.example.com:1521/prod

SQL Server环境则要确保应用程序连接字符串中使用的是集群的虚拟服务器名称,而不是某个物理节点名:

Server=sql-cluster.example.com;Database=MyDB;Integrated Security=true;

这里最关键的细节是,连接字符串里的名称必须和DNS区域里注册的名称完全一致。大小写、点号、后缀都不能错,否则客户端解析不到目标,或者走了NETBIOS解析,导致认证方式异常。

5. 故障排查实录:DNS引发的集群“伪故障”

这一节我把实际运营中遇到的DNS相关故障做个汇总,每一种都给出症状、排查思路和处理办法,希望对大家有用。

5.1 SCAN解析“时好时坏”的典型处理

症状是应用间歇性报错,错误信息有时是ORA-12545,有时是ORA-12514,重启应用后可能恢复正常,过一段时间又复现。

这类问题几乎都是DNS解析列表和真实监听状态不一致导致的。客户端每次连接时通过DNS随机取得一个SCAN IP,如果某个IP对应的SCAN监听器已经失效,而DNS轮询又把请求分发到该IP上,就会出现“这次能连上、下次连不上”的现象。

排查路径分三步:

第一步,在应用服务器上连续执行nslookup,观察返回的IP列表;

第二步,确认每个SCAN IP的1521端口是否都能telnet通;

第三步,检查SCAN监听器的状态:

srvctl status scan lsnrctl status LISTENER_SCAN1

处理方式一般是把失效监听器对应的节点维护好,或者重启SCAN监听器,让三个SCAN IP重新全量注册。如果反复出现某个SCAN IP不可用,还要检查该IP是否被网卡占用、路由是否正确。

5.2 SQL Server集群故障转移后客户端解析不到

症状是集群Failover之后,应用一直报找不到sql-cluster.example.com对应的主机,但用IP地址直连新的节点却能连上。

这说明集群虚拟名称的DNS A记录没有更新到新节点IP。常见原因有三个:

第一,DNS动态更新权限不足。集群账号对DNS区域只有“安全更新”权限,但没有“动态更新”权限,导致Failover后注册失败。处理方式是在DNS区域的高级属性中,把动态更新改为“安全”或者“非安全及安全”,同时确认集群账号在DNS区域有相应权限。

第二,旧节点的DNS记录没有删除。新节点尝试注册时,DNS服务器可能拒绝覆盖旧记录。此时需要手动删除旧的A记录,或者在AD里重置集群计算机账号。

第三,DNS服务器缓存未过期。特别是客户端自己开启了DNS缓存,本地解析结果会停留一段时间。用命令刷新:

ipconfig /flushdns

在有大量客户端的环境里,建议把集群虚拟名称记录的TTL调短一些,并配合故障转移演练验证收敛时间。

5.3 集群节点启动时卡在“加入域”阶段

这个问题严格说不是数据库集群本身的问题,但我遇到过多次,多发生在VMware虚机克隆出来的SQL Server节点上。克隆VM后,节点启动时网络配置和AD注册经常出现重复SID问题,表现为加入域时提示“找不到域控制器”,但网络明明是通的。

排查要点是检查节点的DNS服务器地址是否指向了正确的域控,以及是否残留了原计算机的AD对象。处理方式是通过系统属性加入域时选择“重置计算机帐户”,或者用PowerShell移除旧的AD计算机后再重新加入域。

5.4 排查命令速查表

我把两套场景下最常用的几条排查命令整理出来,放在一起对比着用会很方便。

场景命令或操作预期结果
Oracle SCAN解析nslookup scan-cluster.example.com返回1到3个IP
Oracle SCAN监听状态srvctl status scan三个SCAN监听ONLINE
Oracle GNS状态srvctl config gnsGNS域名和端口正确显示
SQL Server集群网络名解析Resolve-DnsName sql-cluster.example.com返回当前节点IP
SQL Server DNS注册刷新ipconfig /registerdns主机记录更新成功
AD对象检查AD用户的Computers容器能看到CNO和VCO对象

表格里这几条,基本覆盖了DNS相关故障的初步定位。后面再往深走,就是抓包、看事件日志、查集群心跳,但绝大多数问题在表格这一步就能定位到七七八八。

5.5 一个容易被忽略的隐性风险:DNS防病毒软件和防火墙

最后提一个冷门但真实的坑:某次一套Oracle RAC系统升级后,SCAN连接频繁失败,排查了很久,最后发现是DNS服务器上安装的防病毒软件把Oracle的DNS请求当成了可疑流量,导致响应时延飙升。这个案例提醒我,DNS基础服务要纳入全链路监控,而不仅仅看数据库层和主机层。

防火墙方面也要注意,除了标准的53端口,无论Oracle集群还是SQL Server集群,都需要确保DNS、Kerberos、RPC动态端口等在节点间和客户端侧均能正常通信。建议在变更单里把DNS解析响应时间、动态注册成功率纳入监控指标。

6. 我在两套集群DNS运维里真正学到的东西

文章写到这里,技术细节已经聊得够多了,最后分享几条个人体会。

DNS在集群架构里最容易被低估,因为它平时太“安静”了。出问题的时候,大家的第一反应都是查数据库日志、查集群日志,很少有人在第一时间去看DNS。但根据我的维护经验,DNS相关的集群故障占比相当高,尤其是Oracle RAC的SCAN解析问题和SQL Server集群的虚拟名称注册问题,几乎每隔一段时间就会遇到一次。

所以我会习惯性地在每套集群的监控设计里,额外加上一组DNS专项检查项,比如SCAN域名的解析结果数量、SQL Server虚拟名称的A记录是否指向当前联机节点、DNS动态更新的时间戳是否新鲜。这些检查在平时看起来不起眼,但真正遇到故障时,它们能帮我把定位时间从小时级压缩到分钟级。

还有一个笨但有效的方法:每次做集群扩容、节点重启、网络变更之后,都强制做一轮DNS验证。Oracle这边就是反复nslookup加tnsping,SQL Server这边就是Resolve-DnsName加故障转移演练。哪怕看起来一切正常,我也会顺手看一眼DNS记录的时间戳,确认记录确实被刷新过,而不是从缓存里读出来的假象。

最后再分享一个配置建议:生产环境里不要图省事把DNS的TTL调得很大。SCAN记录和集群虚拟名称记录,TTL控制在5到10分钟比较合适。太短会增加DNS服务器压力,太长会拖慢故障收敛速度。这个参数需要在容错与性能之间找一个平衡点,根据我多个项目的实践,8分钟是一个稳妥的起点,后续再根据实际变更频率做微调。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询