### 第九期:高可用与灾难恢复 —— 日志传送、复制、Always On
#### 1. 高可用 vs 灾难恢复:两个不同的目标
| 维度 | 高可用(HA) | 灾难恢复(DR) |
|------|-------------|---------------|
| **目标** | 应对局部故障(服务器、磁盘、网络) | 应对大规模灾难(机房、城市、自然灾害) |
| **指标** | RTO:分钟级,RPO:秒级或零 | RTO:小时级,RPO:分钟到小时级 |
| **距离** | 同机房或同城 | 异地或跨区域 |
| **典型技术** | 故障转移集群,Always On | 日志传送,异地备份 |
| **自动切换** | 通常自动 | 通常手动 |
关键术语:
- **RTO(恢复时间目标)**:从故障到恢复服务的时间
- **RPO(恢复点目标)**:允许丢失的数据时间窗口
#### 2. SQL Server 高可用技术全景
| 技术 | 范围 | 数据丢失 | 自动切换 | 复杂度 | 适用场景 |
|------|------|----------|----------|--------|----------|
| 故障转移集群 | 实例级 | 可能(取决于磁盘) | 是 | 中 | 共享存储,传统HA |
| 日志传送 | 数据库级 | 分钟级 | 否 | 低 | DR,报表服务器 |
| 事务复制 | 表级 | 秒级 | 否 | 高 | 数据分发,多主 |
| 合并复制 | 表级 | 分钟级 | 否 | 高 | 移动/离线场景 |
| 镜像(已弃用) | 数据库级 | 秒~零 | 是 | 中 | 老环境 |
| Always On AG | 数据库级 | 零(同步)| 是 | 中高 | 现代HA+DR首选 |
| Always On FCI | 实例级 | 可能 | 是 | 中 | 共享存储或无存储AG |
#### 3. 故障转移集群(FCI)
**架构图**:
  客户端
  ↓
  虚拟网络名
  ↓
  活动节点 ← 心跳 ← 备用节点
  ↓ ↓
  共享存储(SAN)────┘
**工作原理**:
- 多台服务器共享同一存储(SAN、SMB文件共享)
- SQL Server 服务只能在一个节点上运行
- 节点间通过心跳网络相互监控
- 故障时,备用节点挂载存储,启动服务
**切换类型**:
| 切换类型 | 触发条件 | 影响 |
|----------|----------|------|
| 计划内切换 | 手动,运维操作 | 短暂中断(秒级) |
| 故障自动切换 | 节点崩溃、网络中断 | 可能丢失未提交事务 |
| 强制仲裁切换 | 多数节点故障 | 可能丢失数据 |
**优劣**:
- ✅ RTO短(10-30秒),配置相对简单
- ❌ 共享存储是单点故障,成本高(SAN设备)
#### 4. 日志传送(Log Shipping)
**架构流程**:
主服务器 辅助服务器
  ↓ ↓
事务日志备份 -----→ 复制日志文件 -----→ 还原(只读模式)
  ↓ ↓
日志备份文件夹 等待下一个日志
**三个作业**:
1. **备份作业**:在主服务器上定期备份事务日志
2. **复制作业**:将备份文件复制到辅助服务器
3. **还原作业**:在辅助服务器上还原日志(可以配置为待机/只读模式)
**配置示例**:
\-- 主服务器设置
EXEC sp\_add\_log\_shipping\_primary\_database
  @database = 'OrdersDB',
  @backup\_directory = '\\\\backupserver\\logs',
  @backup\_share = '\\\\backupserver\\logs',
  @backup\_job\_name = 'LSBackup\_OrdersDB',
  @backup\_retention\_period = 4320, -- 保留3天
  @monitor\_server = 'MonitorServer';
\-- 辅助服务器设置
EXEC sp\_add\_log\_shipping\_secondary\_database
  @secondary\_database = 'OrdersDB',
  @primary\_server = 'PrimaryServer',
  @primary\_database = 'OrdersDB',
  @restore\_delay = 0, -- 立即还原
  @restore\_mode = 1; -- 待机/只读模式
