Skip to content

MySQL 异地灾备

异地灾备是 MySQL 高可用架构的重要组成部分,能够在主数据中心发生灾难时,确保业务数据的安全性和可用性。本文将详细介绍 MySQL 异地灾备的设计和实践,包括灾备架构、复制配置、切换流程和最佳实践,兼顾不同 MySQL 版本的差异,帮助 DBA 团队设计和实施有效的异地灾备方案。

异地灾备概述

1. 异地灾备的概念

异地灾备是指在不同地理位置的数据中心部署数据库备份系统,当主数据中心发生灾难时,能够快速切换到灾备数据中心,确保业务连续性。

2. 异地灾备的分级

根据灾难恢复能力的不同,异地灾备可以分为以下几个级别:

灾备级别特点RTORPO
第0级:无灾备没有任何灾备措施数天到数周全部数据丢失
第1级:本地备份仅在本地进行数据备份数小时到数天小时级数据丢失
第2级:热备份本地有热备份系统数小时分钟级数据丢失
第3级:温站灾备异地有温备份系统数小时分钟级数据丢失
第4级:冷站灾备异地有冷备份系统数小时到数天小时级数据丢失
第5级:双活/多活异地有活跃系统,可快速切换秒级到分钟级秒级数据丢失

3. 异地灾备的关键指标

  • RTO(恢复时间目标):灾难发生后,系统恢复正常运行的最长时间
  • RPO(恢复点目标):灾难发生后,允许丢失的数据量(时间维度)
  • RTO 演练值:实际演练中达到的恢复时间
  • RPO 演练值:实际演练中达到的恢复点

异地灾备架构设计

1. 主从复制架构

1.1 架构原理

主从复制架构是最基础的异地灾备架构,通过 MySQL 主从复制将主数据中心的数据同步到灾备数据中心。

主数据中心(DC1)          灾备数据中心(DC2)
┌─────────────┐          ┌─────────────┐
│ 主库(Master)│────────▶│ 从库(Slave)│
└─────────────┘          └─────────────┘
        │                         │
        ▼                         ▼
┌─────────────┐          ┌─────────────┐
│ 从库(Slave)│          │ 应用系统    │
└─────────────┘          └─────────────┘
        │                         │
        ▼                         ▼
┌─────────────┐          ┌─────────────┐
│ 应用系统    │          │ 监控系统    │
└─────────────┘          └─────────────┘

1.2 适用场景

  • 对 RTO 和 RPO 要求不是特别严格的场景
  • 预算有限的场景
  • 小规模应用

1.3 配置示例

ini
# 主库配置(DC1)
[mysqld]
server-id = 101
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON

# 从库配置(DC2)
[mysqld]
server-id = 201
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON
read_only = 1
super_read_only = 1

2. 级联复制架构

2.1 架构原理

级联复制架构通过中间从库将主数据中心的数据同步到灾备数据中心,减少主库的复制压力。

主数据中心(DC1)          灾备数据中心(DC2)
┌─────────────┐          ┌─────────────┐
│ 主库(Master)│────────▶│ 中间从库    │────────▶│ 灾备从库    │
└─────────────┘          └─────────────┘          └─────────────┘
        │                         │                         │
        ▼                         ▼                         ▼
┌─────────────┐          ┌─────────────┐          ┌─────────────┐
│ 从库(Slave)│          │ 从库(Slave)│          │ 应用系统    │
└─────────────┘          └─────────────┘          └─────────────┘

2.2 适用场景

  • 主库负载较高的场景
  • 灾备数据中心距离较远的场景
  • 需要减少主库复制压力的场景

2.3 配置示例

sql
-- 中间从库配置(DC1)
CHANGE MASTER TO
  MASTER_HOST = '192.168.1.101',
  MASTER_USER = 'repl',
  MASTER_PASSWORD = 'Repl@123456',
  MASTER_AUTO_POSITION = 1;

START SLAVE;

-- 灾备从库配置(DC2)
CHANGE MASTER TO
  MASTER_HOST = '192.168.1.102',
  MASTER_USER = 'repl',
  MASTER_PASSWORD = 'Repl@123456',
  MASTER_AUTO_POSITION = 1;

START SLAVE;

3. 双主复制架构

3.1 架构原理

双主复制架构是指两个数据中心的数据库相互复制,每个数据中心都可以写入数据。

主数据中心(DC1)          灾备数据中心(DC2)
┌─────────────┐          ┌─────────────┐
│ 主库(Master1)│◀────────▶│ 主库(Master2)│
└─────────────┘          └─────────────┘
        │                         │
        ▼                         ▼
┌─────────────┐          ┌─────────────┐
│ 应用系统    │          │ 应用系统    │
└─────────────┘          └─────────────┘

