外观
PostgreSQL 异地备份策略
异地备份架构设计
异地备份类型
- 异步异地备份:备份数据异步传输到异地,对生产环境影响小
- 同步异地备份:备份数据实时同步到异地,数据安全性高
- 混合异地备份:结合异步和同步备份,平衡性能和安全性
异地备份位置选择
| 位置类型 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 同城异地 | 距离近,传输速度快 | 可能受同一地区灾难影响 | 实时灾备,快速恢复 |
| 跨城异地 | 不受同一地区灾难影响 | 传输延迟较大 | 重要数据灾备 |
| 跨国异地 | 最高级别的灾难防护 | 传输成本高,延迟大 | 核心业务数据灾备 |
异地备份配置
使用 rsync 实现异地备份
bash
# 创建本地备份目录
mkdir -p /backup/postgresql/$(date +%Y%m%d)
# 执行全量备份
pg_basebackup -h localhost -U replication_user -D /backup/postgresql/$(date +%Y%m%d) -F p -X stream -R -P
# 同步到异地服务器
rsync -avz --delete /backup/postgresql/$(date +%Y%m%d) remote_user@remote_server:/backup/postgresql/
# 同步 WAL 文件
rsync -avz --delete /var/lib/postgresql/15/main/pg_wal/ remote_user@remote_server:/backup/postgresql/wal/使用 Barman 配置异地备份
bash
# Barman 配置文件(barman.conf)
[main]
barman_home = /var/lib/barman
barman_user = barman
log_file = /var/log/barman/barman.log
compression = gzip
retention_policy = RECOVERY WINDOW OF 14 DAYS
# 异地备份配置
[offsite]
host = offsite_server
user = barman
dbname = postgres
port = 5432
backup_method = postgres
backup_options = exclusive_backup
streaming_archiver = on
slot_name = barman_offsite
archiver = on
archive_command = 'rsync -a %p barman@offsite_server:/var/lib/barman/offsite/incoming/%f'
# 执行异地备份
barman backup offsite使用云存储实现异地备份
AWS S3 配置
bash
# 安装 AWS CLI
pip install awscli
# 配置 AWS 凭证
aws configure
# 创建 S3 存储桶
aws s3 mb s3://postgresql-backups
# 备份到 S3
pg_basebackup -h localhost -U replication_user -F t -X stream -P > /tmp/full_backup.tar
aws s3 cp /tmp/full_backup.tar s3://postgresql-backups/full/$(date +%Y%m%d)/
# 备份 WAL 文件到 S3
find /var/lib/postgresql/15/main/pg_wal -name "000000010000*" -mmin +5 -exec aws s3 cp {} s3://postgresql-backups/wal/ \;阿里云 OSS 配置
bash
# 安装 ossutil
wget https://gosspublic.alicdn.com/ossutil/1.7.14/ossutil64
chmod +x ossutil64
./ossutil64 config
# 创建 OSS 存储桶
./ossutil64 mb oss://postgresql-backups
# 备份到 OSS
pg_basebackup -h localhost -U replication_user -F t -X stream -P > /tmp/full_backup.tar
./ossutil64 cp /tmp/full_backup.tar oss://postgresql-backups/full/$(date +%Y%m%d)/异地备份自动化
使用 cron 定时执行备份
bash
# 创建备份脚本 /usr/local/bin/offsite_backup.sh
#!/bin/bash
# 全量备份
mkdir -p /backup/postgresql/full/$(date +%Y%m%d)
pg_basebackup -h localhost -U replication_user -D /backup/postgresql/full/$(date +%Y%m%d) -F p -X stream -R -P
# 同步到异地服务器
rsync -avz --delete /backup/postgresql/full/$(date +%Y%m%d) remote_user@remote_server:/backup/postgresql/full/
# 同步 WAL 文件
rsync -avz --delete /var/lib/postgresql/15/main/pg_wal/ remote_user@remote_server:/backup/postgresql/wal/
# 清理本地过期备份
find /backup/postgresql/full -name "*" -mtime +7 -delete
# 添加执行权限
chmod +x /usr/local/bin/offsite_backup.sh
# 配置 cron 任务
0 2 * * 0 /usr/local/bin/offsite_backup.sh >> /var/log/postgresql/offsite_backup.log 2>&1使用 Ansible 管理异地备份
yaml
# ansible-playbook offsite_backup.yml
---
- hosts: postgresql_servers
become: yes
tasks:
- name: Create backup directory
file:
path: /backup/postgresql/{{ ansible_date_time.date }}
state: directory
owner: postgres
group: postgres
mode: '0700'
- name: Perform full backup
command: pg_basebackup -h localhost -U replication_user -D /backup/postgresql/{{ ansible_date_time.date }} -F p -X stream -R -P
become_user: postgres
- name: Sync to offsite server
synchronize:
src: /backup/postgresql/{{ ansible_date_time.date }}
dest: remote_user@remote_server:/backup/postgresql/
delete: yes
compress: yes
delegate_to: localhost异地备份恢复
从异地备份恢复
bash
# 从异地服务器复制备份到本地
rsync -avz remote_user@remote_server:/backup/postgresql/full/20240124 /backup/postgresql/
# 从云存储下载备份
aws s3 cp s3://postgresql-backups/full/20240124/full_backup.tar /backup/postgresql/
# 停止 PostgreSQL
systemctl stop postgresql-15
# 清理数据目录
rm -rf /var/lib/postgresql/15/main/*
# 恢复备份
tar -xf /backup/postgresql/full_backup.tar -C /var/lib/postgresql/15/main/
# 配置恢复参数(recovery.conf)
echo "restore_command = 'cp /backup/postgresql/wal/%f %p'" > /var/lib/postgresql/15/main/recovery.conf
echo "recovery_target_time = '2024-01-24 12:00:00'" >> /var/lib/postgresql/15/main/recovery.conf
# 启动 PostgreSQL
systemctl start postgresql-15异地灾备切换
bash
# 在异地从库上执行
# 检查复制状态
psql -c "SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS replay_delay FROM pg_stat_wal_receiver;"
# 停止复制
psql -c "SELECT pg_wal_receiver_status();"
# 提升为独立实例
pg_ctl promote -D /var/lib/postgresql/15/main/
# 更新应用连接配置
# 修改应用的数据库连接字符串,指向异地实例异地备份监控与管理
备份状态监控
bash
# 检查异地备份完整性
ssh remote_user@remote_server "pg_verifybackup /backup/postgresql/full/$(date +%Y%m%d)"
# 检查备份大小
ssh remote_user@remote_server "du -sh /backup/postgresql/full/$(date +%Y%m%d)"
# 监控备份进度
barman show-backup offsite latest备份保留策略
bash
# 清理异地过期备份
ssh remote_user@remote_server "find /backup/postgresql/full -name "*" -mtime +14 -delete"
# 清理异地过期 WAL 文件
ssh remote_user@remote_server "find /backup/postgresql/wal -name "000000010000*" -mtime +21 -delete"
# 云存储生命周期管理(AWS S3)
aws s3api put-bucket-lifecycle-configuration --bucket postgresql-backups --lifecycle-configuration '{"Rules": [{"ID": "ExpireOldBackups", "Status": "Enabled", "Prefix": "full/", "Expiration": {"Days": 14}}, {"ID": "ExpireOldWAL", "Status": "Enabled", "Prefix": "wal/", "Expiration": {"Days": 21}}]}'最佳实践
异地备份性能优化
- 使用压缩:减少备份传输时间和存储空间
- 增量备份:减少传输数据量
- 带宽优化:使用专用网络或 CDN 加速
- 备份分片:将大备份分成多个小文件,便于传输
异地备份安全性
- 加密传输:使用 SSH、SSL 或 TLS 加密传输通道
- 加密存储:对备份数据进行加密存储
- 访问控制:限制异地备份服务器的访问权限
- 备份验证:定期验证异地备份的完整性
灾难恢复测试
- 定期测试恢复:每年至少进行一次完整的灾难恢复测试
- 记录恢复时间:了解异地恢复所需时间
- 文档化恢复流程:确保团队成员都了解恢复步骤
- 模拟灾难场景:测试不同灾难场景下的恢复能力
常见问题(FAQ)
Q:异地备份对生产环境性能有影响吗?
A:异地备份对生产环境的影响取决于备份类型和配置:
- 异步备份对生产环境影响较小
- 同步备份可能会影响生产环境性能
- 使用压缩和增量备份可以减少影响
- 在低峰期执行备份可以进一步减少影响
Q:如何选择合适的异地备份策略?
A:选择异地备份策略的考虑因素:
- 数据重要性和恢复时间要求
- 预算和成本限制
- 网络带宽和延迟
- 合规性要求
- 灾难恢复目标(RTO 和 RPO)
Q:如何确保异地备份的可靠性?
A:确保异地备份可靠性的方法:
- 定期验证备份完整性
- 监控备份状态和进度
- 配置备份失败告警
- 测试恢复流程
- 多地点备份,避免单点故障
Q:云备份和自建异地备份哪个更好?
A:选择云备份或自建异地备份的考虑因素:
- 云备份:易于部署和管理,成本可预测,扩展性好
- 自建异地备份:更高的控制权,可能更适合敏感数据
- 混合方案:结合云备份和自建备份,提供更高的安全性
Q:异地备份的数据如何合规?
A:确保异地备份合规的方法:
- 了解数据保护法规要求
- 选择符合合规要求的备份位置
- 加密敏感数据
- 实施访问控制和审计
- 保留必要的备份日志
Q:如何减少异地备份的成本?
A:减少异地备份成本的方法:
- 使用增量备份和压缩
- 优化备份保留策略
- 选择合适的云存储层级
- 利用免费或低成本的网络资源
- 定期清理过期备份