**成败关键**:
- RPO = 日志备份间隔(通常15-30分钟)
- RTO = 手动故障转移时间(可能10-60分钟)
- 辅助库可用于报表查询(在还原期间短暂中断)
#### 5. Always On 可用性组(AG)
**核心概念**:
| 概念 | 说明 |
|------|------|
| 可用性副本 | 每个SQL Server实例是一个副本(主+最多8个从) |
| 可用性数据库 | AG保护的数据库集合 |
| 同步提交 | 主库等待从库确认日志硬化后才提交(RPO=0) |
| 异步提交 | 主库不等待从库(高性能,可能丢数据) |
| 自动故障转移 | 仅同步提交副本支持 |
| 手动故障转移 | 同步或异步都支持 |
| 只读路由 | 将读请求自动转发到辅助副本 |
| 侦听器 | 虚拟网络名+IP,客户端连接点 |
**部署架构示例**:
  客户端
  ↓
  可用性组侦听器
  ↓
  ┌─────┴─────┐
  ↓ ↓
  主副本 辅助副本
(同步提交) (同步提交)
  / \\ / \\
 生产DC1 生产DC2
  ↘ ↙
  异步副本(DR中心)
  (异步提交)
**创建AG示例**:
\-- 创建端点(加密通信)
CREATE ENDPOINT HadrEndpoint
  STATE=STARTED
  AS TCP (LISTENER\_PORT=5022)
  FOR DATA\_MIRRORING (ROLE=ALL);
\-- 创建可用性组
CREATE AVAILABILITY GROUP OrdersAG
  WITH (CLUSTER\_TYPE = WSFC) -- Windows故障转移集群
  FOR DATABASE OrdersDB
  REPLICA ON
  'PrimaryServer' WITH (
  ENDPOINT\_URL = 'TCP://PrimaryServer:5022',
  AVAILABILITY\_MODE = SYNCHRONOUS\_COMMIT,
  FAILOVER\_MODE = AUTOMATIC
  ),
  'SecondaryServer' WITH (
  ENDPOINT\_URL = 'TCP://SecondaryServer:5022',
  AVAILABILITY\_MODE = SYNCHRONOUS\_COMMIT,
  FAILOVER\_MODE = AUTOMATIC
  );
\-- 添加侦听器
ALTER AVAILABILITY GROUP OrdersAG
  ADD LISTENER 'OrdersAG\_Listener' (
  WITH IP (('192.168.1.100', '255.255.255.0')),
  PORT=1433
  );
**关键限制**:
- 一个AG最多9个副本(1主+8从)
- 每个数据库只能属于一个AG
- 辅助副本不能直接写入(可用只读操作)
- 跨版本有限支持(从库可低于主库两个版本)
**监控AG健康**:
\-- 检查副本状态
SELECT replica\_server\_name, role\_desc, synchronization\_health\_desc
FROM sys.dm\_hadr\_availability\_replica\_states;
\-- 检查数据同步延迟
SELECT ag.name, db\_name(database\_id) as dbname,
  log\_send\_queue\_size, log\_send\_rate,
  redo\_queue\_size, redo\_rate
FROM sys.dm\_hadr\_database\_replica\_states drs
JOIN sys.availability\_groups ag ON drs.group\_id = ag.group\_id;
#### 6. 复制技术(Replication)
**三种类型对比**:
| 类型 | 数据流向 | 延迟 | 冲突处理 | 适用场景 |
|------|----------|------|----------|----------|
| 快照复制 | 单向 | 高(定时复制)| 无 | 小表,静态数据 |
| 事务复制 | 单向 | 低(秒级)| 无(默认)| 数据分发,报表 |
| 合并复制 | 双向/多向 | 中 | 需要解决 | 移动设备,离线 |
**事务复制架构**:
发布服务器(Publisher)→ 分发服务器(Distributor)→ 订阅服务器(Subscriber)
  ↓ ↓ ↓
  事务日志读取器 分发数据库 应用更改
**创建复制示例**:
\-- 创建发布(主服务器)
EXEC sp\_addpublication
  @publication = 'OrdersPub',
  @description = '发布订单表',
  @sync\_method = 'native',
  @repl\_freq = 'continuous', -- 连续(事务复制)
  @status = 'active';
\-- 添加项目(表)
EXEC sp\_addarticle
  @publication = 'OrdersPub',
  @article = 'Orders',
  @source\_object = 'Orders',
  @destination\_table = 'Orders';
\-- 创建订阅(订阅服务器)
EXEC sp\_addsubscription
  @publication = 'OrdersPub',
  @subscriber = 'SubscriberServer',
  @destination\_db = 'OrdersDB\_Sub',
  @status = 'active';
