资讯动态

SQL Server高可用改造:AlwaysOn可用性组从0到1部署实战指南

发布时间:2026/9/15 17:00:43 来源:尧图企业网站定制
近期给一套新业务系统做了 SQL Server 高可用改造从单机迁到了基础的 AlwaysOn 可用性组规划、建集群、搭 AG、切监听器整个流程走下来大概花了一周多。网上讲 AlwaysOn 的教程不少但要么停在概念阶段要么只教你在 GUI 向导里点下一步真到生产环境里碰到权限、仲裁、防火墙这类问题还是得靠摸索。这篇我就按实际部署顺序把一套基础 AlwaysOn 从 0 到 1 的完整过程写清楚重点标出哪些地方容易翻车。如果你正打算把单机 SQL Server 升级成双机高可用或者刚接手一套 AlwaysOn 环境想搞清楚底层的部署逻辑这篇文章可以当你的落地笔记。我会把每一步背后的原因也讲明白不只是“点哪里”这样以后你遇到变种环境标准版、跨网段、自动故障转移不可用等也自己能判断该调哪些参数。1. 先想清楚你要的到底是哪种“高可用”1.1 AlwaysOn 可用性组和故障转移集群实例别选错很多人一提到 SQL Server 高可用就自动把 AlwaysOn 和故障转移集群实例FCI即 Failover Cluster Instance混在一起。这俩虽然底层都依赖 Windows 故障转移集群WSFC但本质上解决的是完全不同的问题必须先分清楚。可用性组是数据库级别的高可用方案。它把一份数据库的多个副本放在不同服务器节点上主副本负责读写辅助副本你可以设定成允许只读访问也可以挂机当备胎。数据库发生故障时集群再把主副本的角色转移到另一台节点。这种方案的好处是不需要共享存储每台机器上都有自己的数据文件所以跨机房部署、容灾场景更灵活。故障转移集群实例则是实例级别的高可用方案。整个 SQL Server 实例变成一个集群资源同一时刻只有一台机器在跑这套实例另一台站着等。但它必须依赖共享存储SAN、iSCSI、SMB 共享等因为数据库文件放在共享盘上谁接管实例谁就接管那堆文件。好处是切换粒度是整个实例坏处是共享存储本身可能成为新的单点而且成本高。我的建议没有条件上共享存储、又想要数据库自动切换的直接走可用性组如果你追求的是实例级接管、且已经有共享存储方案那才考虑 FCI。在实际生产环境里可用性组因为对存储的要求低部署门槛明显更小这也是它成为主流选择的原因。这里顺带说一句也有人把可用性组和 FCI 叠加成“集群里的集群”这是进阶玩法基础部署阶段不用碰。1.2 版本怎么选企业版还是标准版直接影响能开哪些功能AlwaysOn 可用性组并不是所有 SQL Server 版本都能用的。企业版Enterprise能开完整版可用性组标准版Standard从 SQL Server 2016 SP1 开始支持“基本可用性组”Basic Availability Group两者的能力差异非常明显。完整版可用性组支持最多 9 个副本1 主 8 备数据库数量没有上限支持只读路由、备份优先级的细致配置、分布式可用性组等等。而基本可用性组最多只能有一主一备两个副本、只支持一个数据库很多高级功能比如只读路由默认就没有具体按版本来不同版本差异我建议你打开官方文档对照一下。所以部署前必须先回答自己两个问题第一公司买的 SQL Server 是企业版还是标准版第二这套环境里要放多少个数据库如果一上来就要在标准版上放几十个库进同一个可用性组这条路是走不通的只能一个库建一个基本可用性组或者老老实实升级企业版。另外提醒一点主副本和辅助副本的 SQL Server 版本号要一致大版本不能跨比如一个 2019 一个 2022 就不行补丁级别最好也保持一致。集群维护时先给辅助节点打补丁再切换是另一个话题但版本基线从一开始就要卡住否则后面做副本同步时会出现“版本过低无法加入可用性组”之类的报错。我这次部署用的是 SQL Server 2019 企业版两节点的方案下文所有操作都以这个环境为例。2. 环境规划与前置检查清单2.1 基础环境域、机器、网络一个都不能省AlwaysOn 可用性组强依赖 Windows 故障转移集群而 Windows 故障转移集群必须运行在域环境里。这不是可选配置而是硬性要求。两个节点如果是独立工作组机器后面连创建集群这一步都过不了。所以环境准备阶段第一优先级就是确认这一点。我的基础环境是这样的两台物理机/虚机操作系统 Windows Server 2019 Datacenter两台机器都加入同一个 Active Directory 域每台机器两块网卡一块走业务网络客户端访问一块走集群心跳和数据库同步内部网络SQL Server 服务账号、集群管理账号都使用域账号这里多说一句网卡的事。基础部署你可以只用一个网卡硬跑但生产环境我强烈建议至少分开业务网和内部同步网。原因很简单AlwaysOn 的辅助副本要持续从主副本拉取日志块如果流量和高并发业务挤在同一张网卡上日志传输延迟会被放大直接拖慢主库的提交速度同步提交模式下尤其明显。两块网卡之后在创建集群和配置可用性组的时候指定内部网卡作为集群通信网络就能把集群心跳和数据库同步跟业务流量隔离。Windows 会默认把所有网络都纳入集群管理记得手动禁用掉业务网卡在集群里的使用。网络规划上还需要注意所有节点、SQL 服务账号、集群名称、可用性组监听器名称都要能被 DNS 正常解析。我建议提前在 DNS 里建好几条 A 记录集群名称例如 SQLAGCluster的 IP可用性组监听器名称例如 AGListener的 IP两台节点的静态 IP 和主机名这个一般加域的时候就有了IP 地址强烈建议全用静态 IP不要让域里的 DHCP 来分配。数据库高可用环境里 IP 变了会导致集群误判节点故障这个坑踩一次就够疼。2.2 SQL Server 安装阶段就要注意的细节很多人以为部署 AlwaysOn 是在 SQL Server 装完之后才开始其实安装阶段就得提前埋好伏笔。我逐个说。第一SQL Server 实例功能组件里不需要额外勾选什么“高可用组件”AlwaysOn 功能是数据库引擎自带的安装完成后再去 SQL Server 配置管理器里启用就行。真正需要注意的反而是服务账号。两个节点上的 SQL Server 服务账号建议用同一个域账号比如 contoso\sqlsvc。这样后面配置可用性组端点权限时不用额外把不同计算机账号互相授权少踩一个权限坑。服务账号只需要有“作为服务登录”的权限正常域账号默认就有不用给管理员权限。第二安装时的排序规则、实例配置要保持一致。两个节点如果排序规则不一致后面副本加入可用性组时会直接失败。最稳妥的做法是两台机器用同一个安装配置文件或者在安装向导里人工核对排序规则、SQL Server 代理账号等关键项。第三数据库文件和日志文件的路径两个节点尽量保持一致。虽然可用性组不要求两边文件路径相同但如果辅助节点的驱动盘符不一样比如主节点是 D:\Data辅助节点数据盘在 E:\也没问题加入可用性组时可以在脚本里指定路径。不过在基础部署里保持一致能少处理很多细节问题后面手写脚本、做自动化维护都会方便很多。第四要把系统重启后 SQL Server 服务的启动模式设为“自动”不要用“自动(延迟启动)”。故障转移发生时辅助节点上的 SQL Server 服务如果没起来角色接管会一直被挂起。这个细节在集群测试时特别容易暴露出来。2.3 数据库层面的前置条件已加入可用性组的数据库有几个硬性要求在规划阶段就要看好否则向导跑到一半会报错退回来。最关键的一条数据库必须是完整恢复模式Full Recovery。简单恢复模式和大容量日志恢复模式的库都不能加入可用性组。如果你的库现在是简单恢复模式必须先在数据库属性里改成完整恢复模式然后做一次完整备份才能加入。因为 AlwaysOn 同步的本质是把主库的事务日志打包发到辅助副本去重放没有完整的日志链根本没法做这件事。另外加入可用性组之前目标数据库要至少做一次完整备份辅助节点上还要先还原出一个处于“恢复中Restoring”状态的副本。这个过程不复杂但必须确保从那一次备份开始主库的日志链没有被中断过。如果你之前从没对库做过完整备份先手动备份一次再说。还要提醒一点多个数据库加入同一个可用性组是完全支持的但生产环境我建议不要把所有库一股脑塞进去。每个库都有独立的日志同步链路库越多任何一个小库的日志堆积都可能拖垮整组的同步状态。基础部署阶段先放业务核心库跑稳了再逐步加。这也是为什么我在 1.2 节里强调先选型一个可用性组放多少库直接影响后续运维难度。3. 搭建 Windows 故障转移集群3.1 安装集群角色与运行验证向导准备工作做完第一步实际动手的操作是给两台节点安装故障转移集群功能。在 Windows Server 上可以用图形界面的“服务器管理器”也可以用 PowerShell 一条命令搞定。我平时喜欢用 PowerShell效率高还能留档Install-WindowsFeature Failover-Clustering -IncludeManagementTools这条命令在两台节点上都执行一遍。安装完成后下一步是用“验证配置”向导检查硬件和设置是否满足集群要求。注意这一步不要跳过。尤其要检查“存储”这一项因为可用性组不依赖共享存储如果你没有任何共享磁盘验证向导里的存储测试会“警告”甚至“失败”这是正常的只需要在测试项里取消勾选存储相关项目即可。验证之后就是创建集群了。同样可以直接用 PowerShellNew-Cluster -Name SQLAGCluster -Node SQLNODE1,SQLNODE2 -NoStorage -StaticAddress 192.168.1.200这里 -NoStorage 参数很关键因为可用性组不需要共享磁盘直接创建一个不带存储资源的集群即可。-StaticAddress 是给集群名称分配一个业务网段里的静态 IP这个 IP 会在域里注册成一台“虚拟计算机”供集群对外通信使用。创建完集群后建议立刻检查一下集群状态Get-ClusterNode Get-ClusterNetwork正常情况下两个节点状态都是 Up网络里能同时看到业务网和心跳网。如果发现两个节点把两块网卡都识别成了群集网络记得手动把业务网卡的“允许集群在此网络通信”勾选去掉仅保留内部网络作为群集通信网络。这一步对后续版本的稳定性影响很大。3.2 仲裁配置两节点集群的命脉集群创建完毕后必须马上配置仲裁Quorum。仲裁机制决定了当集群里节点失联时谁有资格继续提供服务。基础的两节点集群如果不配仲裁任意一个节点宕掉剩下的那个节点因为拿不到多数票集群会直接下线数据库也跟着不可用——这和你做高可用的初衷完全相反。我给两节点集群的标准配置是“节点和文件共享见证”Node and File Share Witness。也就是两台节点各有一票再加一台额外的文件共享服务器作为见证拥有第三票。多数派 3 票中必须拿到 2 票才能维持集群这样任何一台节点宕机剩下的节点加见证票仍然有 2 票集群可以继续运行。见证共享不建议放在集群节点本机上找一个第三方的机器或 NAS 目录来放路径给协商好的共享目录即可。配置命令如下Set-ClusterQuorum -FileShareWitness \\WITNESS-SERVER\SQLAGWitness如果之后迁移到 Azure也可以用云见证Cloud Witness替代文件共享见证原理一样都是给集群额外加一票。这里我多说一句坑位经验很多第一次搭集群的人会忽略见证共享的权限问题SQL 集群的计算机账号需要对该共享目录有读写权限。你可以在共享目录的权限设置里显式添加两个集群节点计算机账号的“更改”权限这一步做完就不会再遇到“无法更新见证配置”的报错。仲裁配置完可以在故障转移集群管理器里看到当前仲裁模式是“节点和文件共享多数”。到这里WSFC 层的部署就算完成了。可用性组是跑在它上面的下一层应用接下来才轮到 SQL Server 上场。4. 创建可用性组4.1 启用 AlwaysOn 功能与副本端点准备有了集群回到 SQL Server 侧先做两件事启用 AlwaysOn 可用性组功能并准备端点。打开 SQL Server 配置管理器SQL Server Configuration Manager找到“SQL Server 服务”右键实例选择“属性”切到“AlwaysOn 高可用性”选项卡勾选“启用 AlwaysOn 可用性组”然后重启 SQL Server 服务。该操作要在两个节点上都执行一次。随后需要为每个 SQL Server 实例创建一个数据库镜像端点Database Mirroring Endpoint。AlwaysOn 的日志同步走的是这个端点默认端口常用 5022。我用 T-SQL 创建脚本如下CREATE ENDPOINT [Hadr_endpoint] STATE STARTED AS TCP ( LISTENER_PORT 5022, LISTENER_IP ALL ) FOR DATA_MIRRORING ( ROLE ALL, ENCRYPTION REQUIRED ALGORITHM AES ); GO两个节点上都要执行同样的脚本。端点的身份验证默认走 Windows 身份验证所以只要两个 SQL Server 服务账号是同一个域账号或者互相有访问权限基本不用额外配置。如果两台机器的 SQL Server 服务是不同域账号那就需要手动为对方端点创建登录名并授予 CONNECT 权限这个属于常见的进阶坑我这里先提一句。端点创建后八成以上的环境会遇到防火墙问题。在 Windows 防火墙里放行 5022 端口的入站规则是必须的而且两边都要放。不要以为集群之间已经有通信通道就可以不管SQL Server 日志同步端点是独立端口防火墙不放行后面副本初始化会一直卡在“正在连接”状态。检查端点状态可以用这条查询SELECT name, state_desc, port FROM sys.tcp_endpoints;确保两个节点上端点的状态都是 STARTED。4.2 通过向导创建可用性组SSMS 里右击“AlwaysOn 高可用性”文件夹选择“新建可用性组向导”是大多数人的选择。它会引导你完成命名、选库、配副本、设端点、建监听器的全过程而且每一步做完都会有验证检查相对不容易出错。但作为一个习惯用脚本的 DBA我更推荐用一种混合方式先搞清楚向导每一步在干什么再决定用不用脚本。向导第一步是填可用性组名称比如 AGProd。这一步注意名称会被注册到 AD 中所以命名最好是能体现业务和环境的不要用带特殊字符的名字。第二步选择要加入的数据库。界面里会直接给出每库的恢复模式、是否已备份等状态。只要发现某库状态不符它在这里就直接标红了很方便。再次强调完整恢复模式完整备份这两条前置条件缺一个都选不进去。第三步配置副本。这一步是整个向导的核心。你会看到主副本和辅助副本两列需要给每个副本设置可用性模式同步提交Synchronous commit还是异步提交Asynchronous commit故障转移模式自动还是手动辅助角色连接只读还是不允许连接基础的生产环境推荐配置是“同步提交 自动故障转移 辅助副本允许只读连接”。同步提交保证主库提交事务时日志已经写到了辅助副本理论上不丢数据自动故障转移让主节点挂了业务可以自动切到备节点。这两个选项是搭配使用的同步提交模式才能启用自动故障转移异步模式只能配手动切换。第四步选择数据同步方式。向导提供“全量备份还原”“仅加入”“手动指定”三种方式。如果两个节点网络好、库不大直接用“全量备份还原”最省事它会自动做主库备份然后把备份文件还原到辅助副本上再建立同步链路。如果库很大几百 GB 以上建议自己先做好备份还原然后选择“仅加入”方式避免向导备份还原过程占用太久时间。第五步是监听器配置我先点跳过放到下一节单独讲。后面的验证页面会做一轮完整校验包括副本可用性、端点连通性、数据库状态等确认全绿后点击完成即可。4.3 把已有数据库加入可用性组以及初始化同步的完整链路如果你向导执行到一半因为网络原因中断或者某个库之前没准备好后面也不需要重建整个可用性组单独把库加进来就行。加库的操作也是在向导的“可用性组”页面里选“添加数据库”。但这里要讲清楚一件事加库并不是瞬间完成的它背后是一条极典型的“备份—传输—还原—同步”链路。假设主库 TestDB 要加入 AGProd 可用性组。首先主库会创建一个数据库完整备份备份文件被传输到辅助节点指定目录辅助节点用 RESTORE WITH NORECOVERY 把备份还原成“正在恢复”状态随后 AG 开始把主库日志连续发送到辅助副本并执行重放等到两边日志同步到同一位置数据库的状态才从“正在恢复”变成“已同步”。在已同步之前万一这时候主库发生故障转移辅助副本上的这个库是没有办法接管的因为它的日志链还没追上。所以在生产上做大库入库操作时尽量选业务低峰期并借助下面的 DMV 观察同步进度SELECT ag.name AS ag_name, drs.database_id, drs.synchronization_state_desc, drs.synchronization_health_desc, drs.last_hardened_lsn, drs.end_of_log_lsn FROM sys.dm_hadr_database_replica_states drs JOIN sys.availability_groups ag ON drs.group_id ag.group_id;如果 synchronization_state_desc 显示 SYNCHRONIZED说明同步链路已经建立起来。如果长时间停在 SYNCHRONIZING优先检查两个节点的日志同步端点是否正常、防火墙有没有放行 5022、以及辅助节点上的数据库文件路径是否存在。基础部署里我看到过不少次问题就出在辅助节点上还原数据库时指定的文件路径不存在因为两边磁盘布局不一致。5. 监听器配置与客户端连接5.1 监听器是什么为什么它比直连实例名更高级很多初学 AlwaysOn 的人会把监听器当成一个可有可无的“附加配置”实际上监听器才是业务层接入高可用环境的关键。如果客户端连接的是单独某个节点的主机名那集群发生故障转移后客户端连接串就得改这显然不符合高可用的初衷。可用性组监听器Availability Group Listener本质上是一个“虚拟网络名称 一组 IP 地址”。它注册在 AD 和 DNS 里代表可用性组对外提供连接入口。客户端连接监听器名称集群负责把连接路由到当前主副本所对应的实际节点上。故障转移发生时监听器的 DNS 记录和资源状态会自动更新客户端无需做任何修改就能继续访问。这也是我们上线时把连接串从原来的单机实例名改成监听器名称的核心原因。在新建可用性组向导里配置监听器或者之后用 T-SQL 添加都可以。核心配置项就三样监听器名称、TCP 端口默认 1433、静态 IP 地址。我这里给一段 T-SQL 示例方便你在脚本化部署时直接改参数用ALTER AVAILABILITY GROUP [AGProd] ADD LISTENER NAGListener ( WITH IP ((192.168.1.210, 255.255.255.0)) , PORT 1433 );这里 192.168.1.210 就是我提前规划好、预留在 DNS/AD 里的监听器 IP。创建成功之后你可以在 AD 里看到它注册成了一个计算机对象这也是为什么创建监听器时对登录账号的 AD 权限有要求——账号要有权在域里创建计算机对象。如果没有权限向导会在最后一步报“无法创建可用性组监听器”解决办法是在 AD 里预先创建一个计算机对象并授权给部署账号这个操作往往需要找域管理员一同完成。5.2 客户端连接串、只读路由与连接时的注意事项监听器上线后DBA 的活并不算完还有重要的客户端侧配置。最简单也最容易被忽略的就是连接串里的初始化。常规连接串比如使用 .NET SqlConnection 时要写成这样Servertcp:AGListener,1433;DatabaseTestDB;Integrated SecuritySSPI;MultiSubnetFailoverTrue;MultiSubnetFailoverTrue 特别关键。如果你的监听器配置了多个子网的 IP比如基于多站点的高可用客户端必须带上这个参数才会启用多子网快速连接逻辑避免每次连接都因为 DNS 轮询而多卡几秒。即使是单子网环境带上它也一般没有副作用。如果你在可用性组里把辅助副本设为可读并且想实现“读走备机、写走主机”的读写分离这就涉及到只读路由Read-Only Routing配置了。基础部署里可以先不碰只读路由但至少应该让辅助副本允许只读连接这样做报表查询、日常备份维护时能往备机上丢任务压力不占主库。客户端只要在连接串里增加 ApplicationIntentReadOnlySQL Server 就会把这类连接路由到允许只读访问的辅助副本上。监听器配置完成、客户端连接串改完之后最好做一轮完整的故障转移演练手动把可用性组切到辅助节点观察监听器能否在秒级内重新指向新主副本客户端连接能否正常建立。这个演练不要只在测试环境做生产上线前也要挑低峰期做一次因为故障转移相关的问题只有在真实网络环境下才最容易暴露出来。6. 常见故障排查与心得6.1 部署与运维中遇到的经典问题速查表AlwaysOn 部署过程中的报错信息翻来覆去就那么几个模型。我把这次部署以及之前在其他项目里经常碰到的问题整理成一张速查表按“现象—根因—解决方式”来归纳方便你以后直接对号入座。现象根因处理方式创建可用性组时报 41069 权限错误当前登录账号缺少“创建可用性组”权限或 AD 对象创建权限给账号授予 CONTROL SERVER 权限或先在 AD 预创建监听器/集群对象并授权副本一直显示“正在连接”或报 35250端点的防火墙端口5022未放行或端点状态不是 STARTED检查 sys.tcp_endpoints 状态防火墙放行 5022 双向端口辅助副本同步不起来报 35202端点身份验证失败两边 SQL 服务账号不能互相识别统一服务域账号或手动创建对方登录名并授予 CONNECT TO ENDPOINT 权限数据库无法加入恢复模式不对目标库是简单恢复模式或大容量日志恢复模式改成完整恢复模式并先做主库完整备份加入可用性组后同步状态一直是 NOT SYNCHRONIZING辅助节点数据文件路径不存在或权限不足核对辅助节点磁盘路径优先让两边文件路径保持一致创建监听器失败“正在尝试更新 DNS 记录”超时域账号没有创建计算机对象的权限域管理员预创建监听器计算机账号并委派权限节点宕机后整个集群不可用两节点集群缺少见证票无法形成多数派配置文件共享见证或云见证并修正见证共享权限自动故障转移长时间不触发同步提交模式下才支持自动故障转移或健康检查超时设置过短确认可用性模式为同步提交、故障转移模式为自动并查看集群事件日志中的健康检测记录故障转移后客户端连接一直失败监听器 IP 或 DNS 记录未及时更新或连接串未开启 MultiSubnetFailover在集群管理器里检查监视器资源是否在线连接串加 MultiSubnetFailoverTrue再多补充两点表格之外的体会。一是排查故障时先看 Windows 故障转移集群的日志再看 SQL Server 错误日志最后看可用性组 Dashboard。这个顺序不能反。因为 AlwaysOn 的很多表象问题根子其实在集群层尤其是一堆“获取仲裁失败”“节点与集群连接中断”这类问题SSMS 那边只会给你一个笼统的“可用性组不可用”真正的原因必须到集群事件日志里翻。二是部署过程中改任何配置比如加端点、改仲裁方式都用 PowerShell 或 T-SQL 记录留痕不要只在 GUI 里点一下。等后面出了问题想回溯变更时有一份脚本历史会让排查效率高出一个量级。6.2 日常巡检怎么快速判断 AG 有没有生病部署不是终点把可观测性做起来才是。我自己的习惯是部署完成后立刻建立一套日常巡检查询每天定时跑一遍并把结果发到运维群让团队对可用性组状态心里有数。最重要的三张检查是副本状态通过 sys.dm_hadr_availability_replica_states 查看每个副本的角色PRIMARY/SECONDARY、连接状态、同步状态。数据库同步状态通过 sys.dm_hadr_database_replica_states 查看每个数据库的 synchronization_state_desc正常应该是 SYNCHRONIZED同步提交模式下如果长时间变成 SYNCHRONIZING就是日志同步跟不上要及时排查。集群健康通过 PowerShell 的 Get-ClusterNode 和 Get-ClusterResource 检查集群节点和资源状态最好再外加对见证共享的连通性检查。除了状态查询我还建议给自动故障转移设置一个合理的健康检查超时时间。默认值通常是 30 秒这意味着从 SQL Server 健康检查失败到触发故障转移大约要等这么长时间。如果业务对中断时间很敏感可以调低 HEALTH_CHECK_TIMEOUT但不要低于 10 秒否则网络抖动也可能引发误切换反而更危险。最后顺便说一句备份策略。可用性组建好后很多人以为备份只要有任何一个副本在线就行其实要注意主库日志备份不能停因为只有日志备份才能截断事务日志。如果不做日志备份主库日志会无限增长可用性组同步也会受影响。比较稳妥的做法是把完整备份和日志备份都定向到辅助副本上执行既减轻主库压力又保证日志链完整。这个属于部署完成后的运维细节但影响非常大这里特别提一下。部署 AlwaysOn 这件事说难不难说简单也不简单。最难的部分不是跟着向导点那几下而是部署前把架构思路理清楚、部署中把环境细节卡严格、部署后把监控和演练做成常态。我这套环境上线前光故障转移演练就做了三轮每一轮都会发现新的小问题最典型的就是监听器 DNS 缓存导致的连接延迟。如果你也准备上手记得把演练当作部署的一部分而不是可选项。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价