☰
SQL Server 2016 AlwaysOn 新增节点实战避坑指南
2026/11/4 2:51:33 网站建设 项目流程

简介:本资源是一份面向SQL Server数据库管理员与高可用架构实施人员的实战操作指南,聚焦在SQL Server 2016 AlwaysOn可用性组集群中新增数据库节点的完整流程,解决生产环境中动态扩容、灾备节点补充等关键运维需求。资源以单个1.92MB的Word文档(.docx)形式提供,内容结构清晰,涵盖环境拓扑说明、Windows故障转移群集加节点、hosts文件配置、SQL Server服务启用、AlwaysOn功能开启及可用性组副本添加等六大核心步骤,每步均配实操截图并标注关键参数与验证要点。已有103人学习下载,内容经作者YABIGNSHI在真实集群环境亲测可行,不仅提供标准化操作路径,更包含IP规划示例、权限配置提示、常见连接失败排错线索等一线经验沉淀,适合中高级DBA快速复现与落地部署。

1. 在 SQL Server 2016 AlwaysOn 集群中新增数据库节点:一个看似简单却极易翻车的高危操作

你刚接到运维工单:“在现有 SQL Server 2016 AlwaysOn 集群里加一台新节点,今天下班前上线。”看起来就几步勾选、点几下鼠标——但如果你没在 test51/test52 上提前验证过 Windows 群集证书链、没确认新节点 test209 的 SQL Server 实例名是否与主副本完全一致、甚至没检查过三台机器的 .NET Framework 4.6.2 补丁版本是否对齐,那恭喜,你将在凌晨两点面对“添加副本失败:错误 41107”、“连接超时:无法建立到可用性端点的 TCP 连接”、或者更玄学的“同步状态始终为 NOT SYNCHRONIZING(挂起)”。这不是理论风险,而是某高校数据库实验室在一次模拟项目X升级中真实发生的三次回滚事件。本文专为已部署过至少一套 SQL Server 2016 AlwaysOn、熟悉基本群集概念、但对跨节点证书信任链、端口防火墙穿透粒度、以及 SQL Server 服务账户权限继承机制仍存模糊认知的 DBA 和系统工程师而写。它不讲高可用原理,只聚焦「从零配置 test209 到它真正出现在 SSMS 的可用性组副本列表里并显示 SYNCHRONIZED」这一条血路。


2. 准备工作:环境对齐是隐形地雷,不是可选项

2.1 操作系统与补丁版本必须严格统一

SQL Server 2016 对 Windows Server 2012 R2 / 2016 的补丁敏感度远超直觉。我们遇到过最隐蔽的一次失败:test51 和 test52 已安装 KB4534310(2020 年 1 月累积更新),而 test209 是全新安装的 Windows Server 2016 标准版,默认只带 KB4041691。结果在“添加节点到 Windows 故障转移群集”阶段,test209 始终报错0x800706ba(RPC 服务器不可用),排查两小时才发现是 SMB 协议栈版本不兼容导致群集心跳包被静默丢弃。

提示:在所有节点(包括待加入的 test209)上执行以下命令,确保输出完全一致:

# 查看 OS 版本与最新安装的补丁 systeminfo | findstr /B /C:"OS Name" /C:"OS Version" /C:"Hotfix(s)" # 查看 .NET Framework 版本(SQL Server 2016 强依赖 4.6.2+) (Get-ItemProperty "HKLM:SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full").Release
  • ✅ 推荐组合:Windows Server 2016 Datacenter(1607,OS Build 14393.x) + 最新累积更新(如 KB5004237) + .NET Framework 4.6.2(Release 值 ≥ 394802)
  • ❌ 绝对禁止:test209 使用 Windows Server 2019 或 2022;或任意节点未安装 KB4054517(修复了 AlwaysOn 端点 TLS 握手缺陷)

2.2 SQL Server 安装参数必须镜像主副本

