备份策略
数据是服务器上最有价值的资产。硬件可以更换,软件可以重装,但丢失的数据往往无法恢复。本文介绍从基础到进阶的备份方案,帮助你构建可靠的数据保护体系。
在制定策略之前,先理解三种基本备份类型:
| 类型 | 说明 | 优点 | 缺点 |
|---|---|---|---|
| 完全备份 | 每次备份所有数据 | 恢复简单快速 | 耗时长、占用空间大 |
| 增量备份 | 仅备份自上次备份后变化的数据 | 速度快、节省空间 | 恢复时需要完整链路 |
| 差异备份 | 备份自上次完全备份后变化的数据 | 恢复较简单 | 随时间推移数据量增长 |
推荐的备份策略(祖父-父-子方案):
- 每日:增量备份
- 每周:完全备份
- 每月:完全备份离线归档
使用 rsync 备份
Section titled “使用 rsync 备份”rsync 是最常用的文件同步工具,支持增量传输,只复制变化的部分。
# 本地目录同步rsync -avh --progress /var/www/ /backup/www/
# 参数说明:# -a 归档模式(保留权限、时间戳、符号链接等)# -v 详细输出# -h 人类可读的文件大小# --progress 显示传输进度# 推送到远程服务器rsync -avhz --progress /var/www/ user@backup-server:/backup/www/
# 从远程服务器拉取rsync -avhz --progress user@backup-server:/data/ /local/backup/data/
# -z 启用压缩传输,适合网络带宽有限的场景带排除规则和删除的同步
Section titled “带排除规则和删除的同步”# 排除不需要备份的目录/文件rsync -avh \ --exclude='*.log' \ --exclude='cache/' \ --exclude='tmp/' \ --delete \ /var/www/ /backup/www/
# --delete 删除目标端多余的文件,保持完全一致# 注意:--delete 有风险,首次使用建议先加 --dry-run 预演rsync -avhn --delete /var/www/ /backup/www/ # -n 等同于 --dry-runrsync 增量备份脚本(带硬链接)
Section titled “rsync 增量备份脚本(带硬链接)”利用硬链接实现高效的增量备份,每次备份看起来都是完整的,但只占用变化文件的空间:
#!/bin/bash# 使用硬链接的增量备份
SOURCE="/var/www"BACKUP_BASE="/backup/www"DATE=$(date +%Y-%m-%d_%H%M%S)LATEST="${BACKUP_BASE}/latest"TARGET="${BACKUP_BASE}/${DATE}"
# 如果存在上次备份,使用硬链接if [ -d "$LATEST" ]; then LINK_DEST="--link-dest=${LATEST}"else LINK_DEST=""fi
# 执行备份rsync -avh --delete $LINK_DEST "${SOURCE}/" "${TARGET}/"
# 更新 latest 链接rm -f "$LATEST"ln -s "$TARGET" "$LATEST"
# 删除 30 天前的备份find "$BACKUP_BASE" -maxdepth 1 -type d -mtime +30 -exec rm -rf {} +
echo "[$(date)] 备份完成: ${TARGET}"使用 tar 打包备份
Section titled “使用 tar 打包备份”tar 适合对特定目录做完整打包归档。
# 创建压缩归档tar czf /backup/www-$(date +%Y%m%d).tar.gz -C / var/www
# 使用 xz 压缩(压缩率更高,但速度较慢)tar cJf /backup/www-$(date +%Y%m%d).tar.xz -C / var/www
# 备份时排除特定内容tar czf /backup/www-$(date +%Y%m%d).tar.gz \ --exclude='*.log' \ --exclude='cache' \ -C / var/wwwtar 支持基于快照文件的增量备份:
# 第一次运行 —— 完全备份(创建快照文件)tar czf /backup/www-full-$(date +%Y%m%d).tar.gz \ --listed-incremental=/backup/www.snar \ -C / var/www
# 后续运行 —— 增量备份(基于快照文件)tar czf /backup/www-incr-$(date +%Y%m%d_%H%M%S).tar.gz \ --listed-incremental=/backup/www.snar \ -C / var/www恢复增量备份时,需要按顺序先恢复完全备份,再依次恢复每个增量:
# 恢复完全备份tar xzf /backup/www-full-20260301.tar.gz -C /
# 按顺序恢复增量备份tar xzf /backup/www-incr-20260302_020000.tar.gz -C /tar xzf /backup/www-incr-20260303_020000.tar.gz -C /使用 BorgBackup
Section titled “使用 BorgBackup”BorgBackup(简称 Borg)是一款现代化的去重压缩备份工具,非常适合服务器备份场景。
sudo dnf install epel-release -ysudo dnf install borgbackup -y# 本地仓库borg init --encryption=repokey /backup/borg-repo
# 远程仓库(通过 SSH)borg init --encryption=repokey ssh://user@backup-server/backup/borg-repo
# 加密密钥会提示你输入密码,请务必妥善保管!# 创建备份存档borg create \ --verbose \ --stats \ --progress \ --compression zstd,3 \ /backup/borg-repo::'{hostname}-{now:%Y-%m-%d_%H%M%S}' \ /var/www \ /etc \ /home \ --exclude '/home/*/.cache' \ --exclude '*.tmp'# 列出所有存档borg list /backup/borg-repo
# 查看某个存档的内容borg list /backup/borg-repo::myserver-2026-03-20_020000
# 恢复到指定目录cd /tmp/restoreborg extract /backup/borg-repo::myserver-2026-03-20_020000
# 仅恢复特定路径borg extract /backup/borg-repo::myserver-2026-03-20_020000 var/www自动清理旧备份
Section titled “自动清理旧备份”# 保留策略:7 个每日、4 个每周、6 个每月borg prune \ --verbose \ --list \ --keep-daily=7 \ --keep-weekly=4 \ --keep-monthly=6 \ /backup/borg-repo
# 释放已删除存档的磁盘空间borg compact /backup/borg-repo完整的 Borg 自动化备份脚本
Section titled “完整的 Borg 自动化备份脚本”#!/bin/bash# BorgBackup 自动化备份脚本
set -euo pipefail
# 配置export BORG_REPO="/backup/borg-repo"export BORG_PASSPHRASE="your_secure_passphrase" # 生产环境建议使用密钥文件BACKUP_NAME="{hostname}-{now:%Y-%m-%d_%H%M%S}"LOG_FILE="/var/log/borg_backup.log"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"}
log "开始备份..."
# 创建备份borg create \ --verbose \ --stats \ --compression zstd,3 \ --exclude '/home/*/.cache' \ --exclude '/var/tmp/*' \ --exclude '/var/log/*.gz' \ "${BORG_REPO}::${BACKUP_NAME}" \ /etc \ /home \ /var/www \ /var/lib/mysql \ 2>&1 | tee -a "$LOG_FILE"
log "备份完成,开始清理旧存档..."
# 清理旧备份borg prune \ --verbose \ --list \ --keep-daily=7 \ --keep-weekly=4 \ --keep-monthly=6 \ "$BORG_REPO" \ 2>&1 | tee -a "$LOG_FILE"
borg compact "$BORG_REPO" 2>&1 | tee -a "$LOG_FILE"
log "所有操作完成。"
# 取消密码变量unset BORG_PASSPHRASEchmod 700 /usr/local/bin/borg_backup.sh使用 cron
Section titled “使用 cron”sudo crontab -e
# 每天凌晨 2 点执行 Borg 备份0 2 * * * /usr/local/bin/borg_backup.sh >> /var/log/borg_backup.log 2>&1
# 每天凌晨 3 点执行 rsync 备份0 3 * * * /usr/local/bin/rsync_backup.sh >> /var/log/rsync_backup.log 2>&1使用 systemd timer(推荐)
Section titled “使用 systemd timer(推荐)”systemd timer 比 cron 更灵活,支持日志集成和依赖管理。
# 创建 service 单元sudo tee /etc/systemd/system/borg-backup.service > /dev/null <<'EOF'[Unit]Description=BorgBackup 每日备份After=network-online.targetWants=network-online.target
[Service]Type=oneshotExecStart=/usr/local/bin/borg_backup.shNice=19IOSchedulingClass=idleEOF
# 创建 timer 单元sudo tee /etc/systemd/system/borg-backup.timer > /dev/null <<'EOF'[Unit]Description=每日凌晨 2 点运行 BorgBackup
[Timer]OnCalendar=*-*-* 02:00:00RandomizedDelaySec=600Persistent=true
[Install]WantedBy=timers.targetEOF
# 启用定时器sudo systemctl daemon-reloadsudo systemctl enable --now borg-backup.timer
# 查看定时器状态systemctl list-timers borg-backup.timer
# 手动触发一次测试sudo systemctl start borg-backup.servicejournalctl -u borg-backup.service -f本地备份无法防范机房级别的故障(火灾、断电、硬件批量损坏)。至少应有一份异地备份。
rsync 到远程服务器
Section titled “rsync 到远程服务器”#!/bin/bash# 将本地备份同步到远程服务器
REMOTE_USER="backup"REMOTE_HOST="offsite-backup.example.com"REMOTE_PATH="/backup/$(hostname)"LOCAL_BACKUP="/backup/borg-repo"
# 使用 SSH 密钥认证(避免密码交互)rsync -avhz --progress \ -e "ssh -i /root/.ssh/backup_key -o StrictHostKeyChecking=yes" \ "${LOCAL_BACKUP}/" \ "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_PATH}/"同步到对象存储(S3 兼容)
Section titled “同步到对象存储(S3 兼容)”# 安装 rclonesudo dnf install rclone -y
# 配置(交互式)rclone config# 按提示配置 S3 兼容存储(如 AWS S3、MinIO、阿里云 OSS 等)
# 同步备份到对象存储rclone sync /backup/borg-repo remote:my-backup-bucket/borg-repo \ --transfers=4 \ --progressBorg 恢复测试
Section titled “Borg 恢复测试”# 创建临时恢复目录mkdir -p /tmp/restore-testcd /tmp/restore-test
# 从最新存档恢复export BORG_REPO="/backup/borg-repo"export BORG_PASSPHRASE="your_secure_passphrase"
LATEST=$(borg list --last 1 --short "$BORG_REPO")echo "恢复存档: ${LATEST}"borg extract "${BORG_REPO}::${LATEST}"
# 验证文件完整性echo "文件数量: $(find . -type f | wc -l)"echo "总大小: $(du -sh .)"
# 对比关键文件diff /etc/nginx/nginx.conf /tmp/restore-test/etc/nginx/nginx.confdiff -r /var/www/html/ /tmp/restore-test/var/www/html/ | head -20
# 清理rm -rf /tmp/restore-testunset BORG_PASSPHRASE自动化恢复测试脚本
Section titled “自动化恢复测试脚本”#!/bin/bash# 自动化备份恢复测试
set -euo pipefail
RESTORE_DIR="/tmp/restore-test-$(date +%s)"BORG_REPO="/backup/borg-repo"export BORG_PASSPHRASE="your_secure_passphrase"MAILTO="admin@example.com"RESULT="成功"
mkdir -p "$RESTORE_DIR"cd "$RESTORE_DIR"
# 获取最新存档LATEST=$(borg list --last 1 --short "$BORG_REPO")
# 尝试恢复if borg extract "${BORG_REPO}::${LATEST}"; then FILE_COUNT=$(find . -type f | wc -l) TOTAL_SIZE=$(du -sh . | awk '{print $1}')
# 基本验证 if [ "$FILE_COUNT" -eq 0 ]; then RESULT="失败 - 恢复文件数为 0" fielse RESULT="失败 - borg extract 返回错误"fi
# 发送报告REPORT="备份恢复测试报告\n\n"REPORT+="日期: $(date)\n"REPORT+="存档: ${LATEST}\n"REPORT+="结果: ${RESULT}\n"REPORT+="文件数: ${FILE_COUNT:-N/A}\n"REPORT+="数据量: ${TOTAL_SIZE:-N/A}\n"
echo -e "$REPORT" | mail -s "[备份测试] 恢复测试${RESULT}" "$MAILTO"
# 清理rm -rf "$RESTORE_DIR"unset BORG_PASSPHRASE将恢复测试加入定时任务,建议每月执行一次:
# 每月 1 号凌晨 5 点运行恢复测试0 5 1 * * /usr/local/bin/test_restore.sh >> /var/log/restore_test.log 2>&1文件备份之外,数据库需要专门的备份策略。
MySQL/MariaDB
Section titled “MySQL/MariaDB”# 完整备份mysqldump --all-databases --single-transaction --quick \ --routines --triggers \ -u root -p | gzip > /backup/mysql-$(date +%Y%m%d).sql.gz
# 指定数据库mysqldump --single-transaction -u root -p mydb | gzip > /backup/mydb-$(date +%Y%m%d).sql.gz
# 恢复gunzip < /backup/mysql-20260320.sql.gz | mysql -u root -pPostgreSQL
Section titled “PostgreSQL”# 完整备份sudo -u postgres pg_dumpall | gzip > /backup/postgres-$(date +%Y%m%d).sql.gz
# 指定数据库sudo -u postgres pg_dump mydb | gzip > /backup/mydb-$(date +%Y%m%d).sql.gz
# 恢复gunzip < /backup/postgres-20260320.sql.gz | sudo -u postgres psql备份策略清单
Section titled “备份策略清单”制定备份方案时,确认以下每一项:
- 明确需要备份的数据范围(配置文件、网站数据、数据库、用户数据)
- 选择合适的备份工具和类型
- 设定备份频率(每日/每周/每月)
- 配置自动化调度
- 设置备份保留策略(保留多少份、保留多长时间)
- 至少有一份异地备份
- 备份数据加密(尤其是异地/云端备份)
- 每月至少进行一次恢复测试
- 监控备份任务是否按时成功执行
- 记录完整的恢复步骤文档