为什么要备份?
2019年,我硬盘挂了,五年来的照片、文档、代码,全没了。那种感觉,就像世界塌了一样。
从那之后,我发誓再也不让这种事发生。现在我有3份备份:本地NAS、云盘、异地服务器。即使哪天硬盘炸了,我也能淡定地换一个继续用。
备份策略:3-2-1原则
3份数据:原始数据+2份备份
2种介质:硬盘+云盘(SSD+HDD也行)
1个异地:至少一份备份在不同地方
简单说:你的电脑 → 本地NAS → 云盘
实战1:文件备份脚本
需求
- 每天凌晨3点备份
/home/user/documents
- 保留最近7天的备份
- 压缩节省空间
编写脚本
创建 /root/backup/backup.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #!/bin/bash
SOURCE_DIR="/home/user/documents" BACKUP_DIR="/backup/daily" DAYS_TO_KEEP=7 DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="backup_${DATE}.tar.gz"
mkdir -p "$BACKUP_DIR"
echo "$(date) 开始备份 $SOURCE_DIR..." tar -czf "${BACKUP_DIR}/${BACKUP_FILE}" \ --exclude='*.log' \ --exclude='*.tmp' \ --exclude='node_modules' \ "$SOURCE_DIR"
if [ $? -eq 0 ]; then echo "$(date) 备份成功: ${BACKUP_DIR}/${BACKUP_FILE}" else echo "$(date) 备份失败!" >&2 exit 1 fi
echo "$(date) 删除${DAYS_TO_KEEP}天前的备份..." find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +$DAYS_TO_KEEP -delete
BACKUP_SIZE=$(du -sh "${BACKUP_DIR}/${BACKUP_FILE}" | cut -f1) echo "$(date) 备份大小: $BACKUP_SIZE"
echo "$(date) 备份完成"
|
添加执行权限:
1
| chmod +x /root/backup/backup.sh
|
定时运行
1 2 3 4
| crontab -e
0 3 * * * /root/backup/backup.sh >> /var/log/backup.log 2>&1
|
手动测试
1 2 3 4 5
| /root/backup/backup.sh
ls -lh /backup/daily/
|
实战2:MySQL数据库备份
编写脚本
创建 /root/backup/backup_mysql.sh:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| #!/bin/bash
DB_USER="root" DB_PASS="YourPassword" DB_NAME="wordpressdb" BACKUP_DIR="/backup/mysql" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_FILE="mysql_${DATE}.sql.gz"
mkdir -p "$BACKUP_DIR"
if [ -n "$DB_NAME" ]; then echo "$(date) 备份数据库: $DB_NAME" mysqldump -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" \ | gzip > "${BACKUP_DIR}/${BACKUP_FILE}" else echo "$(date) 备份所有数据库" mysqldump -u"$DB_USER" -p"$DB_PASS" --all-databases \ | gzip > "${BACKUP_DIR}/${BACKUP_FILE}" fi
if [ $? -eq 0 ]; then echo "$(date) 备份成功: ${BACKUP_DIR}/${BACKUP_FILE}" else echo "$(date) 备份失败!" >&2 exit 1 fi
find "$BACKUP_DIR" -name "mysql_*.sql.gz" -mtime +7 -delete
echo "$(date) 备份完成"
|
权限:
1
| chmod +x /root/backup/backup_mysql.sh
|
定时:
1 2 3 4
| crontab -e
0 2 * * * /root/backup/backup_mysql.sh >> /var/log/backup_mysql.log 2>&1
|
实战3:上传到云盘(百度云/阿里云/腾讯云)
以阿里云OSS为例:
安装阿里云CLI
1 2 3 4 5 6
| apt install -y ossutil
ossutil config
|
修改备份脚本
在文件备份脚本的最后添加:
1 2 3 4 5 6 7 8 9 10 11 12 13
| OSS_BUCKET="your-bucket-name" OSS_PATH="backups/"
echo "$(date) 上传到阿里云OSS..." ossutil cp "${BACKUP_DIR}/${BACKUP_FILE}" \ "oss://${OSS_BUCKET}/${OSS_PATH}${BACKUP_FILE}" -f
if [ $? -eq 0 ]; then echo "$(date) 上传成功" else echo "$(date) 上传失败" >&2 fi
|
实战4:异地备份(SCP到另一台服务器)
配置SSH免密登录
1 2 3 4 5
| ssh-keygen -t rsa -b 4096
ssh-copy-id user@remote-server.com
|
修改脚本
在备份脚本添加:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| REMOTE_USER="user" REMOTE_HOST="remote-server.com" REMOTE_DIR="/backup/backup-local"
echo "$(date) 拷贝到异地服务器..." scp "${BACKUP_DIR}/${BACKUP_FILE}" \ "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/"
if [ $? -eq 0 ]; then echo "$(date) 异地备份成功" else echo "$(date) 异地备份失败" >&2 fi
|
实战5:Docker容器备份
备份所有容器
创建 /root/backup/backup_docker.sh:
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/docker" DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
echo "$(date) 备份Docker数据卷..." docker volume ls -q | while read volume; do echo "备份卷: $volume" docker run --rm -v "$volume":/data -v "$BACKUP_DIR":/backup \ alpine tar czf "/backup/volume_${volume}_${DATE}.tar.gz" /data done
find "$BACKUP_DIR" -name "*.tar.gz" -mtime +30 -delete
echo "$(date) Docker备份完成"
|
实战6:完整备份系统(全量镜像)
创建系统快照
谨慎使用,这是”核武器”级别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #!/bin/bash
DATE=$(date +%Y%m%d) BACKUP_FILE="/backup/system_${DATE}.img"
AVAILABLE=$(df -BG / | awk 'NR==2{print $4}' | tr -d 'G') if [ "$AVAILABLE" -lt 20 ]; then echo "磁盘空间不足(剩余${AVAILABLE}G),需要至少20G" >&2 exit 1 fi
echo "$(date) 开始备份整个系统(这可能需要很长时间)..." dd if=/dev/sda of="$BACKUP_FILE" bs=4M status=progress
gzip "$BACKUP_FILE"
echo "$(date) 系统备份完成: ${BACKUP_FILE}.gz"
|
警告:
- 需要至少20G空闲空间
- 不要在系统运行时做全量备份
- 建议在维护窗口(凌晨)执行
脚本调试技巧
调试模式
在脚本开头添加:
1
| #!/bin/bash -x # -x显示执行的每条命令
|
日志记录
1 2 3 4 5 6 7 8 9 10 11
| LOG_FILE="/var/log/backup.log"
exec > >(tee -a "$LOG_FILE") 2>&1
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE" }
log "开始备份..."
|
错误处理
1 2 3 4
| set -e
trap 'echo "备份失败!"' ERR
|
邮件通知
备份完成后发邮件:
1 2 3 4 5 6 7 8 9 10 11 12 13
| apt install -y mailutils
mail -s "备份完成" your@example.com << EOF 备份完成!
文件: ${BACKUP_FILE} 大小: $BACKUP_SIZE 时间: $(date)
详见日志: /var/log/backup.log EOF
|
配合cron:
1
| 0 3 * * * /root/backup/backup.sh && echo "备份成功" | mail -s "备份通知" you@example.com
|
恢复测试(重要!)
备份后不测试,等于没备份。
测试文件恢复
1 2 3 4 5
| tar -xzf /backup/daily/backup_20240213_030001.tar.gz -C /tmp/test
ls -la /tmp/test/home/user/documents
|
测试数据库恢复
1 2 3 4 5 6
| gunzip < /backup/mysql/mysql_20240213_030001.sql.gz | \ mysql -uroot -p wordpressdb
mysql -uroot -p wordpressdb -e "SHOW TABLES;"
|
定期演练(每月一次)
- 选一个周末
- 恢复备份到测试服务器
- 验证数据完整性
- 记录恢复时间
备份监控
检查备份是否成功
1 2 3 4 5 6 7 8 9 10 11
| #!/bin/bash
LATEST=$(find /backup/daily -name "backup_*.tar.gz" -mtime -1 | tail -1)
if [ -z "$LATEST" ]; then echo "$(date) 警告:最近24小时没有备份!" | \ mail -s "备份失败警告" your@example.com else echo "$(date) 备份正常:$LATEST" fi
|
检查备份文件大小
1 2 3 4 5 6 7 8
| LATEST_BACKUP=$(find /backup/daily -name "backup_*.tar.gz" -mtime -0 | tail -1) SIZE=$(stat -c%s "$LATEST_BACKUP")
if [ "$SIZE" -lt 1024 ]; then echo "$(date) 警告:备份文件过小($SIZE字节)" | \ mail -s "备份异常" your@example.com fi
|
常见问题
Q: 备份太慢怎么办?
A:
- 用
--exclude 排除不需要的文件
- 压缩级别调低(zip用
-1,tar已自动平衡)
- 增量备份(
rsync)
Q: 磁盘满了,备份失败?
A:
- 减少保留天数
- 删除旧文件:
find /backup -mtime +30 -delete
- 扩容磁盘
Q: crontab没执行?
A:
- 查看cron日志:
tail -f /var/log/cron
- 检查脚本权限:
ls -l /root/backup/*.sh
- 检查脚本路径:写绝对路径
Q: 如何增量备份?
A: 用rsync:
1
| rsync -av --delete /source/ /backup/
|
完整备份系统架构
1 2 3 4 5 6 7 8 9
| 本地 ├── /backup/daily/ # 文件备份 ├── /backup/mysql/ # 数据库备份 ├── /backup/docker/ # Docker备份 └── /backup/system/ # 系统镜像(可选)
异地(云端) ├── OSS对象存储 # 阿里云/腾讯云/百度云 └── 远程服务器 # SCP同步
|
总结
- 3-2-1原则:3份数据,2种介质,1个异地
- 文件备份:tar压缩,排除无用文件
- 数据库备份:mysqldump导出,gzip压缩
- 云盘备份:用OSS/CLI工具上传
- 异地备份:SCP拷贝到远程服务器
- Docker备份:卷和镜像都保留
- 定时执行:crontab设定时间,0 3 * * * 每天凌晨3点
- 日志记录:所有输出写日志,出问题好排查
- 邮件通知:备份完成/失败都发邮件
- 恢复测试:定期演练,别等到丢了才慌
- 监控告警:检查备份是否成功,文件大小是否正常
最后一句:备份这事儿,要么做,要么不做,不存在”差不多”。多做一份,多一份安心。
恭喜!15篇教程全部完成!
从SSH连接到自动备份,你现在应该能独立配置一台Linux服务器了。有问题随时回来翻翻,多写写,多练练,很快就能成为运维大神!加油!💪