“略”字害死人。2.1 节说的“安装 SQL Server 软件略”,实际藏着三个致命细节:

  1. 实例名必须为MSSQLSERVER(默认实例):如果主副本用的是命名实例(如SQL2016PROD),则新节点也必须用同名实例。AlwaysOn 不支持跨实例名同步。
  2. 排序规则(Collation)必须完全一致:执行SELECT SERVERPROPERTY('Collation'),三台机器结果必须一字不差。常见坑是 test209 安装时选了Chinese_PRC_CI_AS,而 test51 是SQL_Latin1_General_CP1_CI_AS,后续添加副本时直接报错 35250(可用性组不兼容)。
  3. 服务账户必须使用域账户,且权限需预配置:不能用NT Service\MSSQLSERVER本地账户。必须创建专用域账户(如DOMAIN\sqlsvc-alwayson),并在所有节点上赋予:
    • “作为服务登录”(Log on as a service)
    • “替换进程级令牌”(Replace a process level token)
    • 对C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\目录的完全控制权

2.3 网络与 DNS:hosts 文件只是起点,不是终点

原文只提修改hosts文件,但这仅解决主机名解析,远不足以支撑 AlwaysOn 正常通信。必须完成以下三项:

  1. DNS 正向/反向解析双向验证:在 test209 上执行nslookup test51.test.com和nslookup 10.106.210.51,两者都必须返回正确结果。若 DNS 服务器未配置反向解析(PTR 记录),则必须在每台机器的hosts文件中同时写入正向和反向映射:
# C:\Windows\System32\drivers\etc\hosts (所有节点均需此内容) 10.106.210.51 test51.test.com test51 10.106.210.52 test52.test.com test52 10.106.210.209 test209.test.com test209 # 反向解析行(关键!AlwaysOn 内部通信会尝试反查) 10.106.210.51 test51.test.com 10.106.210.52 test52.test.com 10.106.210.209 test209.test.com
  1. Windows 防火墙必须放行四个端口:不仅是 SQL Server 默认端口 1433,AlwaysOn 依赖的端口必须显式开放:

    • TCP 5022:AlwaysOn 可用性端点(必须!)
    • TCP 135:DCOM 端口(群集 RPC 通信)
    • TCP 3343:群集服务心跳端口
    • UDP 3343:同上(UDP 心跳)
  2. 禁用 IPv6(生产环境强烈建议):SQL Server 2016 的 AlwaysOn 在混合 IPv4/IPv6 环境下存在已知握手失败问题。在所有节点执行:

# 禁用 IPv6 协议栈(重启生效) Set-NetIPInterface -AddressFamily IPv6 -Disabled true # 验证 Get-NetIPInterface -AddressFamily IPv6 | Select-Object ifIndex, InterfaceDescription, AddressFamily, Enabled # 输出应为 Enabled=False

3. Windows 故障转移群集(WSFC)集成:比点击“添加节点”复杂十倍

3.1 预检:运行集群验证向导(Cluster Validation Wizard)是唯一可信依据

不要跳过这一步。在当前主节点(test51)上打开“故障转移群集管理器”,右键“故障转移群集管理器” → “验证配置”。必须勾选:

  • “所有节点”(test51, test52, test209)
  • “网络”(验证所有网卡连通性)
  • “存储”(即使不共享存储,也要验证 CSV 仲裁盘可见性)
  • “系统配置”(检查时间同步、域成员身份、服务状态)

关键观察点:验证报告中“网络”部分必须显示test209 ↔ test51和test209 ↔ test52的“节点间通信”状态为Passed,且延迟< 10ms。若出现Warning: Network interface is not configured for cluster use,说明该网卡未在群集管理器中启用(右键网卡 → “启用用于群集通信”)。

3.2 添加节点:必须用 FQDN,且顺序不能错

原文说“输入要添加的服务器的主机名”,这是最大误区。必须输入完全限定域名(FQDN),即test209.test.com,而非test209。原因:群集服务内部使用 Kerberos 认证,短名无法生成有效 SPN。

