Linux 系统备份策略与恢复

一、引言

数据是企业的核心资产,完善的备份策略是运维工作的重中之重。本文介绍 Linux 系统备份的完整方案,包括备份策略设计、工具选择、自动化实施和灾难恢复流程。

二、备份策略设计原则

2.1 3-2-1 备份原则

  • 3 份数据副本(1 份生产 + 2 份备份)
  • 2 种不同存储介质(如硬盘 + 云存储)
  • 1 份异地备份(防止区域性灾难)

2.2 RTO 与 RPO 定义

指标 定义 示例目标
RTO (Recovery Time Objective) 恢复时间目标 ≤ 4 小时
RPO (Recovery Point Objective) 恢复点目标 ≤ 1 小时

2.3 备份类型选择

类型 优点 缺点 适用场景
完全备份 恢复简单快速 占用空间大、耗时长 每周一次
增量备份 节省空间和时间 恢复需要多个备份集 每日备份
差异备份 恢复比增量快 空间占用逐渐增加 关键系统

三、常用备份工具

3.1 rsync - 文件级备份

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# 本地备份脚本
SOURCE_DIR="/data"
BACKUP_DIR="/backup/data_$(date +%Y%m%d_%H%M%S)"

rsync -avz --delete \
--exclude '*.tmp' \
--exclude '*.log' \
$SOURCE_DIR/ $BACKUP_DIR/

# 保留最近 7 天的备份
find /backup -type d -name "data_*" -mtime +7 -exec rm -rf {} \;
1
2
3
4
# 远程备份(推送到备份服务器)
rsync -avz -e "ssh -p 22" \
/data/ \
backup_user@backup-server:/backup/data/

3.2 tar - 归档压缩备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
# 创建压缩备份
BACKUP_FILE="/backup/system_$(date +%Y%m%d_%H%M%S).tar.gz"

tar -czf $BACKUP_FILE \
--exclude='/proc' \
--exclude='/sys' \
--exclude='/tmp' \
--exclude='/dev' \
--exclude='/backup' \
/etc /home /var/log /opt

# 验证备份完整性
tar -tzf $BACKUP_FILE > /dev/null && echo "备份验证成功"
1
2
3
4
5
6
# 增量备份(使用 --listed-incremental)
# 首次完全备份
tar -czf backup-1.tar.gz --listed-incremental=/var/tmp/snapshot.snar /data

# 后续增量备份
tar -czf backup-2.tar.gz --listed-incremental=/var/tmp/snapshot.snar /data

3.3 BorgBackup - 去重备份工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 初始化仓库
borg init --encryption=repokey /backup/borg-repo

# 创建备份
borg create \
--compression lz4 \
--exclude '*.tmp' \
/backup/borg-repo::'{now:%Y-%m-%d_%H:%M}' \
/data /etc /home

# 列出备份
borg list /backup/borg-repo

# 恢复备份
borg extract /backup/borg-repo::2026-03-04_14:00 /data

# 清理旧备份(保留最近 7 天、4 周、6 个月)
borg prune \
--keep-daily=7 \
--keep-weekly=4 \
--keep-monthly=6 \
/backup/borg-repo

3.4 dd - 磁盘镜像备份

1
2
3
4
5
6
7
8
# 整盘备份(适用于系统迁移)
dd if=/dev/sda of=/backup/disk_image.img bs=4M status=progress

# 压缩备份
dd if=/dev/sda bs=4M status=progress | gzip > /backup/disk_image.img.gz

# 恢复磁盘
dd if=/backup/disk_image.img of=/dev/sda bs=4M status=progress

四、数据库备份

4.1 MySQL/MariaDB 备份

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# MySQL 备份脚本
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
MYSQL_USER="backup_user"
MYSQL_PASS="your_password"

# 完全备份
mysqldump -u$MYSQL_USER -p$MYSQL_PASS \
--all-databases \
--single-transaction \
--routines \
--triggers \
--events | gzip > $BACKUP_DIR/all_databases_$DATE.sql.gz

# 保留 30 天备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete

4.2 PostgreSQL 备份

1
2
3
4
5
6
7
8
9
10
#!/bin/bash
# PostgreSQL 备份脚本
BACKUP_DIR="/backup/postgresql"
DATE=$(date +%Y%m%d_%H%M%S)

# 完全备份
pg_dumpall -U postgres | gzip > $BACKUP_DIR/full_backup_$DATE.sql.gz

# 单数据库备份
pg_dump -U postgres mydb | gzip > $BACKUP_DIR/mydb_$DATE.sql.gz

4.3 MongoDB 备份

