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

第九期:高可用与灾难恢复 —— 日志传送、复制、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

    );

关键限制

[quads id="805"]
  • 一个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<em>hadr</em>* |

| 日志传送延迟大 | 网络慢、作业冲突 | 检查复制、还原作业耗时 |

| 复制跳过某些行 | 冲突、数据不一致、约束失败 | 查看复制监视器、分发数据库错误表 |

| 辅助库无法查询 | 正在还原日志、未开启只读 | 设置STANDBY模式或AG读路由 |

| RPO超过预期 | 异步模式、网络高延迟 | 改用同步,或压缩日志备份 |

10. 最佳实践总结

  1. Always On 为主流首选(SQL Server 2012+):
  • 灵活性高(同步/异步,自动/手动)

  • 支持多种场景(本地HA+异地DR)

  • 从库可用于备份和报表

  1. 日志传送作为补充
  • 简单易维护,RPO可控

  • 适合低成本DR方案

  • 可配合AG使用(备份还原延迟保护)

  1. 复制用于特定需求
  • 数据分发(中心到分支)

  • 异构环境(Oracle → SQL Server)

  • 实时报表卸载

  1. 定期演练
  • 每季度一次计划内切换

  • 每年一次灾难恢复模拟

  • 验证RTO/RPO是否达标

  1. 监控关键指标
  • 同步延迟(秒)

  • 未发送/未还原日志量(KB)

  • 集群仲裁状态

  • 复制延迟和冲突数


第九期小结

高可用与灾难恢复的选择取决于RTO/RPO要求、预算和运维能力。Always On AG是当前功能最全面的解决方案,支持同步提交实现零数据丢失,异步提交支持异地容灾。日志传送适合预算有限的DR场景,复制则解决特定数据分发问题。无论选择哪种技术,定期演练和健全的监控都是保证故障时能正确恢复的关键。

下期预告:性能监控与调优方法论 —— 从等待统计到DMV分析,如何建立系统化的性能优化流程?

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top