3.2 适用场景

  • 需要双向数据同步的场景
  • 双活或多活架构
  • 对 RTO 要求较高的场景

3.3 配置示例

ini
# 主库1配置(DC1)
[mysqld]
server-id = 101
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON

# 自动递增配置
auto_increment_increment = 2
auto_increment_offset = 1

# 主库2配置(DC2)
[mysqld]
server-id = 201
log_bin = mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON

# 自动递增配置
auto_increment_increment = 2
auto_increment_offset = 2

4. MGR 架构

4.1 架构原理

MGR 是 MySQL 8.0 引入的原生高可用方案,支持跨数据中心部署,提供自动故障切换和数据一致性保证。

主数据中心(DC1)          灾备数据中心(DC2)
┌─────────────┐          ┌─────────────┐
│ MGR 节点1   │          │ MGR 节点3   │
└─────────────┘          └─────────────┘
        │                         │
        └─────────────────────────┘

        ┌─────────┘

┌─────────────┐
│ MGR 节点2   │
└─────────────┘

4.2 适用场景

  • 对数据一致性要求较高的场景
  • 对 RTO 要求较高的场景
  • 双活或多活架构

4.3 配置示例

ini
# MGR 节点配置(所有节点)
[mysqld]
server-id = 101
plugin-load = group_replication.so
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON
binlog_transaction_dependency_tracking = WRITESET
group_replication_bootstrap_group = OFF
group_replication_start_on_boot = OFF
group_replication_ssl_mode = REQUIRED
group_replication_recovery_use_ssl = 1
group_replication_group_name = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_local_address = "node1:33061"
group_replication_group_seeds = "node1:33061,node2:33061,node3:33061"
group_replication_single_primary_mode = ON
group_replication_member_expel_timeout = 5

异地灾备复制配置

1. 网络配置

1.1 网络延迟优化

  • 使用专线或 VPN 连接两个数据中心
  • 优化网络路由,减少网络跳数
  • 启用复制压缩,减少网络带宽消耗
  • 配置合理的复制延迟阈值

1.2 复制压缩配置

ini
# 主库配置
slave_compressed_protocol = 1

# 从库配置
slave_compressed_protocol = 1

2. 复制模式选择

2.1 异步复制

  • 特点:主库写入数据后立即返回,不等待从库确认
  • RPO:可能丢失大量数据
  • 适用场景:对 RPO 要求不高的场景

2.2 半同步复制

  • 特点:主库写入数据后,等待至少一个从库确认后返回
  • RPO:可能丢失少量数据
  • 适用场景:对 RPO 有一定要求的场景

2.3 增强半同步复制

  • 特点:主库写入数据后,等待至少一个从库将数据写入磁盘后返回
  • RPO:数据丢失风险较低
  • 适用场景:对 RPO 要求较高的场景

2.4 配置示例

ini
# 主库配置(半同步复制)
plugin-load = "rpl_semi_sync_master=semisync_master.so"
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 10000

# 从库配置(半同步复制)
plugin-load = "rpl_semi_sync_slave=semisync_slave.so"
rpl_semi_sync_slave_enabled = 1

3. 复制过滤配置

3.1 复制过滤类型

  • 基于数据库的过滤:只复制特定数据库
  • 基于表的过滤:只复制特定表
  • 基于正则表达式的过滤:根据正则表达式过滤复制对象

3.2 配置示例

ini
# 基于数据库的过滤(从库配置)
# 只复制 test 和 production 数据库
replicate-do-db = test
replicate-do-db = production

# 基于表的过滤(从库配置)
# 只复制 test 数据库的 user 和 order 表
replicate-do-table = test.user
replicate-do-table = test.order

# 基于正则表达式的过滤(从库配置)
# 只复制以 prod_ 开头的数据库
replicate-wild-do-table = prod_%.%

异地灾备切换流程

1. 切换前准备

1.1 灾难确认

  • 确认主数据中心发生灾难,无法恢复
  • 确认灾备数据中心的状态正常
  • 确认灾备数据的完整性

1.2 切换决策

  • 成立切换决策小组
  • 评估灾难影响范围
  • 确定切换方案和时间
  • 通知相关团队和业务方

2. 切换执行

2.1 灾备库准备

sql
-- 1. 停止从库复制
STOP SLAVE;
RESET SLAVE ALL;

-- 2. 解除只读模式
SET GLOBAL read_only = 0;
SET GLOBAL super_read_only = 0;

-- 3. 如果使用 GTID 复制,确保所有事务已提交
SET @@GLOBAL.gtid_purged = (SELECT @@GLOBAL.gtid_executed);

