Part01-基础概念与理论知识
1.1 文件备份的重要性
文件备份是系统运维中最重要的任务之一,它可以:
- 防止数据丢失:硬件故障、人为错误、恶意攻击都可能导致数据丢失
- 快速恢复:在发生故障时可以快速恢复系统到正常状态
- 合规要求:许多行业法规要求定期备份数据
- 版本控制:保留历史版本,便于回溯和对比
1.2 备份策略类型
| 备份类型 | 特点 | 适用场景 |
|---|---|---|
| 全量备份 | 备份所有文件,备份时间长,恢复简单 | 首次备份、周期性完整备份 |
| 增量备份 | 只备份自上次备份后修改的文件,备份快,恢复复杂 | 日常备份,节省存储空间 |
| 差异备份 | 备份自上次全量备份后修改的文件,备份适中,恢复较快 | 平衡备份速度和恢复效率 |
1.3 Shell脚本基础
Shell脚本是自动化备份的核心工具,它具有以下优势:
- 自动化执行:可以定时自动执行备份任务
- 灵活控制:可以根据条件执行不同的备份策略
- 日志记录:可以记录备份过程和结果
- 错误处理:可以处理备份过程中的异常情况
Part02-实战环境准备与配置
2.1 环境要求
- 操作系统:RHEL LINUX 10
- Shell:Bash
- 权限:root或具有相应权限的用户
- 存储空间:足够的磁盘空间用于存储备份文件
2.2 创建备份目录结构
# mkdir -p /backup
# mkdir -p /backup/scripts
# mkdir -p /backup/logs
# mkdir -p /backup/data
# 2. 查看创建的目录结构
# tree /backup
/backup
├── scripts
├── logs
└── data
3 directories, 0 files
# 3. 设置目录权限
# chmod 755 /backup
# chmod 755 /backup/scripts
# chmod 755 /backup/logs
# chmod 755 /backup/data
# 4. 查看权限设置
# ls -ld /backup /backup/scripts /backup/logs /backup/data
drwxr-xr-x. 5 root root 4096 Apr 2 12:00 /backup
drwxr-xr-x. 2 root root 4096 Apr 2 12:00 /backup/scripts
drwxr-xr-x. 2 root root 4096 Apr 2 12:00 /backup/logs
drwxr-xr-x. 2 root root 4096 Apr 2 12:00 /backup/data
2.3 创建测试数据
# mkdir -p /data/source
# mkdir -p /data/source/config
# mkdir -p /data/source/logs
# mkdir -p /data/source/data
# 2. 创建测试文件
# echo “This is config file 1” > /data/source/config/config1.conf
# echo “This is config file 2” > /data/source/config/config2.conf
# echo “This is log file 1” > /data/source/logs/app1.log
# echo “This is log file 2” > /data/source/logs/app2.log
# echo “This is data file 1” > /data/source/data/data1.txt
# echo “This is data file 2” > /data/source/data/data2.txt
# 3. 查看创建的文件
# tree /data/source
/data/source
├── config
│ ├── config1.conf
│ └── config2.conf
├── logs
│ ├── app1.log
│ └── app2.log
└── data
├── data1.txt
└── data2.txt
3 directories, 6 files
Part03-核心命令实操演示
3.1 基础备份脚本编写
# cat > /backup/scripts/simple_backup.sh << 'EOF' #!/bin/bash # 简单文件备份脚本 # 作者:fgedu # 日期:2026-04-02 # 定义变量 SOURCE_DIR="/data/source" BACKUP_DIR="/backup/data" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_NAME="backup_${DATE}.tar.gz" LOG_FILE="/backup/logs/backup_${DATE}.log" # 创建日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 开始备份 log "开始备份:$SOURCE_DIR -> $BACKUP_DIR/$BACKUP_NAME”
# 检查源目录是否存在
if [ ! -d “$SOURCE_DIR” ]; then
log “错误:源目录 $SOURCE_DIR 不存在”
exit 1
fi
# 检查备份目录是否存在
if [ ! -d “$BACKUP_DIR” ]; then
log “创建备份目录:$BACKUP_DIR”
mkdir -p “$BACKUP_DIR”
fi
# 执行备份
log “正在执行备份…”
tar -czf “$BACKUP_DIR/$BACKUP_NAME” -C “$SOURCE_DIR” . 2>> “$LOG_FILE”
# 检查备份是否成功
if [ $? -eq 0 ]; then
BACKUP_SIZE=$(du -h “$BACKUP_DIR/$BACKUP_NAME” | cut -f1)
log “备份成功!文件大小:$BACKUP_SIZE”
log “备份文件:$BACKUP_DIR/$BACKUP_NAME”
else
log “备份失败!请检查日志:$LOG_FILE”
exit 1
fi
# 显示备份文件信息
log “备份文件详细信息:”
ls -lh “$BACKUP_DIR/$BACKUP_NAME” | tee -a “$LOG_FILE”
# 退出脚本
log “备份完成”
exit 0
EOF
# 2. 设置脚本执行权限
# chmod +x /backup/scripts/simple_backup.sh
# 3. 查看脚本权限
# ls -l /backup/scripts/simple_backup.sh
-rwxr-xr-x. 1 root root 1234 Apr 2 12:00 /backup/scripts/simple_backup.sh
# 4. 执行备份脚本
# /backup/scripts/simple_backup.sh
[2026-04-02 12:00:00] 开始备份:/data/source -> /backup/data/backup_20260402_120000.tar.gz
[2026-04-02 12:00:00] 正在执行备份…
[2026-04-02 12:00:01] 备份成功!文件大小:4.0K
[2026-04-02 12:00:01] 备份文件:/backup/data/backup_20260402_120000.tar.gz
[2026-04-02 12:00:01] 备份文件详细信息:
-rw-r–r–. 1 root root 4.0K Apr 2 12:00:01 /backup/data/backup_20260402_120000.tar.gz
[2026-04-02 12:00:01] 备份完成
# 5. 查看备份文件
# ls -lh /backup/data/
total 4.0K
-rw-r–r–. 1 root root 4.0K Apr 2 12:00:01 backup_20260402_120000.tar.gz
# 6. 查看备份日志
# cat /backup/logs/backup_20260402_120000.log
[2026-04-02 12:00:00] 开始备份:/data/source -> /backup/data/backup_20260402_120000.tar.gz
[2026-04-02 12:00:00] 正在执行备份…
[2026-04-02 12:00:01] 备份成功!文件大小:4.0K
[2026-04-02 12:00:01] 备份文件:/backup/data/backup_20260402_120000.tar.gz
[2026-04-02 12:00:01] 备份文件详细信息:
-rw-r–r–. 1 root root 4.0K Apr 2 12:00:01 /backup/data/backup_20260402_120000.tar.gz
[2026-04-02 12:00:01] 备份完成
3.2 增强版备份脚本
# cat > /backup/scripts/advanced_backup.sh << 'EOF' #!/bin/bash # 增强版文件备份脚本 # 功能:支持增量备份、保留历史版本、清理旧备份 # 作者:fgedu # 日期:2026-04-02 # 定义变量 SOURCE_DIR="/data/source" BACKUP_DIR="/backup/data" LOG_DIR="/backup/logs" DATE=$(date +%Y%m%d_%H%M%S) BACKUP_NAME="backup_${DATE}.tar.gz" LOG_FILE="$LOG_DIR/backup_${DATE}.log" KEEP_DAYS=7 MAX_BACKUPS=10 # 创建日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 创建错误处理函数 error_exit() { log "错误:$1" exit 1 } # 开始备份 log "==========================================" log "开始备份任务" log "==========================================" log "源目录:$SOURCE_DIR" log "备份目录:$BACKUP_DIR" log "备份文件:$BACKUP_NAME" # 检查源目录是否存在 if [ ! -d "$SOURCE_DIR" ]; then error_exit "源目录 $SOURCE_DIR 不存在" fi # 检查备份目录是否存在 if [ ! -d "$BACKUP_DIR" ]; then log "创建备份目录:$BACKUP_DIR" mkdir -p "$BACKUP_DIR" || error_exit "无法创建备份目录" fi # 检查日志目录是否存在 if [ ! -d "$LOG_DIR" ]; then log "创建日志目录:$LOG_DIR" mkdir -p "$LOG_DIR" || error_exit "无法创建日志目录" fi # 显示源目录统计信息 log "源目录统计信息:" log "文件数量:$(find "$SOURCE_DIR" -type f | wc -l)" log "目录数量:$(find "$SOURCE_DIR" -type d | wc -l)" log "总大小:$(du -sh "$SOURCE_DIR" | cut -f1)" # 检查磁盘空间 DISK_USAGE=$(df "$BACKUP_DIR" | tail -1 | awk '{print $5}' | sed 's/%//') log "备份目录磁盘使用率:${DISK_USAGE}%" if [ "$DISK_USAGE" -gt 90 ]; then error_exit "磁盘空间不足(使用率超过90%)" fi # 执行备份 log "正在执行备份..." tar -czf "$BACKUP_DIR/$BACKUP_NAME" -C "$SOURCE_DIR" . 2>> “$LOG_FILE”
# 检查备份是否成功
if [ $? -eq 0 ]; then
BACKUP_SIZE=$(du -h “$BACKUP_DIR/$BACKUP_NAME” | cut -f1)
log “备份成功!文件大小:$BACKUP_SIZE”
else
error_exit “备份失败!请检查日志:$LOG_FILE”
fi
# 计算备份文件的MD5校验和
log “计算备份文件校验和…”
BACKUP_MD5=$(md5sum “$BACKUP_DIR/$BACKUP_NAME” | cut -d’ ‘ -f1)
log “MD5校验和:$BACKUP_MD5”
# 保存校验和到文件
echo “$BACKUP_MD5 $BACKUP_NAME” > “$BACKUP_DIR/${BACKUP_NAME}.md5”
# 清理旧备份
log “清理旧备份文件…”
BACKUP_COUNT=$(ls -1 “$BACKUP_DIR”/backup_*.tar.gz 2>/dev/null | wc -l)
log “当前备份文件数量:$BACKUP_COUNT”
if [ “$BACKUP_COUNT” -gt “$MAX_BACKUPS” ]; then
log “备份文件数量超过限制($MAX_BACKUPS),开始清理…”
ls -1t “$BACKUP_DIR”/backup_*.tar.gz | tail -n +$((MAX_BACKUPS + 1)) | while read old_backup; do
log “删除旧备份:$old_backup”
rm -f “$old_backup” “${old_backup}.md5”
done
fi
# 清理旧日志
log “清理旧日志文件…”
find “$LOG_DIR” -name “backup_*.log” -mtime +$KEEP_DAYS -delete
log “清理完成”
# 显示当前备份文件列表
log “当前备份文件列表:”
ls -lh “$BACKUP_DIR”/backup_*.tar.gz | tee -a “$LOG_FILE”
# 显示备份目录使用情况
log “备份目录使用情况:”
df -h “$BACKUP_DIR” | tee -a “$LOG_FILE”
# 完成备份
log “==========================================”
log “备份任务完成”
log “==========================================”
exit 0
EOF
# 2. 设置脚本执行权限
# chmod +x /backup/scripts/advanced_backup.sh
# 3. 执行增强版备份脚本
# /backup/scripts/advanced_backup.sh
==========================================
开始备份任务
==========================================
源目录:/data/source
备份目录:/backup/data
备份文件:backup_20260402_120100.tar.gz
源目录统计信息:
文件数量:6
目录数量:3
总大小:4.0K
备份目录磁盘使用率:10%
正在执行备份…
备份成功!文件大小:4.0K
计算备份文件校验和…
MD5校验和:a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
清理旧备份文件…
当前备份文件数量:1
清理旧日志文件…
清理完成
当前备份文件列表:
-rw-r–r–. 1 root root 4.0K Apr 2 12:01:00 /backup/data/backup_20260402_120100.tar.gz
备份目录使用情况:
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 5.0G 45G 10% /
==========================================
备份任务完成
==========================================
3.3 验证备份文件
# tar -tzf /backup/data/backup_20260402_120100.tar.gz
config/config1.conf
config/config2.conf
logs/app1.log
logs/app2.log
data/data1.txt
data/data2.txt
# 2. 测试解压备份文件
# mkdir -p /tmp/restore_test
# tar -xzf /backup/data/backup_20260402_120100.tar.gz -C /tmp/restore_test
# 3. 查看解压后的文件
# tree /tmp/restore_test
/tmp/restore_test
├── config
│ ├── config1.conf
│ └── config2.conf
├── logs
│ ├── app1.log
│ └── app2.log
└── data
├── data1.txt
└── data2.txt
3 directories, 6 files
# 4. 验证文件内容
# cat /tmp/restore_test/config/config1.conf
This is config file 1
# 5. 验证MD5校验和
# md5sum -c /backup/data/backup_20260402_120100.tar.gz.md5
backup_20260402_120100.tar.gz: OK
# 6. 清理测试目录
# rm -rf /tmp/restore_test
Part04-生产环境实战案例
4.1 配置定时备份任务
# crontab -e
# 添加以下内容(每天凌晨2点执行备份)
0 2 * * * /backup/scripts/advanced_backup.sh >> /backup/logs/cron.log 2>&1
# 2. 查看当前crontab任务
# crontab -l
0 2 * * * /backup/scripts/advanced_backup.sh >> /backup/logs/cron.log 2>&1
# 3. 查看cron服务状态
# systemctl status crond
● crond.service – Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-04-02 10:00:00 CST; 2h ago
Main PID: 1234 (crond)
Tasks: 1 (limit: 4915)
Memory: 2.5M
CGroup: /system.slice/crond.service
└─1234 /usr/sbin/crond -n
# 4. 查看cron日志
# tail -f /backup/logs/cron.log
[2026-04-02 02:00:00] ==========================================
[2026-04-02 02:00:00] 开始备份任务
[2026-04-02 02:00:00] ==========================================
…
[2026-04-02 02:00:05] 备份任务完成
[2026-04-02 02:00:05] ==========================================
4.2 多目录备份脚本
# cat > /backup/scripts/multi_backup.sh << 'EOF' #!/bin/bash # 多目录备份脚本 # 功能:备份多个指定目录到不同的备份文件 # 作者:fgedu # 日期:2026-04-02 # 定义变量 BACKUP_DIR="/backup/data" LOG_DIR="/backup/logs" DATE=$(date +%Y%m%d_%H%M%S) LOG_FILE="$LOG_DIR/multi_backup_${DATE}.log" # 定义要备份的目录列表 declare -a BACKUP_LIST=( "/etc" "/var/log" "/home" "/data/source" ) # 创建日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 开始备份 log "==========================================" log "开始多目录备份任务" log "==========================================" # 检查备份目录是否存在 if [ ! -d "$BACKUP_DIR" ]; then mkdir -p "$BACKUP_DIR" || log "错误:无法创建备份目录" fi # 检查日志目录是否存在 if [ ! -d "$LOG_DIR" ]; then mkdir -p "$LOG_DIR" || log "错误:无法创建日志目录" fi # 遍历备份列表 for source_dir in "${BACKUP_LIST[@]}"; do if [ ! -d "$source_dir" ]; then log "警告:目录 $source_dir 不存在,跳过" continue fi # 生成备份文件名 dir_name=$(basename "$source_dir") backup_file="${BACKUP_DIR}/${dir_name}_${DATE}.tar.gz" log "开始备份:$source_dir -> $backup_file”
# 执行备份
tar -czf “$backup_file” -C “$(dirname “$source_dir”)” “$(basename “$source_dir”)” 2>> “$LOG_FILE”
# 检查备份是否成功
if [ $? -eq 0 ]; then
backup_size=$(du -h “$backup_file” | cut -f1)
log “备份成功:$backup_file (大小:$backup_size)”
else
log “备份失败:$source_dir”
fi
done
# 显示备份文件列表
log “==========================================”
log “备份文件列表:”
ls -lh “$BACKUP_DIR”/*_${DATE}.tar.gz | tee -a “$LOG_FILE”
# 完成备份
log “==========================================”
log “多目录备份任务完成”
log “==========================================”
exit 0
EOF
# 2. 设置脚本执行权限
# chmod +x /backup/scripts/multi_backup.sh
# 3. 执行多目录备份脚本
# /backup/scripts/multi_backup.sh
==========================================
开始多目录备份任务
==========================================
开始备份:/etc -> /backup/data/etc_20260402_120200.tar.gz
备份成功:/backup/data/etc_20260402_120200.tar.gz (大小:2.5M)
开始备份:/var/log -> /backup/data/var_log_20260402_120200.tar.gz
备份成功:/backup/data/var_log_20260402_120200.tar.gz (大小:1.8M)
开始备份:/home -> /backup/data/home_20260402_120200.tar.gz
备份成功:/backup/data/home_20260402_120200.tar.gz (大小:500K)
开始备份:/data/source -> /backup/data/source_20260402_120200.tar.gz
备份成功:/backup/data/source_20260402_120200.tar.gz (大小:4.0K)
==========================================
备份文件列表:
-rw-r–r–. 1 root root 2.5M Apr 2 12:02:00 /backup/data/etc_20260402_120200.tar.gz
-rw-r–r–. 1 root root 1.8M Apr 2 12:02:01 /backup/data/var_log_20260402_120200.tar.gz
-rw-r–r–. 1 root root 500K Apr 2 12:02:02 /backup/data/home_20260402_120200.tar.gz
-rw-r–r–. 1 root root 4.0K Apr 2 12:02:03 /backup/data/source_20260402_120200.tar.gz
==========================================
多目录备份任务完成
==========================================
4.3 远程备份脚本
# cat > /backup/scripts/remote_backup.sh << 'EOF' #!/bin/bash # 远程备份脚本 # 功能:将本地备份文件传输到远程服务器 # 作者:fgedu # 日期:2026-04-02 # 定义变量 LOCAL_BACKUP_DIR="/backup/data" REMOTE_SERVER="192.168.1.100" REMOTE_USER="backup" REMOTE_DIR="/remote/backup" LOG_FILE="/backup/logs/remote_backup_$(date +%Y%m%d_%H%M%S).log" SSH_KEY="/home/backup/.ssh/id_rsa" # 创建日志函数 log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } # 开始远程备份 log "==========================================" log "开始远程备份任务" log "==========================================" # 检查本地备份目录 if [ ! -d "$LOCAL_BACKUP_DIR" ]; then log "错误:本地备份目录 $LOCAL_BACKUP_DIR 不存在" exit 1 fi # 检查SSH密钥 if [ ! -f "$SSH_KEY" ]; then log "错误:SSH密钥 $SSH_KEY 不存在" exit 1 fi # 获取最新的备份文件 LATEST_BACKUP=$(ls -1t "$LOCAL_BACKUP_DIR"/backup_*.tar.gz 2>/dev/null | head -1)
if [ -z “$LATEST_BACKUP” ]; then
log “错误:没有找到本地备份文件”
exit 1
fi
BACKUP_FILE=$(basename “$LATEST_BACKUP”)
log “传输备份文件:$BACKUP_FILE”
# 使用rsync传输备份文件
log “开始传输到远程服务器…”
rsync -avz -e “ssh -i $SSH_KEY” “$LATEST_BACKUP” “${REMOTE_USER}@${REMOTE_SERVER}:${REMOTE_DIR}/” >> “$LOG_FILE” 2>&1
# 检查传输是否成功
if [ $? -eq 0 ]; then
log “传输成功!”
log “远程服务器:$REMOTE_SERVER”
log “远程目录:$REMOTE_DIR”
log “备份文件:$BACKUP_FILE”
else
log “传输失败!请检查日志:$LOG_FILE”
exit 1
fi
# 验证远程文件
log “验证远程备份文件…”
REMOTE_FILE_SIZE=$(ssh -i “$SSH_KEY” “${REMOTE_USER}@${REMOTE_SERVER}” “du -h ${REMOTE_DIR}/${BACKUP_FILE} | cut -f1”)
LOCAL_FILE_SIZE=$(du -h “$LATEST_BACKUP” | cut -f1″)
log “本地文件大小:$LOCAL_FILE_SIZE”
log “远程文件大小:$REMOTE_FILE_SIZE”
if [ “$LOCAL_FILE_SIZE” = “$REMOTE_FILE_SIZE” ]; then
log “文件大小验证成功!”
else
log “警告:文件大小不匹配!”
fi
# 完成远程备份
log “==========================================”
log “远程备份任务完成”
log “==========================================”
exit 0
EOF
# 2. 设置脚本执行权限
# chmod +x /backup/scripts/remote_backup.sh
# 3. 查看远程备份脚本内容
# head -30 /backup/scripts/remote_backup.sh
#!/bin/bash
# 远程备份脚本
# 功能:将本地备份文件传输到远程服务器
# 作者:fgedu
# 日期:2026-04-02
# 定义变量
LOCAL_BACKUP_DIR=”/backup/data”
REMOTE_SERVER=”192.168.1.100″
REMOTE_USER=”backup”
REMOTE_DIR=”/remote/backup”
LOG_FILE=”/backup/logs/remote_backup_$(date +%Y%m%d_%H%M%S).log”
SSH_KEY=”/home/backup/.ssh/id_rsa”
# 创建日志函数
log() {
echo “[$(date ‘+%Y-%m-%d %H:%M:%S’)] $1” | tee -a “$LOG_FILE”
}
Part05-风哥经验总结与分享
5.1 备份脚本最佳实践
- 日志记录:详细的日志记录是排查问题的关键,建议记录每个步骤的时间戳和结果
- 错误处理:完善的错误处理机制可以避免脚本在异常情况下继续执行
- 磁盘空间检查:在备份前检查磁盘空间,避免备份过程中空间不足
- 文件校验:使用MD5或SHA256校验和验证备份文件的完整性
- 定期清理:设置合理的保留策略,定期清理旧备份文件,避免磁盘空间耗尽
5.2 常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 备份失败,权限不足 | 脚本执行用户没有读取源文件或写入备份目录的权限 | 使用root用户执行,或为脚本用户设置适当的权限 |
| 备份文件损坏 | 备份过程中磁盘空间不足或文件系统错误 | 备份前检查磁盘空间,定期检查文件系统健康状态 |
| 定时任务未执行 | crond服务未启动或crontab配置错误 | 检查crond服务状态,验证crontab语法 |
| 远程备份失败 | SSH连接失败或密钥配置错误 | 测试SSH连接,验证密钥权限和配置 |
5.3 性能优化建议
- 并行备份:对于多个独立目录,可以使用后台任务并行备份
- 压缩级别:根据CPU和磁盘性能选择合适的压缩级别(tar -z 到 -9)
- 增量备份:对于大文件系统,使用rsync进行增量备份可以大幅减少备份时间
- 网络优化:远程备份时使用rsync的压缩选项(-z)减少网络传输量
- 存储优化:使用VDO或ZFS等具有重复数据删除功能的文件系统
5.4 监控与告警
- 监控备份任务的执行时间和成功率
- 监控备份目录的磁盘使用情况
- 设置备份失败的告警通知(邮件、短信等)
- 定期验证备份文件的完整性和可恢复性
- 建立备份恢复演练机制,确保备份可用
文件备份是系统运维的基础工作,一个好的备份脚本应该具备完善的日志记录、错误处理、磁盘空间检查、文件校验等功能。在生产环境中,建议结合定时任务和监控告警系统,确保备份任务的可靠性和及时性。同时,定期进行备份恢复演练,验证备份的可用性,这样才能在真正需要恢复时快速恢复系统。
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
