Skip to content

PostgreSQL 异地灾备架构

异地灾备概述

什么是异地灾备

异地灾备(Remote Disaster Recovery)是指在地理位置上分离的两个或多个数据中心之间建立数据复制关系,当主数据中心发生灾难时,能够在备数据中心恢复业务运行。异地灾备是确保业务连续性的重要手段。

异地灾备的重要性

  • 应对区域性灾难:如地震、洪水、火灾等
  • 满足合规要求:如PCI DSS、ISO 27001等
  • 提高业务连续性:减少停机时间
  • 保护数据安全:防止数据丢失
  • 支持业务扩展:实现多活架构

异地灾备目标

  • RTO(恢复时间目标):从灾难发生到业务恢复的时间
  • RPO(恢复点目标):灾难发生后允许丢失的数据量
  • 数据一致性:确保灾备数据与生产数据一致
  • 自动化恢复:减少人工干预
  • 可测试性:能够定期测试灾备有效性

异地灾备架构类型

1. 异步复制架构

架构说明

异步复制是指主库将WAL日志发送到备库,但不等待备库确认已接收或应用WAL日志。这种架构的特点是:

  • 主库性能影响小
  • 复制延迟可能较大
  • 配置简单,易于部署
  • 适合远距离数据中心

适用场景

  • 对主库性能要求较高
  • 数据中心之间网络延迟较大
  • 可以接受一定的数据丢失
  • 成本有限

架构图

主数据中心(DC1)       备用数据中心(DC2)
+----------------+     +----------------+
|                |     |                |
|  PostgreSQL主库 +---->+  PostgreSQL备库|
|                |     |                |
+----------------+     +----------------+

2. 同步复制架构

架构说明

同步复制是指主库将WAL日志发送到备库,并等待备库确认已写入磁盘后才返回成功给客户端。这种架构的特点是:

  • 数据零丢失
  • 主库性能受网络延迟影响较大
  • 适合近距离数据中心
  • 可靠性高

适用场景

  • 对数据一致性要求极高
  • 数据中心之间网络延迟较小(< 10ms)
  • 可以接受主库性能影响
  • 金融、证券等行业

架构图

主数据中心(DC1)       备用数据中心(DC2)
+----------------+     +----------------+
|                |     |                |
|  PostgreSQL主库 <---->+  PostgreSQL备库|
|                |     |                |
+----------------+     +----------------+
      ^                       |
      |                       |
      +-----------------------+
          同步确认

3. 半同步复制架构

架构说明

半同步复制是介于异步和同步之间的一种复制方式,主库等待至少一个备库确认已接收WAL日志,但不等待备库写入磁盘。这种架构的特点是:

  • 数据丢失风险较小
  • 主库性能影响适中
  • 适合中等距离数据中心
  • 平衡了性能和可靠性

适用场景

  • 对数据一致性要求较高
  • 数据中心之间网络延迟中等(10-50ms)
  • 希望平衡性能和可靠性
  • 大多数企业级应用

架构图

主数据中心(DC1)       备用数据中心(DC2)
+----------------+     +----------------+
|                |     |                |
|  PostgreSQL主库 +---->+  PostgreSQL备库|
|                |<----+                |
+----------------+     +----------------+
      ^                       |
      |                       |
      +-----------------------+
          接收确认

4. 级联复制架构

架构说明

级联复制是指主库只向一个备库发送WAL日志,然后该备库再将WAL日志转发给其他备库。这种架构的特点是:

  • 减少主库的复制压力
  • 可以支持更多的备库
  • 适合复杂的灾备拓扑
  • 复制延迟可能会累积

适用场景

  • 需要多个备库
  • 主库资源有限
  • 复杂的灾备拓扑
  • 分层数据中心架构

架构图

主数据中心(DC1)       中间数据中心(DC2)       备用数据中心(DC3)
+----------------+     +----------------+     +----------------+
|                |     |                |     |                |
|  PostgreSQL主库 +---->+  PostgreSQL备库 +---->+  PostgreSQL备库|
|                |     |                |     |                |
+----------------+     +----------------+     +----------------+

异地灾备部署方案

1. 部署前准备

网络规划

  • 网络带宽:根据数据量和RPO要求确定带宽需求
  • 网络延迟:尽量控制在可接受范围内
  • 网络可靠性:使用专线或VPN确保连接稳定
  • 网络安全性:加密传输,使用SSL/TLS