2.2 应用切换

  • 更新应用的数据库连接配置,指向灾备库
  • 重启应用或刷新连接池
  • 验证应用连接和业务功能

2.3 DNS 切换

  • 更新 DNS 记录,将数据库服务指向灾备数据中心
  • 配置 DNS 缓存失效时间,加速切换

2.4 监控和验证

  • 监控灾备库的性能和稳定性
  • 验证业务功能的完整性
  • 检查数据一致性

3. 切换后处理

3.1 原主数据中心恢复

  • 修复原主数据中心的故障
  • 原主库作为从库连接到灾备库
  • 验证原主库的复制状态

3.2 灾备架构调整

  • 调整灾备架构,确保新的主库有足够的冗余
  • 配置新的灾备复制关系
  • 更新监控和告警配置

3.3 切换总结

  • 记录切换过程和时间点
  • 分析切换过程中的问题和改进点
  • 编写详细的切换报告
  • 跟踪改进措施的落实

不同 MySQL 版本的异地灾备支持

MySQL 5.6

  • 支持主从复制(异步和半同步)
  • 支持 GTID 复制(但功能有限)
  • 复制延迟可能较高
  • 灾备切换流程复杂

MySQL 5.7

  • 增强了 GTID 复制的可靠性
  • 支持基于逻辑时钟的并行复制,减少复制延迟
  • 支持增强半同步复制,提高数据安全性
  • 支持多源复制,适合复杂灾备架构

MySQL 8.0

  • 引入了 MGR,原生支持跨数据中心部署
  • 增强了 GTID 复制的性能
  • 支持基于 WRITESET 的并行复制,进一步减少复制延迟
  • 支持复制通道的加密,提高安全性
  • 与 MGR 集成良好,支持自动故障切换

异地灾备最佳实践

1. 架构设计

  • 选择合适的灾备架构,平衡成本和 RTO/RPO 要求
  • 考虑数据中心之间的网络延迟
  • 配置合理的复制模式
  • 设计完善的切换流程

2. 复制配置

  • 启用 GTID 复制,简化切换流程
  • 启用半同步或增强半同步复制,提高数据安全性
  • 配置复制压缩,减少网络带宽消耗
  • 配置合理的复制过滤规则

3. 监控告警

  • 监控复制延迟和状态
  • 监控网络连接状态
  • 配置复制中断告警
  • 配置灾备库状态监控

4. 测试验证

  • 定期进行灾备切换演练
  • 测试不同灾难场景下的切换效果
  • 验证灾备数据的完整性
  • 测试应用的切换兼容性

5. 文档管理

  • 编写详细的灾备架构文档
  • 编写详细的切换流程文档
  • 编写回滚计划
  • 定期更新文档

异地灾备常见问题与解决方案

1. 复制延迟过大

症状:主从复制延迟过大,影响灾备的 RPO

解决方案

  • 优化主库性能,减少主库负载
  • 增加从库的并行复制线程数
  • 启用基于逻辑时钟或 WRITESET 的并行复制
  • 优化网络连接,减少网络延迟

2. 复制中断

症状:主从复制中断,影响灾备数据的同步

解决方案

  • 检查复制错误日志,定位中断原因
  • 修复中断原因,重新启动复制
  • 配置复制中断告警
  • 实现复制自动恢复机制

3. 数据不一致

症状:主从库数据不一致,影响灾备的可靠性

解决方案

  • 定期使用 pt-table-checksum 检查数据一致性
  • 使用 pt-table-sync 修复数据不一致
  • 启用半同步或增强半同步复制
  • 设计合理的复制过滤规则

4. 切换时间过长

症状:切换时间超过预期,影响业务可用性

解决方案

  • 优化切换流程,减少切换步骤
  • 提高团队的操作熟练度
  • 考虑使用自动化工具
  • 设计并行切换方案

总结

异地灾备是 MySQL 高可用架构的重要组成部分,能够在主数据中心发生灾难时,确保业务数据的安全性和可用性。选择合适的灾备架构、配置合理的复制模式、设计完善的切换流程是异地灾备成功的关键。不同 MySQL 版本的异地灾备支持有所差异,需要根据实际版本进行调整。

在实施异地灾备时,需要注意以下几点:

  1. 选择合适的灾备架构,平衡成本和 RTO/RPO 要求
  2. 配置合理的复制模式,提高数据安全性
  3. 设计完善的切换流程和回滚计划
  4. 定期进行灾备切换演练
  5. 建立完善的监控和告警机制
  6. 编写详细的灾备文档

通过合理的异地灾备设计和实施,可以确保在主数据中心发生灾难时,能够快速、准确地进行切换,减少业务中断时间,提高系统的可用性和可靠性。