本节摘要:可用性组(Always On Availability Groups)是 SQL Server 高可用的现代答案:一组副本共同维护用户数据库,故障时监听器带着角色整体漂移,应用无感重连。本节讲清它的三层架构、同步与异步的语义光谱、三种接管形式与仲裁配置,最后给出一套可复现的季度接管演练流程。高可用不是装出来的,是演练出来的。
先立两个数字再谈技术。RPO(恢复点目标)回答"最多能丢多少数据";RTO(恢复时间目标)回答"最多停多久"。所有高可用选型都是这两个数字与成本的博弈:RPO 为零意味着必须同步复制(每笔提交等所有同步副本落盘确认),RTO 以秒计意味着必须有自动故障转移加监听器。反过来,报表型系统 RPO 容忍分钟级、RTO 容忍小时级,那异步副本加脚本接管就够了——把钱包花在业务真正需要的数字上。
可用性组的三层架构:最底层是 Windows 服务器故障转移集群(WSFC),提供节点存活检测与仲裁投票;中间层是可用性组本体,把一组用户数据库作为整体在副本间同步日志块;最上层是监听器,一个虚拟网络名加虚拟 IP,应用连接串只认它。三层各自有独立性:可用性组跑在集群上但不要求共享存储,每个副本本地都有完整数据——这让它既能当高可用(同城同步副本自动接管),又能当灾备(异地异步副本扛机房灾难),还能当扩展(副本开放只读分担报表)。
同步提交:主副本把日志块发到同步副本,等对方持久化确认后才向客户端返回提交成功——RPO 严格为零,代价是每笔事务的网络往返,所以同步副本必须放在低延迟网络内(同城或同园区)。异步提交:发出即走,不等确认——吞吐不受链路影响,但故障切换可能丢掉传输中的日志(RPO 大于零),适合异地灾备与只读分流。接管形式有三种:自动故障转移(同步副本配自动模式,集群检测故障秒级漂移,前提是副本数据同步且仲裁健康)、计划内手动转移(升级补丁前的受控切换,秒级且零丢失)、强制转移(主副本彻底损坏时接受数据丢失强行拉起,属于灾备手段,之后必须立刻补备份重置同步)。仲裁是集群防脑裂的投票机制:节点、共享磁盘、文件共享见证都有票,总数过半的一方才有权运行——两节点集群必须加见证凑奇数票,否则网络分区时两边都不敢当主,服务全停(比脑裂更隐蔽的故障形态)。
-- 建组的骨架:先建端点与集群资源,这里给组与副本的关键子句 CREATE AVAILABILITY GROUP [AG_订单核心] FOR DATABASE [订单库] REPLICA ON N'NODE1' WITH (ENDPOINT_URL = N'TCP://node1.corp.local:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = AUTOMATIC, -- 同步加自动 = 可无感接管 SEEDING_MODE = AUTOMATIC), -- 自动播种:新副本自动初始化 N'NODE2' WITH (ENDPOINT_URL = N'TCP://node2.corp.local:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = AUTOMATIC, SEEDING_MODE = AUTOMATIC), N'NODE3-DR' WITH (ENDPOINT_URL = N'TCP://node3-dr.corp.local:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, -- 异地副本手动接管扛灾难 SEEDING_MODE = AUTOMATIC);
-- 值班巡检:同步状态与健康延迟一目了然 SELECT ar.replica_server_name AS 副本, db.database_name AS 库名, drs.synchronization_state_desc AS 同步状态, -- SYNCHRONIZED 才算健康 drs.log_send_queue_size AS 日志积压KB, drs.redo_queue_size AS 重做积压KB FROM sys.dm_hadr_database_replica_states drs JOIN sys.availability_replicas ar ON ar.replica_id = drs.replica_id JOIN sys.databases db ON db.database_id = drs.database_id; -- 日志积压持续增长:链路带宽不足或副本磁盘跟不上,异步副本会拉长 RPO。
高可用的可靠性由演练频率决定,不由架构图决定。季度演练剧本四幕:第一幕对账——确认三个副本同步状态健康、积压为零、备份作业全部成功;第二幕计划内接管——维护窗口执行手动转移到节点二,观察监听器漂移与应用重连时长,记录 RTO 实测值;第三幕破坏性测试——在测试环境直接断节点一电源,验证自动转移与仲裁行为,同时验证见证节点失联场景(应表现为服务暂停而非脑裂);第四幕复盘归档——把实测 RTO 与设计值对比,差一个数量级就要查:应用连接串是否写死了节点名(写死即绕过监听器,接管必断)、作业是否有对"主副本"的硬编码假设、登录名与作业是否在副本间同步(常见事故:切换成功但作业没跑,因为 SQL 代理作业只存在原主上——副本侧登录与作业同步要纳入配置管理)。
一次真实教训归档于此:某系统演练接管一切正常,真故障当晚却发现应用连不上——排查发现应用连接池在切换瞬间缓存的旧连接没有失效重试逻辑。架构做了万全准备,最后一米倒在了应用代码。此后该团队的演练剧本加了一幕:从应用侧发起的端到端验证,不满足于数据库层自己说"我切换成功了"。
可用性组保运行,但副本会忠实复制误删——对抗逻辑错误要靠另一件武器:备份链。下一节把备份还原做成一次可复现的演练。