硬件规划

  • 服务器配置:与主库相似的配置
  • 存储配置:足够的存储空间,考虑数据增长
  • 备份设备:独立的备份存储
  • 监控设备:监控服务器和网络

软件规划

  • PostgreSQL版本:与主库相同版本
  • 复制方式:流复制或逻辑复制
  • 高可用工具:Patroni、repmgr等
  • 监控工具:Prometheus + Grafana、Zabbix等

2. 异步复制部署

1. 配置主库

sql
-- 创建复制用户
CREATE USER replicator REPLICATION LOGIN PASSWORD 'replicator_password';

-- 配置postgresql.conf
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
wal_keep_size = 8192
wal_sender_timeout = 60s

-- 配置pg_hba.conf
host    replication     replicator     备库IP/32            scram-sha-256

2. 配置备库

bash
# 初始化备库数据目录
pg_basebackup -h 主库IP -U replicator -D /var/lib/pgsql/14/data -Fp -Xs -P -R

# 配置recovery.signal
cat > /var/lib/pgsql/14/data/recovery.signal << 'EOF'
standby_mode = 'on'
primary_conninfo = 'host=主库IP port=5432 user=replicator password=replicator_password application_name=备库名称'
EOF

# 启动备库
systemctl start postgresql-14

3. 半同步复制部署

1. 配置主库

sql
-- 安装半同步复制插件
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

-- 配置postgresql.conf
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
wal_keep_size = 8192

-- 启用半同步复制
shared_preload_libraries = 'pgsync,pg_stat_statements'

-- 配置半同步参数
synchronous_commit = on
synchronous_standby_names = '备库名称'

-- 配置pg_hba.conf
host    replication     replicator     备库IP/32            scram-sha-256

2. 配置备库

bash
# 初始化备库数据目录
pg_basebackup -h 主库IP -U replicator -D /var/lib/pgsql/14/data -Fp -Xs -P -R

# 配置recovery.signal
cat > /var/lib/pgsql/14/data/recovery.signal << 'EOF'
standby_mode = 'on'
primary_conninfo = 'host=主库IP port=5432 user=replicator password=replicator_password application_name=备库名称'
EOF

# 启动备库
systemctl start postgresql-14

4. 级联复制部署

1. 配置主库

sql
-- 创建复制用户
CREATE USER replicator REPLICATION LOGIN PASSWORD 'replicator_password';

-- 配置postgresql.conf
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
wal_keep_size = 8192

-- 配置pg_hba.conf
host    replication     replicator     中间备库IP/32            scram-sha-256

2. 配置中间备库

bash
# 初始化中间备库
pg_basebackup -h 主库IP -U replicator -D /var/lib/pgsql/14/data -Fp -Xs -P -R

# 配置postgresql.conf
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
wal_keep_size = 8192

# 配置pg_hba.conf
host    replication     replicator     级联备库IP/32            scram-sha-256

# 启动中间备库
systemctl start postgresql-14

3. 配置级联备库

bash
# 从中间备库初始化级联备库
pg_basebackup -h 中间备库IP -U replicator -D /var/lib/pgsql/14/data -Fp -Xs -P -R

# 配置recovery.signal
cat > /var/lib/pgsql/14/data/recovery.signal << 'EOF'
standby_mode = 'on'
primary_conninfo = 'host=中间备库IP port=5432 user=replicator password=replicator_password application_name=级联备库名称'
EOF

# 启动级联备库
systemctl start postgresql-14

异地灾备监控与管理

1. 复制状态监控

sql
-- 主库查看复制状态
SELECT 
    application_name AS 备库名称,
    client_addr AS 备库IP,
    state AS 复制状态,
    sync_state AS 同步状态,
    pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS 回放延迟_bytes,
    now() - replay_lag AS 时间延迟
FROM pg_stat_replication;

-- 备库查看复制状态
SELECT 
    last_wal_receive_lsn AS 最后接收LSN,
    last_wal_replay_lsn AS 最后回放LSN,
    last_wal_replay_time AS 最后回放时间
FROM pg_stat_wal_receiver;

2. 网络状态监控

  • 监控网络延迟:使用ping、traceroute等工具
  • 监控网络带宽:使用iftop、nload等工具
  • 监控网络丢包率:使用mtr等工具
  • 设置网络告警:当延迟或丢包率超过阈值时告警

3. 存储监控

  • 监控磁盘使用率:确保有足够的存储空间
  • 监控磁盘IO:使用iostat等工具
  • 监控磁盘健康:使用smartctl等工具
  • 设置存储告警:当磁盘使用率超过阈值时告警

