数据库备份策略
备份类型
全量备份
备份整个数据库的所有数据,是恢复的基础。
优点:恢复简单,一份文件搞定 缺点:耗时长,占用空间大,频率低
增量备份
备份自上次备份以来发生变化的数据。
优点:速度快,占用空间小 缺点:恢复时需要依赖全量备份和所有增量链
差异备份
备份自上次全量备份以来发生变化的数据。
优点:恢复比增量快(只需要全量+最新差异) 缺点:随着时间推移越来越大
备份策略金字塔
存储层: 归档备份(月度)→ 冷存储
↓
保留层: 全量备份(周度)→ 对象存储
↓
恢复层: 差异备份(日度)→ 本地/远程
↓
实时层: 增量备份/WAL 归档 → 快速恢复
↓
流式复制(实时保护)
PostgreSQL 备份
pg_dump 逻辑备份
# 单库备份
pg_dump -h localhost -U postgres -d mydb -F c -f mydb.dump
# 压缩备份
pg_dump -h localhost -U postgres -d mydb -Z 9 -f mydb.sql.gz
# 目录格式(支持并行)
pg_dump -h localhost -U postgres -d mydb -F d -j 4 -f mydb_dir/
# 仅备份数据(不备份 schema)
pg_dump -h localhost -U postgres -d mydb --data-only -f data.sql
pg_dumpall 整集群备份
# 备份所有数据库和全局对象
pg_dumpall -h localhost -U postgres -f full_cluster.sql
物理备份与 WAL 归档
# postgresql.conf 配置
wal_level = replica
archive_mode = on
archive_command = 'cp %p /backup/wal/%f'
# 基础备份
pg_basebackup -h localhost -U replicator -D /backup/base -X stream -P
恢复
# 逻辑恢复
pg_restore -h localhost -U postgres -d mydb -j 4 mydb.dump
# PITR 时间点恢复
# 1. 恢复基础备份
# 2. 创建 recovery.conf
restore_command = 'cp /backup/wal/%f %p'
recovery_target_time = '2024-01-15 14:30:00'
MySQL 备份
mysqldump
# 单库备份
mysqldump -h localhost -u root -p --single-transaction --routines --triggers mydb > mydb.sql
# 压缩备份
mysqldump -h localhost -u root -p --all-databases | gzip > all_dbs.sql.gz
# 只备份结构
mysqldump --no-data mydb > schema.sql
XtraBackup 物理备份
# 全量备份
xtrabackup --backup --target-dir=/backup/full
# 增量备份
xtrabackup --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/full
# 准备恢复
xtrabackup --prepare --target-dir=/backup/full
MongoDB 备份
# mongodump
mongodump --host localhost --db mydb --out /backup/mongodb/
# 带认证
mongodump --uri="mongodb://user:pass@localhost:27017/mydb" --out /backup/
# mongorestore
mongorestore --drop /backup/mongodb/
备份自动化脚本
PostgreSQL 备份脚本
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/backup/postgresql"
DB_NAME="mydb"
RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
LOG_FILE="/var/log/backup.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
}
# 全量备份(每周日)
if [[ $(date +%u) -eq 7 ]]; then
log "开始全量备份..."
pg_dump -h localhost -U postgres -d "$DB_NAME" -F c \
-f "${BACKUP_DIR}/full/${DB_NAME}_${DATE}.dump"
log "全量备份完成"
fi
# 差异备份(其他日子)
log "开始差异备份..."
pg_dump -h localhost -U postgres -d "$DB_NAME" \
-f "${BACKUP_DIR}/diff/${DB_NAME}_${DATE}.sql"
# 清理过期备份
find "${BACKUP_DIR}/full" -type f -mtime +$RETENTION_DAYS -delete
find "${BACKUP_DIR}/diff" -type f -mtime +7 -delete
log "备份完成"
WAL 归档清理
#!/bin/bash
# archive_cleanup.sh - 保留最近 7 天的 WAL
find /backup/wal -type f -mtime +7 -delete
备份验证
备份无效比没有备份更糟——它带来虚假的安全感。
验证策略
# 1. 检查文件完整性
pg_restore -l mydb.dump > /dev/null && echo "备份文件完整"
# 2. 恢复到测试环境
pg_restore -h test-host -U postgres -d test_db mydb.dump
# 3. 数据一致性检查
psql -h test-host -U postgres -d test_db -c "SELECT count(*) from critical_tables;"
# 4. 对比行数
psql -h prod-host -U postgres -d mydb -c \
"SELECT schemaname, tablename, n_live_tup FROM pg_stat_user_tables ORDER BY n_live_tup DESC;"
备份检查清单
- 是否启用了自动化定时备份?
- 是否配置了远程备份(异地容灾)?
- 备份文件是否加密?
- 是否定期测试恢复流程?
- 是否监控备份成功率?
- 是否有备份告警机制?
- WAL 归档是否正常工作?
- 备份保留策略是否合理?
- 是否有专人负责备份恢复演练?
总结
可靠的备份策略需要满足三个目标:RPO(恢复点目标)、RTO(恢复时间目标)和备份验证。推荐采用"全量+WAL 归档"的组合策略,自动化备份流程,定期演练恢复,确保在灾难发生时能够快速恢复业务。