数据库与文件备份策略
High Contrast
Dark Mode
Light Mode
Sepia
Forest
3 min read647 words

数据库与文件备份策略

如果你没有备份,你就没有生产环境,只是在赌运气。

备份对象与方式

对象 备份方式 工具 频率建议
关系型数据库 逻辑导出(可跨版本恢复) pg_dump / mysqldump 每日
数据库(大型) 物理快照(快但需相同版本) pg_basebackup / 云快照 每日
用户上传文件 增量同步到对象存储 rclone / rsync 每小时
配置文件 Git 或加密文件备份 git / gpg 每次变更

备份流程图

graph LR A[数据库 pg_dump/mysqldump] --> B[本地 /backup/] B --> C[压缩 + 加密] C --> D[上传对象存储 S3/GCS/OSS] E[上传目录 /data/uploads] --> F[rclone 增量同步] F --> D G[配置文件 /etc/myapp] --> H[Git 仓库/加密备份]

PostgreSQL 备份与恢复

# === 备份 ===
# 压缩格式(推荐,支持并行恢复)
pg_dump -U postgres -Fc mydb -f /backup/mydb-$(date +%F).dump
# SQL 文本格式(可阅读,便于部分恢复)
pg_dump -U postgres mydb | gzip > /backup/mydb-$(date +%F).sql.gz
# === 恢复 ===
# 从压缩格式恢复(-j 4 并行,加速大库)
pg_restore -U postgres -d mydb -j 4 /backup/mydb-2026-03-22.dump
# 从 SQL 文本格式恢复
gunzip < /backup/mydb-2026-03-22.sql.gz | psql -U postgres mydb
# 验证备份完整性(不执行恢复,只列出内容)
pg_restore --list /backup/mydb-2026-03-22.dump | head -20

MySQL / MariaDB 备份与恢复

# === 备份 ===
# --single-transaction 保证 InnoDB 一致性快照(不锁表)
mysqldump -u root -p --single-transaction --routines --triggers mydb \
| gzip > /backup/mydb-$(date +%F).sql.gz
# 所有库(生产常用)
mysqldump -u root -p --all-databases --single-transaction \
| gzip > /backup/all-dbs-$(date +%F).sql.gz
# === 恢复 ===
gunzip < /backup/mydb-2026-03-22.sql.gz | mysql -u root -p mydb

完整生产备份脚本

#!/usr/bin/env bash
# backup.sh — PostgreSQL + 文件备份,加密上传至对象存储
set -euo pipefail
BACKUP_DIR=/backup
DATE=$(date +%F)
DB_NAME=mydb
DB_USER=postgres
REMOTE=s3:my-prod-backups
ENCRYPT_KEY=/etc/backup/backup.key   # openssl 加密密钥文件
LOG=/var/log/backup.log
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG"; }
# 1. 数据库备份
log "开始数据库备份"
pg_dump -U "$DB_USER" -Fc "$DB_NAME" -f "$BACKUP_DIR/db-$DATE.dump"
# 2. 加密(可选,对合规要求高的场景)
openssl enc -aes-256-cbc -salt -pbkdf2 \
-in "$BACKUP_DIR/db-$DATE.dump" \
-out "$BACKUP_DIR/db-$DATE.dump.enc" \
-pass file:"$ENCRYPT_KEY"
rm "$BACKUP_DIR/db-$DATE.dump"   # 删除明文
# 3. 上传文件备份
log "同步上传目录"
rclone copy /data/uploads "$REMOTE/uploads-$DATE/" --progress
# 4. 上传加密 dump
log "上传数据库备份"
rclone copy "$BACKUP_DIR/db-$DATE.dump.enc" "$REMOTE/db/"
# 5. 清理本地备份(保留最近 7 天)
find "$BACKUP_DIR" -name "*.dump.enc" -mtime +7 -delete
log "备份完成: db-$DATE.dump.enc"

备份保留策略(3-2-1 原则)

保留周期 份数 说明
每日备份 保留 7 份 覆盖过去 7 天,用于快速恢复
每周备份 保留 4 份 每周日保留,覆盖过去 4 周
每月备份 保留 12 份 每月 1 日保留,覆盖过去 1 年

3 份副本,2 种介质,1 份异地:本地磁盘 + 对象存储 + 跨区域复制。

自动清理旧备份的 cron 示例:

# 每日 2:00 执行备份,每日 3:00 清理超过 7 天的本地备份
0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
0 3 * * * find /backup -name "*.dump.enc" -mtime +7 -delete

逻辑备份 vs 物理备份

对比 逻辑备份(pg_dump) 物理备份(pg_basebackup/快照)
跨版本恢复 ✅ 可以 ❌ 需相同主版本
恢复速度 慢(重放 SQL) 快(文件复制)
文件大小 较小(可压缩) 较大
适合大库 小于 10GB 推荐 大库(>10GB)推荐
部分恢复 ✅ 可以(指定表) ❌ 全库恢复

常见误区

误区 正确做法
备份只留在同一台机器上 必须异地(对象存储 / 跨机房)
只备份数据库,不备份上传文件 用户上传的图片、附件同样是生产数据
有备份但从没做过恢复测试 每季度至少做一次恢复演练(见下一节)
mysqldump 不加 --single-transaction 不加会锁表,生产环境不可接受
备份文件明文存储 涉及用户隐私/支付的数据,备份文件必须加密

本节执行清单

下一节恢复演练与灾备意识——备份的价值只有在恢复时才真正体现。