4. 定期测试

  • 数据一致性测试:定期验证主备数据一致性
  • 灾备切换测试:定期进行灾备切换演练
  • 恢复测试:定期测试从灾备恢复业务
  • 文档更新:根据测试结果更新灾备文档

异地灾备最佳实践

1. 网络优化

  • 使用专线:减少网络延迟和丢包率
  • 启用压缩:减少网络带宽消耗
  • 配置QoS:确保复制流量优先
  • 使用SSL/TLS:加密传输数据

2. 复制配置优化

  • 合理设置wal_keep_size:确保备库有足够的WAL日志
  • 调整wal_sender_timeout:适应网络延迟
  • 使用复制槽:防止WAL日志被过早删除
  • 启用hot_standby_feedback:防止主库清理备库需要的旧数据

3. 监控与告警

  • 建立完善的监控体系:监控复制状态、网络状态、存储状态
  • 设置合理的告警阈值:复制延迟、网络延迟、存储使用率等
  • 建立告警升级机制:确保告警能够及时处理
  • 定期检查告警配置:确保告警规则有效

4. 灾备测试

  • 定期进行灾备测试:至少每年一次
  • 测试不同场景:主库故障、网络中断、存储故障等
  • 测试恢复流程:从灾备恢复业务的完整流程
  • 记录测试结果:分析测试中遇到的问题并改进

5. 文档管理

  • 编写详细的灾备文档:包括架构、配置、操作流程等
  • 定期更新文档:根据环境变化及时更新
  • 培训相关人员:确保所有人员熟悉灾备流程
  • 建立文档版本控制:便于追溯变更

常见问题与解决方案

1. 复制延迟过大

问题现象

  • 备库复制延迟持续增长
  • 主库WAL日志堆积
  • 网络带宽使用率过高

解决方案

  • 增加网络带宽
  • 优化主库WAL生成速率
  • 调整wal_compression参数
  • 考虑使用级联复制

2. 网络中断

问题现象

  • 备库无法连接到主库
  • 复制状态显示disconnected
  • 网络监控显示连接中断

解决方案

  • 检查网络连接
  • 检查防火墙设置
  • 检查DNS配置
  • 考虑使用多路径网络

3. 数据不一致

问题现象

  • 主备库数据不一致
  • 备库无法应用WAL日志
  • 复制报错

解决方案

  • 重新初始化备库
  • 使用pg_rewind工具
  • 检查主库和备库的PostgreSQL版本
  • 验证复制配置

4. 备库性能问题

问题现象

  • 备库CPU使用率过高
  • 备库IO使用率过高
  • 备库回放WAL日志缓慢

解决方案

  • 提高备库硬件配置
  • 调整备库参数,如max_worker_processes
  • 考虑使用并行复制
  • 优化主库写入模式

版本差异注意事项

PostgreSQL 9.6

  • 不支持pg_rewind工具
  • 不支持recovery.signal文件
  • 半同步复制功能有限
  • 复制监控视图字段较少

PostgreSQL 10-11

  • 支持pg_rewind工具
  • 开始支持recovery.signal文件
  • 半同步复制功能增强
  • 支持逻辑复制

PostgreSQL 12+

  • 支持并行复制
  • 增强了WAL管理功能
  • 支持write_lag、flush_lag、replay_lag字段
  • 复制性能进一步提升

PostgreSQL 14+

  • 增强了逻辑复制功能
  • 支持更详细的复制状态监控
  • 改进了备库性能
  • 支持更灵活的复制配置

总结

异地灾备是确保PostgreSQL数据库高可用性和业务连续性的重要手段。选择合适的异地灾备架构需要考虑业务需求、数据中心距离、网络条件和成本等因素。异步复制适合对性能要求较高的场景,同步复制适合对数据一致性要求极高的场景,半同步复制则平衡了性能和可靠性。

在实际生产环境中,建议:

  1. 根据业务需求选择合适的异地灾备架构
  2. 优化网络配置,减少复制延迟
  3. 建立完善的监控和告警机制
  4. 定期进行灾备测试,确保灾备有效
  5. 编写详细的灾备文档,培训相关人员
  6. 考虑使用自动化工具管理灾备集群

通过合理的异地灾备设计和管理,可以确保PostgreSQL数据库在面对区域性灾难时能够快速恢复,减少业务中断时间,保护数据安全。