1
2
3
4
5
6
7
8
9
#!/bin/bash
# MongoDB 备份
BACKUP_DIR="/backup/mongodb"
DATE=$(date +%Y%m%d_%H%M%S)

mongodump --out $BACKUP_DIR/mongo_$DATE

# 恢复
mongorestore $BACKUP_DIR/mongo_20260304_140000

五、自动化备份方案

5.1 Cron 定时任务

1
2
3
4
5
6
7
8
9
10
11
# 编辑 crontab
crontab -e

# 每日凌晨 2 点执行完全备份
0 2 * * * /usr/local/bin/backup_daily.sh >> /var/log/backup.log 2>&1

# 每小时执行增量备份
0 * * * * /usr/local/bin/backup_hourly.sh >> /var/log/backup.log 2>&1

# 每周日清理旧备份
0 3 * * 0 /usr/local/bin/backup_cleanup.sh >> /var/log/backup.log 2>&1

5.2 systemd Timer(推荐)

1
2
3
4
5
6
7
8
9
# /etc/systemd/system/backup.service
[Unit]
Description=Daily System Backup
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup_daily.sh
User=root
1
2
3
4
5
6
7
8
9
10
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 2:00 AM

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target
1
2
3
4
5
6
7
# 启用定时任务
systemctl daemon-reload
systemctl enable backup.timer
systemctl start backup.timer

# 查看状态
systemctl list-timers

5.3 备份监控与告警

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
# 备份状态检查脚本
BACKUP_DIR="/backup"
ALERT_EMAIL="admin@example.com"

# 检查最新备份时间
LATEST_BACKUP=$(ls -t $BACKUP_DIR/*.tar.gz 2>/dev/null | head -1)
if [ -z "$LATEST_BACKUP" ]; then
echo "警告:未找到备份文件" | mail -s "备份告警" $ALERT_EMAIL
exit 1
fi

# 检查备份是否超过 24 小时
BACKUP_TIME=$(stat -c %Y "$LATEST_BACKUP")
CURRENT_TIME=$(date +%s)
AGE_HOURS=$(( (CURRENT_TIME - BACKUP_TIME) / 3600 ))

if [ $AGE_HOURS -gt 24 ]; then
echo "警告:备份已超过 ${AGE_HOURS} 小时" | mail -s "备份告警" $ALERT_EMAIL
exit 1
fi

echo "备份检查正常"

六、灾难恢复流程

6.1 恢复前准备

1
2
3
4
5
6
7
8
# 1. 确认备份可用性
tar -tzf /backup/system_20260304_020000.tar.gz | head

# 2. 检查磁盘空间
df -h /restore

# 3. 准备恢复环境
mkdir -p /restore

6.2 系统恢复步骤

1
2
3
4
5
6
7
8
9
10
11
# 场景 1:文件恢复
tar -xzf /backup/system_20260304_020000.tar.gz -C /restore

# 场景 2:rsync 恢复
rsync -avz /backup/data_20260304_020000/ /data/

# 场景 3:Borg 恢复
borg extract /backup/borg-repo::2026-03-04_02:00 --target /restore

# 场景 4:数据库恢复
gunzip < /backup/mysql/all_databases_20260304_020000.sql.gz | mysql -u root -p

6.3 恢复验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
# 恢复验证脚本

# 1. 检查关键文件
for file in /etc/passwd /etc/fstab /etc/hosts; do
if [ ! -f "$file" ]; then
echo "错误:$file 不存在"
exit 1
fi
done

# 2. 检查服务状态
systemctl is-active --quiet nginx || echo "警告:nginx 未运行"
systemctl is-active --quiet mysql || echo "警告:mysql 未运行"

# 3. 数据完整性检查
mysqlcheck -u root -p --all-databases

echo "恢复验证完成"

七、备份最佳实践总结

7.1 必须执行

  • ✅ 定期测试恢复流程(至少每季度一次)
  • ✅ 备份加密存储(特别是敏感数据)
  • ✅ 异地备份(防止区域性灾难)
  • ✅ 备份日志记录与监控
  • ✅ 文档化恢复流程

7.2 避免事项

  • ❌ 备份与生产数据同盘存储
  • ❌ 无验证的备份(可能备份了损坏数据)
  • ❌ 过度依赖单一备份工具
  • ❌ 忽略备份权限管理
  • ❌ 忘记测试恢复流程

八、备份检查清单

检查项 频率 负责人
备份任务执行状态 每日 运维值班
备份空间使用率 每周 运维主管
恢复演练测试 每季度 全体运维
备份策略评审 每半年 技术负责人
异地备份验证 每月 运维主管

参考资源