操作路径(在 test51 上):

  1. 故障转移群集管理器 → 右键集群名称(如CLUSTER-TESTGROUP1)→ “添加节点”
  2. 在“指定要添加的服务器”对话框中,手动输入test209.test.com(不能从下拉列表选,列表可能缓存旧信息)
  3. 点击“下一步”,进入“验证”阶段 —— 此时群集服务会自动在 test209 上启动ClusSvc服务、注册群集资源、同步仲裁配置
  4. 若卡在“正在验证节点”超过 2 分钟,立即检查 test209 的 Windows 事件查看器 → “系统”日志,过滤事件 ID1191(群集服务启动失败)或1205(网络检测失败)

3.3 仲裁配置:三节点集群必须用“多数节点”模式

test51/test52/test209 是三节点集群,仲裁模型必须设为Node Majority(节点多数)。若沿用原双节点时代的“节点和磁盘多数”,则添加 test209 后,仲裁票数变为 3(节点)+1(磁盘)=4,但法定人数(Quorum Required)为(4/2)+1 = 3,此时任意两个节点宕机,集群即停止服务 —— 这违背了增加节点提升容灾能力的初衷。

设置方法(在任意节点):

# 查看当前仲裁配置 Get-ClusterQuorum # 设置为节点多数(无磁盘仲裁) Set-ClusterQuorum -NodeMajority # 验证 Get-ClusterQuorum | Select-Object QuorumType, QuorumResource # 输出应为 QuorumType = NodeMajority, QuorumResource = <null>

4. SQL Server AlwaysOn 配置:开启服务只是序章,端点与证书才是核心

4.1 开启 AlwaysOn 功能:必须重启服务,且验证服务账户权限

原文说“右击 SQL Server(MSSQLSERVER)-属性 → 输入密码 → 提示重启”。但此处有两大陷阱:

  1. 密码必须是域账户密码,不是本地管理员密码:若服务账户是DOMAIN\sqlsvc-alwayson,则此处必须输入该账户密码。输错会导致 SQL Server 服务无法启动,错误日志中出现Logon failure: unknown user name or bad password。
  2. 重启后必须验证服务是否以正确账户运行:
# 在 test209 上执行 Get-WmiObject Win32_Service | Where-Object {$_.Name -eq 'MSSQLSERVER'} | Select-Object Name, StartName, State # StartName 必须为 DOMAIN\sqlsvc-alwayson,State 必须为 Running

4.2 创建可用性端点:端口、证书、加密缺一不可

AlwaysOn 节点间通信通过专用端点进行,必须在 test209 上手动创建,且参数必须与 test51/test52逐字匹配:

-- 在 test209 的 SQL Server Management Studio 中执行(以 sysadmin 身份) -- 1. 创建主密钥(若不存在) CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'YourStrongPassword123!'; GO -- 2. 创建证书(注意:证书名必须与 test51 上完全一致,此处假设为 'HADR_Cert_test51') CREATE CERTIFICATE HADR_Cert_test209 WITH SUBJECT = 'HADR Certificate for test209', START_DATE = '2023-01-01', EXPIRY_DATE = '2030-01-01'; GO -- 3. 备份证书(用于分发给其他节点) BACKUP CERTIFICATE HADR_Cert_test209 TO FILE = 'C:\temp\HADR_Cert_test209.cer' WITH PRIVATE KEY ( FILE = 'C:\temp\HADR_Cert_test209.pvk', ENCRYPTION BY PASSWORD = 'CertPrivateKeyPass123!' ); GO -- 4. 创建端点(端口必须为 5022,ROLE 必须为 ALL,ENCRYPTION 必须为 REQUIRED) CREATE ENDPOINT [Hadr_endpoint] STATE = STARTED AS TCP (LISTENER_PORT = 5022, LISTENER_IP = ALL) FOR DATA_MIRRORING ( ROLE = ALL, AUTHENTICATION = CERTIFICATE HADR_Cert_test209, ENCRYPTION = REQUIRED ALGORITHM AES ); GO

参数说明:

  • LISTENER_IP = ALL:监听所有网卡,避免因多网卡导致端点绑定失败
  • ROLE = ALL:允许该节点担任主/辅助角色(若只做只读副本,可设为SECONDARY,但新增节点初期建议ALL)
  • ENCRYPTION = REQUIRED ALGORITHM AES:强制加密,且必须用 AES(SQL Server 2016 不支持 RC4)