**事务复制冲突**:
- 中心发布服务器模式:一般无冲突
- 可更新订阅:需要冲突解决策略(发布服务器胜出/订阅服务器胜出/自定义)
#### 7. 技术选型决策树
是否要求自动故障转移?
├─ 是 → 是否允许数据丢失?
│ ├─ 零丢失(RPO=0)→ Always On 同步提交(需要2台以上服务器+见证)
│ └─ 秒级丢失(RPO>0)→ 故障转移集群 或 Always On 异步提交
│
└─ 否 → 是否需要辅助库做报表查询?
  ├─ 是 → 日志传送(简单) 或 Always On 异步(更强)
  ├─ 部分表需要实时 → 事务复制(灵活)
  └─ 移动/离线场景 → 合并复制
需要考虑其他因素:
\- 数据库数量:Always On 支持多数据库但每个AG上限有限
\- 跨版本:事务复制支持混合版本(2016→2019)
\- 跨平台:AG和FCI要求Windows故障转移集群(不支持Linux?现在部分支持)
\- 网络延迟:同城<1ms可用同步提交,异地用异步
#### 8. 高可用切换演练关键步骤
**计划内切换(Always On)**:
\-- 1. 检查辅助副本状态
SELECT \* FROM sys.dm\_hadr\_database\_replica\_states;
\-- 2. 连接辅助副本准备
ALTER AVAILABILITY GROUP OrdersAG SET (ROLE = SECONDARY);
\-- 3. 执行切换(在主副本执行)
ALTER AVAILABILITY GROUP OrdersAG FAILOVER;
\-- 4. 验证新主副本
SELECT @@SERVERNAME, DATABASEPROPERTYEX('OrdersDB', 'Updateability');
**灾难后强制恢复(日志传送)**:
\-- 1. 备份尾日志(如果主库还可用)
BACKUP LOG OrdersDB TO DISK = '\\\\backupserver\\logs\\OrdersDB\_tail.trn'
WITH NORECOVERY;
\-- 2. 应用所有日志到辅助库
RESTORE LOG OrdersDB FROM DISK = '\\\\backupserver\\logs\\orders\_20240101.trn'
WITH RECOVERY;
\-- 3. 启用辅助库对外服务
ALTER DATABASE OrdersDB SET ONLINE;
\-- 4. 重新配置应用连接字符串
#### 9. 常见问题与排查
| 问题 | 常见原因 | 排查方向 |
|------|----------|----------|
| AG切换失败 | 仲裁丢失、健康检查失败 | 查看Windows集群日志,检查sys.dm\_hadr\_\* |
| 日志传送延迟大 | 网络慢、作业冲突 | 检查复制、还原作业耗时 |
| 复制跳过某些行 | 冲突、数据不一致、约束失败 | 查看复制监视器、分发数据库错误表 |
| 辅助库无法查询 | 正在还原日志、未开启只读 | 设置STANDBY模式或AG读路由 |
| RPO超过预期 | 异步模式、网络高延迟 | 改用同步,或压缩日志备份 |
#### 10. 最佳实践总结
1. **Always On 为主流首选**(SQL Server 2012+):
- 灵活性高(同步/异步,自动/手动)
- 支持多种场景(本地HA+异地DR)
- 从库可用于备份和报表
2. **日志传送作为补充**:
- 简单易维护,RPO可控
- 适合低成本DR方案
- 可配合AG使用(备份还原延迟保护)
3. **复制用于特定需求**:
- 数据分发(中心到分支)
- 异构环境(Oracle → SQL Server)
- 实时报表卸载
4. **定期演练**:
- 每季度一次计划内切换
- 每年一次灾难恢复模拟
- 验证RTO/RPO是否达标
5. **监控关键指标**:
- 同步延迟(秒)
- 未发送/未还原日志量(KB)
- 集群仲裁状态
- 复制延迟和冲突数
---
**第九期小结**
高可用与灾难恢复的选择取决于RTO/RPO要求、预算和运维能力。Always On AG是当前功能最全面的解决方案,支持同步提交实现零数据丢失,异步提交支持异地容灾。日志传送适合预算有限的DR场景,复制则解决特定数据分发问题。无论选择哪种技术,定期演练和健全的监控都是保证故障时能正确恢复的关键。
**下期预告**:性能监控与调优方法论 —— 从等待统计到DMV分析,如何建立系统化的性能优化流程?