第九期:高可用与灾难恢复 —— 日志传送、复制、Always On

0 阅读9分钟

### 第九期:高可用与灾难恢复 —— 日志传送、复制、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分析,如何建立系统化的性能优化流程?