4.3 证书互信:三节点必须形成闭环信任链

这是最容易被忽略、也最致命的步骤。test209 的证书必须被 test51/test52 信任,反之亦然。操作流程是双向分发+双向创建:

  1. 将 test209 的证书文件(.cer)复制到 test51/test52 的C:\temp\下
  2. 在 test51 上执行(以 sysadmin 身份):
-- 在 test51 上为 test209 创建登录名和用户 CREATE LOGIN login_test209 FROM CERTIFICATE HADR_Cert_test209; CREATE USER user_test209 FOR LOGIN login_test209; -- 授予连接端点权限 GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [login_test209]; GO
  1. 同理,在 test209 上为 test51/test52 创建对应登录名、用户并授权
  2. 验证信任:在 test209 上执行SELECT * FROM sys.certificates,应看到HADR_Cert_test51和HADR_Cert_test52两条记录;在 test51 上应看到HADR_Cert_test209

5. 常见问题与血泪排查:那些让你怀疑人生的报错,其实都有解法

5.1 现象:添加副本时卡在“正在连接到辅助副本”,10 分钟后报错 41107

原因:test209 的防火墙未开放 TCP 5022 端口,或 Windows 防火墙策略阻止了入站连接。
解决:

  • 在 test209 上执行netsh advfirewall firewall show rule name="SQL Server AlwaysOn Endpoint",确认状态为Enabled
  • 若无此规则,手动创建:
New-NetFirewallRule -DisplayName "SQL Server AlwaysOn Endpoint" -Direction Inbound -Protocol TCP -LocalPort 5022 -Action Allow -Profile Domain
  • 在 test51 上用Test-NetConnection test209.test.com -Port 5022验证连通性

5.2 现象:副本状态显示 “NOT SYNCHRONIZING”,且日志中反复出现 “The remote endpoint is in a disconnected state”

原因:证书未正确导入或权限未授予。常见于只在 test209 上创建了证书,但忘记在 test51 上为 test209 创建登录名。
解决:

  • 在 test51 上执行SELECT * FROM sys.database_mirroring_endpoints,确认state_desc为STARTED
  • 执行SELECT * FROM sys.server_permissions WHERE permission_name = 'CONNECT' AND class_desc = 'ENDPOINT',检查是否有login_test209的 CONNECT 权限
  • 若缺失,补执行GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [login_test209]

5.3 现象:添加副本成功,但数据库同步状态始终为 “SUSPENDED”,手动恢复时报错 35250

原因:数据库恢复模式不是 FULL,或未做完整备份。AlwaysOn 要求数据库必须处于 FULL 恢复模式,且已有至少一个完整备份。
解决:

  • 在 test51 上检查:SELECT name, recovery_model_desc FROM sys.databases WHERE name = 'YourDBName',必须为FULL
  • 若非 FULL,执行:
ALTER DATABASE YourDBName SET RECOVERY FULL; BACKUP DATABASE YourDBName TO DISK = 'C:\backup\YourDBName_Full.bak';
  • 关键:备份必须在主副本(test51)上执行,且备份文件需手动复制到 test209 的相同路径,再在 test209 上还原(WITH NORECOVERY)

5.4 现象:SSMS 中右键可用性组 → “添加副本”,但 test209 不在下拉列表中

原因:test209 的 SQL Server 服务未启用 AlwaysOn,或未重启。
解决:

  • 在 test209 上执行SELECT SERVERPROPERTY('IsHadrEnabled'),返回值必须为1
  • 若为0,说明“SQL Server 配置管理器”中未勾选“启用 AlwaysOn 可用性组”,或勾选后未重启服务
  • 重启服务后再次验证

5.5 现象:所有步骤完成后,客户端连接侦听器 VIP 时,偶尔路由到 test209(只读副本)并报错 “The target database, ‘xxx’, is participating in an availability group and is currently not accessible for queries”

原因:侦听器未配置只读路由列表(Read-Only Routing List),客户端驱动未启用 ApplicationIntent=ReadOnly。
解决:

  • 在主副本(test51)上为可用性组配置只读路由:
ALTER AVAILABILITY GROUP [testgroup1] MODIFY REPLICA ON 'test209.test.com' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('test209.test.com','test52.test.com'))); GO
  • 应用程序连接字符串必须包含ApplicationIntent=ReadOnly

6. 验证与收尾:用三步真验证代替“看起来成功”

6.1 第一步:验证 Windows 群集层面的健康度

在任意节点打开 PowerShell,执行以下命令,结果必须全部为True:

# 1. 所有节点在线且就绪 (Get-ClusterNode).State -eq 'Up' # 2. 群集服务状态正常 (Get-ClusterResource | Where-Object {$_.ResourceType -eq 'Network Name'}).State -eq 'Online' # 3. 仲裁配置生效 (Get-ClusterQuorum).QuorumType -eq 'NodeMajority' # 4. test209 的群集网络已启用 (Get-ClusterNetwork | Where-Object {$_.Name -eq 'Cluster Network 1'}).AutoAssignVLAN -eq $false

若任一为False,立即回到第 3 章排查。不要跳过这一步直接进 SQL 层验证。

6.2 第二步:验证 SQL Server AlwaysOn 端点与证书链

在 test209 上执行以下查询,输出必须符合表格要求:

查询语句期望结果说明
SELECT * FROM sys.endpoints WHERE type_desc = 'DATABASE_MIRRORING'state_desc = 'STARTED',port = 5022端点必须启动且监听 5022
SELECT name, pvt_key_encryption_type_desc FROM sys.certificates WHERE name LIKE 'HADR%'pvt_key_encryption_type_desc = 'ENCRYPTED_BY_PASSWORD'证书私钥必须加密,否则无法跨节点使用
SELECT * FROM sys.dm_hadr_availability_replica_states WHERE replica_id = (SELECT replica_id FROM sys.availability_replicas WHERE replica_server_name = 'test209.test.com')role_desc = 'SECONDARY',operational_state_desc = 'ONLINE',connected_state_desc = 'CONNECTED'副本必须在线且已连接

技巧:若connected_state_desc为DISCONNECTED,立即在 test51 上执行SELECT * FROM sys.dm_hadr_availability_replica_cluster_states,检查is_local为 1 的行中is_connected是否为 1。若否,说明 test51 无法连接 test209 的端点,回归 5.1 节排查防火墙。

6.3 第三步:执行端到端业务级验证

这才是真正的“跑通”。在 SSMS 中连接侦听器 VIP(如tcp://testgroup1-listener.test.com:1433),执行以下脚本:

-- 1. 检查当前连接的副本角色(应为 PRIMARY) SELECT ar.replica_server_name, ars.role_desc, ars.operational_state_desc FROM sys.dm_hadr_availability_replica_states ars JOIN sys.availability_replicas ar ON ars.replica_id = ar.replica_id WHERE ars.is_local = 1; -- 2. 强制将 test209 设为只读(模拟业务流量) ALTER AVAILABILITY GROUP [testgroup1] MODIFY REPLICA ON 'test209.test.com' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY)); -- 3. 从另一台客户端机器,用 ApplicationIntent=ReadOnly 连接侦听器,执行: SELECT TOP 10 * FROM YourDBName.dbo.YourTable; -- ✅ 成功返回数据,且不报错,证明只读路由生效 -- 4. 模拟主副本故障(在 test51 上停止 SQL Server 服务) -- 等待 30 秒,再次连接侦听器,执行: SELECT @@SERVERNAME AS CurrentPrimary; -- ✅ 返回值应为 'test52.test.com' 或 'test209.test.com'(取决于故障转移优先级) -- 此时所有读写请求应自动路由到新主副本,业务无感知中断

从那以后我每次新增 AlwaysOn 节点,都强制走一遍这三步验证:先 PowerShell 看群集,再 T-SQL 查端点,最后用真实连接串压测。少走任何一步,都可能在某个深夜的告警电话里,听见自己心跳声盖过键盘敲击声。希望帮到你。

本文还有配套的精品资源,点击获取

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

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

立即咨询