拓冰建站拓冰建站
首页 / 资讯中心 / 正文

SQL Server AlwaysOn可用性组从零部署:高可用架构实战指南

我有个习惯技术圈里只要刮起“部署”风我总会先往数据库这层瞟一眼。这不最近大家聊本地部署聊得火热从大模型到Docker再到CI/CD自动部署人人都能把几十个容器跑起来但真正轮到底层数据库的高可用部署敢拍胸脯说没翻过车的人真不多。AlwaysOn可用性组就是SQL Server世界里绕不开的那道坎它不像docker compose up那样敲一下就能起来也不像改个配置文件就能交付但只要掌握了它整个数据库层的可用性才算是真正握在了自己手里。这篇文章我会从零开始把一套基础版AlwaysOn的部署过程完整走一遍。适合刚接手SQL Server环境的运维工程师、准备把单机数据库升级成高可用的DBA以及想弄明白高可用原理的架构师。不需要你之前有很深的群集基础我会把每一个环节背后的原因、操作目的、以及最容易踩坑的地方都讲清楚。1. 先把AlwaysOn这件事想明白它到底解决什么问题AlwaysOn可用性组Availability Group不是SQL Server本身新增的某个开关也不是某一种实例角色。它是构建在Windows故障转移群集WSFC之上的数据库级冗余方案同一个数据库在主副本和辅助副本上各保留一份事务在主副本上提交后日志会同步或异步地传送到辅助副本并在辅助副本上重放。主副本出问题的时候群集可以决定把角色切换到某个辅助副本应用层几乎无感。很多人在部署前没有想清楚AlwaysOn和以前的高可用方案有什么区别结果搭到一半才发现根本不是自己想要的。这节先把几个方案掰开揉碎讲明白。1.1 为什么群集、镜像都替代不了可用性组在SQL Server 2012以前主流的HA方案是故障转移群集实例FCI和数据库镜像Database Mirroring。FCI的本质是“一台服务器挂了另一台接管同一个共享存储上的数据”。听起来可用但它有个致命前提必须依赖共享存储比如SAN。存储一旦出问题整个群集一起完蛋而且FCI在副本层面没有第二份数据切换速度完全取决于存储的故障转移速度。更麻烦的是FCI只解决了“实例可用性”数据库文件本身还是那一份。数据库镜像则是数据库级的复制方案它在SQL Server 2012开始被标记为弃用功能。镜像最大问题是缺少对应用透明的侦听器主库挂了应用不能无缝切换需要手动改连接串或靠额外机制接管。而且镜像虽然能支持自动故障转移但要搭见证服务器部署门槛高辅助库还不能对外提供只读访问。日志传送更不用提它本质上是一个定时备份加还原的调度任务延迟是分钟级甚至小时级只适合做灾备不适合当高可用方案。AlwaysOn可用性组把这些问题一次性解决掉它依托WSFC提供仲裁和自动故障转移能力通过数据库副本保存独立数据不依赖共享存储提供侦听器Listener让应用固定连接一个虚拟IP和端口节点切换对应用完全透明辅助副本还能承担只读查询和备份任务。整个思路就是把高可用和灾难恢复统一到一套机制里。1.2 基础可用性组与经典可用性组先分清再动手微软从SQL Server 2016开始在标准版里加入了一个简化版特性叫基础可用性组Basic Availability Group。你标题写的“基础的AlwaysOn”我理解大概率指的就是这一类面向入门和小规模业务场景的基础版但也可能是指“从零搭一套最小可用的经典版”。两个概念很容易混我直接列个表格对清楚。对比项基础可用性组Basic AG经典可用性组Classic AG版本要求SQL Server 2016及以上标准版企业版副本数量仅2个1主1辅最多9个1主8辅数据库数量仅支持1个支持多个数据库打包进同一组只读路由不支持支持备份首选项不支持支持分布式可用性组不支持支持适合场景小型业务、学习环境、低成本高可用生产核心系统、多副本扩展我强烈建议如果你只是在测试环境或虚拟机里做验证直接用SQL Server 2016以上的标准版勾选基础可用性组就够了。这套路径最省心故障转移逻辑和经典版是一样的学会了它之后上企业版经典AG就是换汤不换药。与此同时本文后续的实操部分我会以“双节点同步提交自动故障转移”这套经典AG的通用流程为主线因为基础AG的创建过程其实就是经典AG的简化版把复杂流程掌握了基础AG你反而会觉得太简单。1.3 副本、同步、故障转移三个核心概念说白了第一个词是副本。每个参与AlwaysOn的SQL Server实例都叫副本。主副本就是当前承担读写业务的那台实例辅助副本是同步数据并等待接管的那台。注意副本不是把整个SQL Server实例复制一份而是同一个实例上某个数据库被纳入可用性组后生成了对应的数据库副本。第二个词是同步提交。这决定了主副节点之间数据保证到什么程度。在同步提交模式下主副本要把事务日志写到本地然后等辅助副本也把这个日志块硬化写入日志文件之后主副本才会向应用返回事务成功。这个模式最安全数据不丢但事务延迟会随网络和磁盘性能增加。异步提交则反过来主副本不用等辅助确认就能提交性能损失小但极端情况下可能丢数据。基础部署里要开启自动故障转移就必须用同步提交模式。第三个词是故障转移。AlwaysOn的自动故障转移不是SQL Server自己拍板的而是由WSFC根据健康状态、仲裁投票来决定。群集里每个节点都有一票一旦拥有仲裁的节点发现主副本不可用它就会推动角色切换。这个机制和“裁判”很像主节点挂了裁判判断谁有资格上场然后让辅助副本顶上。所以群集仲裁的存活是故障转移能否成功的第一前提。2. 动手部署前的环境规划与检查清单AlwaysOn部署之所以翻车率高大部分原因不是SQL Server配置错了而是底层的操作系统、域控、网络、群集这些地基就没打稳。我见过好多人在VMware里拿两台没加域的Windows Server直接想开AlwaysOn结果卡在群集创建这一步然后开始怀疑人生。在敲任何命令之前先花半小时把下面这些规划做完。2.1 双节点加见证的拓扑怎么定最基础、最容易理解、也最适合生产环境起步的拓扑就是“两个节点加一个文件共享见证”。为什么需要见证两节点群集在仲裁机制下其实很尴尬群集里只有两票节点一挂剩下的节点只有一票达不到多数群集资源就会整体离线SQL Server也没法继续服务。这等于高可用没实现反而多了一个会“主动停服”的环节。文件共享见证的价值就是提供第三票让剩下那个活着的节点拿到多数票从而成功接管资源。角色机器名IP地址作用主节点SQL01192.168.1.11安装SQL Server主副本辅助节点SQL02192.168.1.12安装SQL Server辅助副本见证机WITNESS192.168.1.13提供文件共享见证不装SQL群集虚拟名称SQLCluster192.168.1.100故障转移群集本身侦听器虚拟名称AGListener192.168.1.110应用连接入口见证机不需要装SQL Server只需要一个Windows共享目录给SQL服务账号读写权限。这个见证不要放在SQL01或SQL02本机上否则节点挂了见证也跟着挂等于白搭。2.2 网络、DNS、防火墙和账号缺一个都别开工两个节点必须加入同一个域这是最省心、最推荐的做法。AlwaysOn的端点通信和群集通信依赖Windows身份验证域环境下用Kerberos认证配置起来非常顺滑。工作组环境也能做但需要手动解决NTLM协商和SPN注册的问题入门阶段不碰为妙。网络方面有四个硬性要求节点主机名和IP必须固定不能依靠DHCP随机分配。DNS里三个虚拟名称SQLCluster、AGListener、两个节点主机名的正向解析要能正常解析。节点之间用主机名互相ping通不要只ping IP。ping不通主机名先查防火墙和DNS。所有节点时间必须同步否则Kerberos认证会在你意想不到的时刻抽风。防火墙端口更是重灾区。我直接把部署过程中需要放行的端口列成表你照抄就行端口用途445SMB文件共享用于文件共享见证1433SQL Server默认实例通信5022AlwaysOn可用性组端点HADR日志传输135RPC群集管理通信3343WSFC群集通信49152-65535Windows动态RPC端口范围群集服务会用到SQL Server服务账号这块强烈建议提前在AD里建好两个域账号一个给SQL Server服务用一个给SQL Server Agent服务用。两个节点的SQL Server服务账号保持一致后面能减少大量权限问题。账号不需要域管理员权限但需要能被用来登录群集节点并注册SPN。2.3 域控与节点准备的几个细节如果你手头还没有域控先起一台Windows Server配成域控再把SQL01和SQL02加进来。如果已经有域环境跳过建域控直接加域就行。加域之后有三个细节容易被忽略每台SQL节点的网卡属性里TCP/IPv6如果不确定会用干脆禁用。多个协议混在一起经常导致DNS解析和Kerberos验证出奇怪问题。SQL节点的Windows防火墙要提前把上面那张端口表配置好。我见过有人在群集验证时报“网络绑定”错误查了半天发现是防火墙没放行群集通信。两台节点的驱动、Windows补丁版本尽量一致不要一个2019一个2022也不要一个打了上月补丁一个还是半年前版本。群集对版本漂移很敏感。3. 一步步部署基础AlwaysOn可用性组规划做完就开始实操。我按照从下往上的顺序走每一层验证通过了再往上一层不要跳步。3.1 第1步在两台服务器上装好故障转移群集在SQL01和SQL02上分别打开PowerShell运行Install-WindowsFeature -Name Failover-Clustering -IncludeManagementTools装完后先在SQL01上做一次群集验证。这一步虽然耗时但能提前暴露网卡绑定、DNS、存储等多方面的问题Test-Cluster -Node SQL01, SQL02 -Include Network, System Configuration如果这里输出了一大堆红色错误先别急着创建群集。把网络相关的错误解决掉再继续。群集验证里关于存储的报警可以直接忽略因为AlwaysOn不需要共享存储靠的是各节点本地磁盘验证工具不认识这种模式会报“无可用共享存储”之类的警告属于正常现象。验证通过后用下面的命令创建群集New-Cluster -Name SQLCluster -Node SQL01, SQL02 -StaticAddress 192.168.1.100群集启动后立刻配置文件共享见证。在WITNESS机器上的任意目录右键共享赋予“Everyone”或者专门的域账号完整控制权限然后在SQL01上执行Set-ClusterQuorum -FileShareWitness \\WITNESS\AgWitness配置完成后在故障转移群集管理器里应该能看到节点处于正常状态核心群集资源在线。到这里底层的WSFC才算真正跑起来。注意创建群集如果提示“如下网络地址未注册”多半是DNS反向解析有问题或者群集IP和现有主机IP冲突。先把DNS记录清干净再试。3.2 第2步安装SQL Server并启用AlwaysOn两台节点都要装SQL Server实例名保持一致。最简单的方式是用默认实例也就是机器名本身。SQL Server版本建议直接上企业版的Evaluation或正式授权如果只有标准版记住后面只能建基础可用性组。安装过程中最关键的配置是服务账号。在“服务器配置”页面把SQL Server和SQL Server Agent的服务账号都改成域账号例如CONTOSO\svc_sql和CONTOSO\svc_sqlagent。账号密码和名称两台节点要保持一致。安装完成后打开“SQL Server配置管理器”在左侧选择“SQL Server服务”右侧找到SQL Server实例右键属性切到“AlwaysOn高可用性”标签页勾选“启用AlwaysOn可用性组”然后重启服务。这一步完成后在SSMS里右键实例展开“AlwaysOn高可用性”节点如果还能正常看到“可用性组向导”的入口说明SQL层已经准许你进行后续操作。可以使用下面这条SQL确认是否启用SELECT SERVERPROPERTY(IsHadrEnabled) AS IsHadrEnabled;返回1就是已经启用返回0就回去检查服务是否重启或者SQL Server版本是否为企业版以上。3.3 第3步备份、还原把数据库送到辅助副本AlwaysOn加入的数据库必须同时满足几个条件用户数据库、完整恢复模式、做过至少一次完整备份、不属于系统库。这些条件任何一个不满足向导都会直接卡住。先把要加入的数据库设为完整恢复模式ALTER DATABASE [YourDB] SET RECOVERY FULL;然后做一次完整备份和一次日志备份。这里有个实操技巧把备份文件放到一个两个节点都能访问到的共享路径下后面还原辅助副本就不用把文件拷来拷去了。BACKUP DATABASE [YourDB] TO DISK N\\WITNESS\Backup\YourDB.bak WITH INIT, COMPRESSION; BACKUP LOG [YourDB] TO DISK N\\WITNESS\Backup\YourDB_Log.bak WITH INIT, COMPRESSION;备份完成后在SQL02的SSMS上还原数据库。关键点是还原时一定要选择带NORECOVERY选项也就是“不对数据库进行任何恢复保持还原状态”。只有这样数据库才能继续接受后续日志备份才能被AlwaysOn接管RESTORE DATABASE [YourDB] FROM DISK N\\WITNESS\Backup\YourDB.bak WITH NORECOVERY, REPLACE; RESTORE LOG [YourDB] FROM DISK N\\WITNESS\Backup\YourDB_Log.bak WITH NORECOVERY;还原完成后你在SQL02上会看到YourDB的状态是“正在还原”不要害怕这是正常现象。如果状态是“在线”说明你漏了NORECOVERY选项需要重新还原。3.4 第4步创建可用性组并加入数据库到这一步图形化向导和T-SQL脚本都可以。我推荐新手用SSMS的新建可用性组向导因为它会自动帮你创建端点、把辅助副本加到群集里非常省事。右键“AlwaysOn高可用性”节点选择“新建可用性组向导”然后照顺序走指定可用性组名称比如AG1。勾选“数据库”的时候你之前备份过的YourDB会出现在可选列表中。在“指定副本”页面点击“添加副本”连接SQL02的实例。然后设置可用性模式为“同步提交”故障转移模式为“自动”。在“选择数据同步”页面如果你已经在SQL02上手动还原了数据库就选择“仅联接”如果想让SQL Server自动做备份还原可以选择“完整”但后面网络带宽占用会很猛生产环境我一般不推荐。侦听器可以先不配置拉到下一步我们稍后手动配。验证完成后向导会把YourDB加入到可选状态然后执行、完成。如果习惯用脚本一步到位T-SQL的核心骨架是这样的CREATE AVAILABILITY GROUP [AG1] WITH ( AUTOMATED_BACKUP_PREFERENCE SECONDARY, DB_FAILOVER ON, CLUSTER_TYPE WSFC ) FOR DATABASE [YourDB] REPLICA ON NSQL01 WITH ( ENDPOINT_URL NTCP://SQL01.contoso.com:5022, FAILOVER_MODE AUTOMATIC, AVAILABILITY_MODE SYNCHRONOUS_COMMIT, SECONDARY_ROLE (ALLOW_CONNECTIONS READ_ONLY) ), NSQL02 WITH ( ENDPOINT_URL NTCP://SQL02.contoso.com:5022, FAILOVER_MODE AUTOMATIC, AVAILABILITY_MODE SYNCHRONOUS_COMMIT, SECONDARY_ROLE (ALLOW_CONNECTIONS READ_ONLY) );创建完成后去SQL02上执行下面三条命令把辅助副本和数据库都“接入”可用性组ALTER AVAILABILITY GROUP [AG1] JOIN; ALTER AVAILABILITY GROUP [AG1] GRANT CREATE ANY DATABASE; ALTER DATABASE [YourDB] SET HADR AVAILABILITY GROUP [AG1];到这一步打开SSMS的“AlwaysOn高可用性”仪表板正常情况下你应该看到两个副本都显示为“同步”状态数据复制已经在往下走了。3.5 第5步配置侦听器应用连接不再翻车侦听器给应用提供一个固定的虚拟IP和端口。无论主副本在SQL01还是SQL02应用只需要连接这个虚拟地址其他什么都不用管。侦听器可以用T-SQL创建ALTER AVAILABILITY GROUP [AG1] ADD LISTENER NAGListener ( WITH IP ((N192.168.1.110, N255.255.255.0)), PORT 1433 );创建完成后在域控的DNS上会看到AGListener对应的A记录自动注册。应用连接字符串这样写就可以ServerAGListener,1433;DatabaseYourDB;Integrated SecurityTrue;MultiSubnetFailoverTrue;额外说一句MultiSubnetFailoverTrue这个参数即使你的环境只有一个子网也建议加上。它能确保故障转移后客户端更快发现新主副本避免几天后你忘了这个问题又来踩一遍连接超时的坑。3.6 第6步手动故障转移与自动故障转移验证可用性组创建好不代表高可用已经生效必须实际验证一次故障转移。先验证同步状态SELECT replica_server_name, role_desc, synchronization_health_desc FROM sys.dm_hadr_availability_replica_states;期望看到SQL01是PRIMARYSQL02是SECONDARY同步健康状态都是HEALTHY。再手动触发一次故障转移把主副本切到SQL02ALTER AVAILABILITY GROUP [AG1] FAILOVER;执行后回到群集管理器里观察“角色”资源是否从SQL01名下移动到SQL02名下。然后用SSMS连接AGListener确认能连上且读写正常。自动故障转移的验证办法是模拟宕机直接对SQL01执行强制关机或者停掉SQL Server服务。等待几十秒打开群集管理器看SQL02是否自动变成了主副本再用AGListener连接一切正常就说明整条链路真正通了。4. 部署中最容易翻车的5个问题与排查技巧即便照着文档一路操作AlwaysOn部署过程中仍然有不少老熟人会准时出现。这里把我踩过和身边人踩过的坑直接整理成速查表碰到类似问题不用慌对着定位。4.1 现象对照表先定位问题再动手问题现象可能原因排查与处理SSMS里“AlwaysOn高可用性”选项是灰色或不存在SQL Server不是企业版或服务未启用AlwaysOn或实例未加入WSFC查询IsHadrEnabled检查SQL Server版本重启服务向导可用但数据库列表为空数据库不是完整恢复模式或没做过完整备份改成FULL恢复模式做一次完整备份辅助副本同步状态一直“未同步”日志链中断或辅助副本还原状态不对检查RESTORE是否用了NORECOVERY重新做完整加日志备份再还原可用性组创建成功数据库状态为“已挂起”辅助副本无法访问主副本的日志流检查5022端口、端点配置、SQL服务账号权限侦听器创建成功但应用连不上DNS未注册或防火墙1433未放行或客户端没开MultiSubnetFailover检查DNS A记录测试端口调整连接字符串自动故障转移不触发可用性模式不是同步提交故障转移模式不是自动或仲裁见证离线检查副本属性确认文件共享见证在线辅助副本想连但报错未配置只读路由或连接时没带ApplicationIntent配置只读路由连接串加ApplicationIntentReadOnly群集验证时网络绑定报警节点有多块网卡或IPV6干扰固定网卡顺序禁用无用的虚拟网卡必要时禁用IPV64.2 三个我踩过多次的坑提前帮你避开第一个坑是把备份文件放在SQL节点本地盘上然后在辅助节点上还原时才发现路径不可达。你以为是文件复制一下的事但生产环境经常有合规要求不允许随意拷贝备份。更合理的方式是从一开始就准备好一个备份共享目录主节点备份直接写过去辅助节点直接从这个共享路径还原。省时省事还能顺便给日志备份留个统一出口。第二个坑是同步提交模式下的性能焦虑。同步提交看起来会让每小时几万次提交的业务卡顿但实际上影响的是每次事务的提交时延不是总吞吐量。只要两个节点网络延迟低于1ms大多数业务根本感受不到区别。我见过不少人为了“提升性能”把同步提交改成了异步结果主节点一挂几十秒的数据直接丢失业务组追责时无从辩解。基础高可用方案里能用同步就坚持同步。第三个坑是只验证了“手动故障转移成功”就宣布完工。自动故障转移的触发条件和手动是不一样的手动转移不关心群集仲裁和可用性模式的限制自动转移则要求副本必须配置为同步提交故障转移模式为自动且群集仲裁在线。很多人部署完只点了手动切换等真出事故时发现自动转移没起来所有节点一起离线。所以一定要在验证阶段主动对主节点执行强制关机跑一遍完整的自动故障转移演练。最后一个经验也算是我个人的心得AlwaysOn部署完以后最值得长期盯的数据不是群集状态而是副本的数据同步时间延迟。你可以在辅助节点上定期跑这条SQL看看日志硬化延迟和同步延迟SELECT replica_server_name, database_name, synchronization_state_desc, last_hardened_time, DATEDIFF(SECOND, last_hardened_time, GETDATE()) AS sync_lag_seconds FROM sys.dm_hadr_database_replica_states;只要这个值长期保持在几秒以内你的高可用环境就在以正确的姿态运行。如果这个值逐渐变大先查网络再查辅助节点磁盘写入性能基本能定位到根本原因。AlwaysOn这东西只要架构搭对了后面的运维其实要比你想象的安静得多。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门