简介:针对在 SQL Server 2016 Always On 集群中新增数据库节点的需求,这份由亲测实践整理而成的操作文档,可供数据库管理员和运维人员直接参考。资源为单个 docx 文件,压缩包约 1.92MB,内含大量界面截图、逐步操作说明和关键配置示例,版式清晰,适合按图索骥执行。已有 102 人学习/下载,适用于在生产或测试环境中向现有可用性组平滑加入新副本的场景,这类集群扩容操作在运维中较为常见。内容从环境角色规划入手,先梳理主副本、辅助副本及计划添加副本的 IP、主机名和读写归属,再依次覆盖新节点安装 SQL Server、启用故障转移群集功能、修改 hosts 文件、将节点加入 Windows 故障转移群集、开启 Always On 并添加到可用性组等完整链路。每个环节都有对应截图与实测说明,能帮助 DBA 提前识别常见疏漏,减少扩容操作风险。
1. 往 Always On 集群里加只读副本:不是跑完向导就完事
在 SQL Server 2016 的 Always On 集群里加一个新节点,表面上是个标准的“添加副本”向导,真上手你会发现它牵扯 Windows 故障转移集群的节点成员身份、SQL Server 服务的启动账号、端点权限、同步模式,任何一个环节没对齐,结果都是副本一直显示“未同步”。这篇用一个三节点环境来拆:主副本负责写(test51)、现有辅助副本负责读(test52)、第三个节点(test209)计划作为新只读副本加入 testgroup1 可用性组,重点落在“加入 Windows 集群、开启 Always On、进可用性组”三步的实操细节和踩坑记录上。适合 DBA 和运维工程师照着复现,也适合第一次在已有集群上动刀、怕把生产搞挂的人提前看清边界。
2. 加入 Windows 故障转移集群:这一步错后面全崩
2.1 为什么必须先把 Windows 集群搞定
Always On 可用性组是跑在 Windows 故障转移集群(WSFC)之上的,不是 SQL Server 自己独立维护高可用。SQL Server 2016 的 Always On 依赖 WSFC 提供健康检测、仲裁投票、故障转移决策。新节点如果没有先加入 WSFC,即便 SQL Server 装好了、服务也开着,打开 SSMS 里“启用 Always On 可用性组”的选项也是灰的——因为在操作系统层它还不是集群的法定成员。
这个设计经常被刚上手的人忽略。有人直接在新节点上装完 SQL Server 就跑去“添加副本”,结果要么连不上、要么提示集群节点不是可用性组的候选节点。根因就在 Windows 集群层没通过。所以顺序必须是:装 SQL Server → 加故障转移集群功能 → 改 hosts → 加节点进 WSFC → 启用 Always On → 加副本。跳一步,后面就是无尽的玄学报错。
2.2 故障转移集群功能怎么开
在新节点上安装 SQL Server 软件这一步按常规来,实例名、排序规则、目录最好跟现有节点保持一致,否则后面维护要分两套路径。装完之后先别碰 SQL Server 配置,先打开“服务器管理器”,点“添加角色和功能”,一路下一步到“功能”页,勾选“故障转移群集”。
这里有个容易漏的点:弹出的对话框会提示“添加功能”确认,必须点掉,否则功能没装全。故障转移群集依赖一些底层功能组件,比如“远程服务器管理工具”里的群集管理单元,不一起装上的话,后续在集群管理器里看不到对应操作项。装完功能后重启一次系统,再进“故障转移群集管理器”确认能正常打开,别急着操作。
2.3 hosts 文件:双端都要改,少一个就找不到机器
修改 hosts 是一个看着简单、错起来很隐蔽的环节。现有节点(test51、test52)的C:\Windows\System32\drivers\etc\hosts里要添加新节点的 IP 和主机名映射:
10.106.210.209 test209.test.com同时新节点自己的 hosts 里要把全部节点的 IP 和主机名都加上:
10.106.210.51 test51.test.com 10.106.210.52 test52.test.com 10.106.210.209 test209.test.com为什么不依赖 DNS?很多内网环境的 DNS 解析策略或安全组策略会阻断 SQL Server 和集群服务对主机名的直接解析,尤其在多网卡、防火墙分段的环境里,hosts 是让集群通信走内网管理段的最直接手段。改完 hosts 建议在命令行执行ping test209.test.com确认解析结果指向正确的 IP,同时确认集群节点之间 TCP 445、UDP 3343(集群通信端口)能通。
2.4 把新节点加进 WSFC:连接和验证细节
在现有主节点上打开“服务器管理器”,点“工具”→“故障转移群集管理器”。如果管理器打开后并没有连到你现有的集群,先右键“故障转移群集管理器”,选择“连接到群集”,输入现有集群的名称(比如 testcluster 或你实际的名字),确认连上了再继续。
右侧操作栏里点“添加节点”,输入新节点的主机名 test209,点“添加”,然后“下一步”。验证界面会让你逐个检查存储、网络、集群配置,这些验证不一定全部通过才能加,但网络部分的错误要看清楚——如果“网络绑定”或“集群通信”报了 ERROR,多半是 hosts 没改对或防火墙把集群端口拦了,解决完再继续。
验证通过后,向导会显示“节点已添加”,此时在集群管理器的“节点”目录下应该能看到 test209 显示为“运行”。如果这里只显示“暂停”或“不可用”,先别进下一步,检查 Windows 事件日志里 Cluster 服务的报错,通常能直接看到问题。
提示:添加节点这一步是在 Windows 集群层面操作,跟 SQL Server 没关系,失败时不要跑去翻 SQL Server 错误日志,方向错了查半天都是空的。
3. 打开 Always On 开关:账号、权限和服务重启三件事
3.1 启用 Always On 可用性组前的系统前置条件
Windows 集群就绪后,新节点的 SQL Server 需要开启 Always On 功能。这一步在很多文档里被一句话带过,但它牵扯 SQL Server 服务的启动账号、集群服务账号、权限分配三件事。
SQL Server 服务账号必须对 WSFC 有访问权限,而且该账号必须能读取集群对象。常见做法是让所有 SQL Server 实例使用同一个域账号运行服务,这样加入 WSFC 后权限天然是一致的。如果新节点用了不同的本地账号或服务账号,集群永远认为这个节点的 SQL Server 实例没有权限参与可用性组。
另外一点,如果 WSFC 是多节点的,SQL Server 服务账号还要有对集群名称对象(CNO)的权限,因为可用性组会用到 WSFC 的虚拟名称。这一步通常由加域时的配置完成,但如果你维护的集群不在域环境里或者账号不是标准域账号,就要手工确认。
3.2 打开开关的具体操作
在 SQL Server 配置管理器里,找到 SQL Server(MSSQLSERVER) 服务,右键属性切到“AlwaysOn 高可用性”页,勾选“启用 AlwaysOn 可用性组”。注意,这之后系统会要求重启 SQL Server 服务。
重启后别急着做任何事,先用以下命令确认开关确实生效:
SELECT servicename, is_alwayson_enabled FROM sys.dm_server_services WHERE servicename LIKE 'SQLSERVER%'正常情况is_alwayson_enabled应该返回 1。如果返回 0,说明勾选没生效,多半还是服务账号或集群权限的问题,这时候去事件日志里搜“AlwaysOn”相关条目,会比瞎猜有用得多。
提示:SQL Server 2016 的 Always On 只能启用一个可用性组吗?不是,一个实例可以承载多个可用性组,但每个副本只能属于一个可用性组。多组场景下,心跳网络和只读路由的配置会复杂一个量级,本文先不展开。
3.3 服务账号密码变更的连锁影响
项目正文里提到“输入密码后提示重启服务生效”,这里说的其实是 SQL Server 服务的登录密码。如果你的 SQL Server 服务是用域账号运行的,并且密码修改过,一定要先确认集群里所有 SQL Server 节点都更新了服务账号密码,否则会出现一种诡异情况:新节点服务起来了,但 WSFC 检测到这个 SQL Server 实例“不健康”,可用性组添加副本时会直接失败。
我的建议是,在改服务账号密码前,先在每个节点上用 SQL Server 配置管理器更新密码,再重启 SQL Server 服务。顺序不能乱,更不能只改一个节点。密码更新后最好执行一次集群验证:“故障转移群集管理器”里右键集群名称,选择“验证群集”,完整跑一遍,确认没有服务账号相关的告警。
4. 把新副本添进可用性组:向导之外的真实工作
4.1 添加副本向导的完整流程
完成前面的准备后,登录数据库集群侦听 VIP,打开 SSMS 的对象资源管理器,展开“AlwaysOn 高可用组”→“可用性组”,右键目标可用性组(这里是 testgroup1),选择“添加副本”。
向导会要求指定副本实例。填入 test209.test.com 的 SQL Server 实例名,点“连接”,然后你会看到可用性组当前副本列表和新增副本的同步模式选择。这里有两个模式:同步提交(Synchronous)和异步提交(Asynchronous)。
对只读副本来说,通常用异步提交就够了——因为它不承担故障转移责任,只提供读负载扩展。但如果你的业务要求只读副本的数据延迟尽量小,且在故障转移时能转正,那可以选同步提交。注意,同步提交会拖累主库提交性能,每个事务要等辅助副本确认写入,延迟升高是必然的。
4.2 端点权限与连接字符串
添加副本时向导会自动创建可用性组端点,但有个常见的坑:如果新节点上 SQL Server 之前没配置过数据库镜像端点,需要手工创建或让向导完成。向导通常会创建端点和授权,但如果你遇到“无法访问端点”的报错,就需要检查以下内容:
SELECT name, type_desc, port, state_desc FROM sys.tcp_endpoints WHERE type = 2state_desc应为 STARTED。如果为 STOPPED 或 DISABLED,需要手动开启。
另外,端点权限非常关键——所有副本节点上的账号必须有 CONNECT 权限。常见做法是给所有可用性组成员实例的启动账号都赋 Connect 权限,执行以下命令:
GRANT CONNECT ON ENDPOINT::Hadr_endpoint TO [YOURDOMAIN\sqlservice]如果这里漏了,副本加进去后会出现反复“连接失败”“同步挂起”的日志,且状态栏里看不到具体原因,非常折磨人。
然后是连接字符串。只读副本的连接字符串,ApplicationIntent 必须设为 ReadOnly:
Server=tcp:listener.test.com,1433;Database=YourDB;ApplicationIntent=ReadOnly;有人把ApplicationIntent写成ReadOnly之外的任意值,连接会被路由到主副本,读负载没减轻,自己还觉得配置没问题——这是用监听器做读写分离时最常见的翻车点。
4.3 数据同步:初始同步还是备份还原
添加副本时向导会问“数据同步选项”,有三个选择:完整(Full)、仅备份(Backup only)、跳过(Skip)。
如果你在生产库上选“完整”,向导会先做一个完整备份,然后在新副本上还原并加入可用性组。对大库(比如超过 1TB)来说,这个操作耗时极长,而且向导在还原时会占用大量磁盘 IO 和网络带宽,可能拖垮主库性能。
我的经验是,大库场景直接选“跳过”,手工做备份和日志还原,最后以JOIN方式加入可用性组。具体的做法是:
在主库上执行完整备份,再备份当前日志,把备份文件复制到新节点,在新节点上还原为NORECOVERY状态,然后手工执行:
ALTER AVAILABILITY GROUP testgroup1 JOIN;然后把数据文件加入可用性组:
ALTER DATABASE YourDB SET HADR AVAILABILITY GROUP = testgroup1;这样做的优势是时间点完全可控,而且不会对主库并发造成不可预期的压力。缺点是操作多了两步,需要你手动保证日志链衔接完整——中间丢一个日志备份,同步就断了。
4.4 只读路由配置
只读副本加进去后,要让它真正承担读流量,还得配置只读路由。这步是很多人到最后才发现的坑:副本状态显示“已同步”,但业务连接永远打不到它身上。
配置路由需要更新可用性组,实现在主副本上执行:
ALTER AVAILABILITY GROUP [testgroup1] MODIFY REPLICA ON N'test51.test.com' WITH (SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY)); ALTER AVAILABILITY GROUP [testgroup1] MODIFY REPLICA ON N'test51.test.com' WITH (PRIMARY_ROLE(READ_ONLY_ROUTING_LIST = ('test209.test.com','test52.test.com')));第一句允许辅助副本接受只读连接,第二句告诉主副本路由优先级先发给 test209,再发给 test52。如果只配了第一句,忘了第二句,连接串就找不到目标。
5. 常见问题与避坑记录:五条高频翻车现象
5.1 添加副本时提示“无法连接到副本”
现象:向导测试连接报错,提示“无法连接到副本实例”(错误 1801 或 18456)。
原因:最常见是 hosts 没配好或 SQL Server 远程连接未开启。SQL Server 2016 默认未启用 TCP/IP 协议的情况很多见,如果新节点只是装完系统、SQL Server 配置管理器里没启动 TCP/IP,连接必然失败。
解决:先在配置管理器里确认 TCP/IP 已启用并监听固定端口(默认 1433),然后 telnet 测一下通不通:telnet test209.test.com 1433。然后再试一次向导。另检查防火墙允许入站 TCP 1433。
5.2 副本显示“未同步”,同步健康状态为“Not Synchronizing”
现象:副本成功加入,但仪表盘上一直是“Not Synchronizing”,数据不追平。
原因:日志备份和还原链有缺口,或者可用性组端点的权限不对。尤其是手工备份还原后没跟上后续日志备份,同步起不来。
解决:先看看sys.dm_hadr_database_replica_states里synchronization_state_desc值,如果是NOT SYNCHRONIZING,通常要重新做一次日志备份并RESTORE ... WITH NORECOVERY来续上链,别指望它能自愈。
5.3 加副本时向导没有“完整”选项
现象:数据同步选项里“完整”是灰的,只能选“跳过”或“仅备份”。
原因:新实例上 SQL Server Agent 没启用,或者备份权限不足。完整选项依赖 SQL Server Agent 执行备份作业。
解决:启动新节点 SQL Server Agent,给它配置为自动启动。如果是权限问题,给执行向导的登录账号授予 Backup Operator 或 sysadmin 角色。
5.4 加入 WSFC 后节点显示“暂停”或“不可用”
现象:集群管理器里能看到节点,但状态一直是 Paused 或 Up 但没有上下文。
原因:节点加进去之后,集群服务没能和节点上的 Cluster Service 完成握手,可能是防火墙拦截了 UDP 3343,也可能是该节点上有多个网卡且网络配置没选对。
解决:在集群管理器“网络”里确认新节点的网络适配器被识别为“集群通信”允许的网卡,如果不确定,用 PowerShell 查看Get-ClusterNetwork的 Role 字段。或者,把节点状态手动恢复:右键节点→“恢复”。
5.5 只读副本连接到了主库
现象:连接串明明指定了只读,SSMS 里却显示连到了主副本。
原因:只读路由没配或ApplicationIntent没设置。还有种可能是监听器在 DNS 层面没有对新副本注册。
解决:确认两段路由 SQL 都执行过,并用 PowerShell 查看(Get-ClusterResource "可用性组监听器").State确认监听器是否正常。连接串里务必带上ApplicationIntent=ReadOnly,而且不能用 IP 直连,要连可用性组监听器名称。
提示:上述五条如果全排查完状态还是不对,建议直接在目标节点上看 SQL Server 错误日志,尤其是
HADR相关的条目。Always On 的日志虽然冗长,但八成问题在日志里能找到第一现场。
6. 验证与收尾:用动态管理视图验收一个“真正可用”的只读副本
副本加入后,最有用的事情不是看 UI 上那个绿色对勾,而是用几条系统视图把自己确认到位的状态固化下来。我每次配完都会跑一遍这套验证逻辑,确认后才算真正交付。
首选在主副本上看sys.dm_hadr_availability_replica_states:
SELECT ar.replica_server_name, ar.availability_mode_desc, ar.secondary_role_allow_connections_desc, ars.role_desc, ars.operational_state_desc, ars.connected_state_desc, ars.synchronization_health_desc FROM sys.dm_hadr_availability_replica_states ars JOIN sys.availability_replicas ar ON ar.replica_id = ars.replica_id关注secondary_role_allow_connections_desc是否为READ_ONLY,operational_state_desc是否 ONLINE,connected_state_desc是否 CONNECTED。三条都符合,副本才是真正可用,不然只能是“纸面同步”。
再在辅助副本上确认数据库同步进度:
SELECT db_name(database_id) AS database_name, synchronization_state_desc, synchronization_health_desc, last_hardened_lsn, end_of_log_lsn FROM sys.dm_hadr_database_replica_states WHERE is_local = 1last_hardened_lsn应该持续增长,跟主库差距保持稳定。如果你看到last_hardened_lsn长期不动,说明日志传输已经中断,复现 5.2 的方案解决。
最后,实际做一次读连接测试,确认 ApplicationIntent 被正确路由:
SELECT @@SERVERNAME, HOST_NAME()如果查出来是 test209,说明只读路由生效了。到这里,一个真正可以接读流量的新副本才算落地完整。
四个月前我第一次在模拟项目X 上做同样操作时,跳过 hosts 直接加 WSFC,结果测试环境折腾了大半个工作日,节点反复“添加失败”,最后发现 DNS 解析串到了别的网段。从那以后我每次进集群操作前,都强制先在一个文本文件里确认好节点名称、IP 映射、防火墙端口三段信息,再动任何一个开关。希望这篇能让你在真实环境里少走这段弯路。
本文还有配套的精品资源,点击获取