Centos 定时冷备磁盘
脚本设计
功能:
- 第一次运行脚本时进行全量同步。
- 后续每次运行只同步新增或修改的文件(增量同步)。
- 增加挂载和卸载 B 磁盘的逻辑。
脚本内容: 编辑 /usr/local/bin/backup_diskA_to_diskB.sh
:
#!/bin/bash
# 配置变量
SRC="/mnt/diskA/" # A 磁盘路径
DEST_MOUNT="/mnt/diskB" # B 磁盘挂载点
DEVICE_UUID="123e4567-e89b-12d3-a456-426614174000" # 替换为实际UUID
LOG_FILE="/var/log/backup.log"
# 检查并挂载 B 磁盘
if ! mount | grep -q "$DEST_MOUNT"; then
mount -U "$DEVICE_UUID" "$DEST_MOUNT"
if [ $? -ne 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Failed to mount UUID=$DEVICE_UUID" >> "$LOG_FILE"
exit 1
fi
fi
# 确保目标目录存在
mkdir -p "$DEST_MOUNT"
# 开始同步(增量同步)
rsync -av --delete "$SRC" "$DEST_MOUNT"
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') Incremental backup completed successfully" >> "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Incremental backup failed" >> "$LOG_FILE"
umount "$DEST_MOUNT"
exit 1
fi
# 卸载目标磁盘
umount "$DEST_MOUNT"
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') Disk UUID=$DEVICE_UUID unmounted successfully" >> "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Failed to unmount UUID=$DEVICE_UUID" >> "$LOG_FILE"
exit 1
fi
配置与使用
1. 设置脚本执行权限
sudo chmod +x /usr/local/bin/backup_diskA_to_diskB.sh
2. 定时任务配置
使用 cron
设置每天 17:00 自动执行脚本:
crontab -e
添加以下内容:
0 17 * * * /usr/local/src/backups/disk/backup_disk.sh
工作原理
- 首次运行:
- 如果目标目录为空,
rsync
会全量复制 A 磁盘的所有数据到 B 磁盘。 - 将数据完整同步到
/mnt/diskB
。
- 如果目标目录为空,
- 后续运行:
rsync
会检查源和目标的文件状态(文件大小、修改时间等)。- 只同步新增或被修改的文件。
- 删除目标目录中已被源目录删除的文件(通过
--delete
参数)。
测试与验证
-
手动运行脚本:
sudo /usr/local/bin/backup_diskA_to_diskB.sh
验证挂载、增量同步和卸载是否正常。
-
检查同步结果:
- 在
/mnt/diskB
查看是否成功同步了/mnt/diskA
的数据。 - 检查
/var/log/backup.log
是否记录了备份的状态。
- 在
-
修改
/mnt/diskA
中的文件,再次运行脚本,确认增量同步只同步了变化部分。
优化建议
-
日志更详细:在
rsync
中添加--log-file
参数,将每次同步的详细信息记录到独立日志文件:rsync -av --delete --log-file=/var/log/rsync.log "$SRC" "$DEST_MOUNT"
-
排除不必要文件:如果有不需要同步的文件或目录,可以使用
--exclude
参数。例如:rsync -av --delete --exclude "temp/" --exclude "*.log" "$SRC" "$DEST_MOUNT"
-
并发保护:避免多个脚本实例同时运行,可添加锁文件:
LOCK_FILE="/tmp/backup.lock" if [ -f "$LOCK_FILE" ]; then echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Script already running" >> "$LOG_FILE" exit 1 fi touch "$LOCK_FILE" trap "rm -f $LOCK_FILE" EXIT
这样可以高效实现全量+增量备份,同时确保数据安全!
完整脚本
#!/bin/bash
# 配置变量
SRC="/mnt/diskA/" # A 磁盘路径
DEST_MOUNT="/mnt/diskB" # B 磁盘挂载点
DEVICE_UUID="123e4567-e89b-12d3-a456-426614174000" # 替换为实际UUID
LOG_FILE="/var/log/backup.log" # 总体日志文件
RSYNC_LOG="/var/log/rsync.log" # rsync 同步详细日志
LOCK_FILE="/tmp/backup.lock" # 锁文件
# 排除文件和目录
EXCLUDES=("--exclude=temp/" "--exclude=*.log") # 配置排除的规则
# 检查并发运行
if [ -f "$LOCK_FILE" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Script already running" >> "$LOG_FILE"
exit 1
fi
# 创建锁文件
touch "$LOCK_FILE"
# 在脚本结束时清理锁文件
trap "rm -f $LOCK_FILE" EXIT
# 检查并挂载 B 磁盘
if ! mount | grep -q "$DEST_MOUNT"; then
mount -U "$DEVICE_UUID" "$DEST_MOUNT"
if [ $? -ne 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Failed to mount UUID=$DEVICE_UUID" >> "$LOG_FILE"
exit 1
fi
fi
# 确保目标目录存在
mkdir -p "$DEST_MOUNT"
# 开始同步(增量同步)
rsync -av --delete "${EXCLUDES[@]}" --log-file="$RSYNC_LOG" "$SRC" "$DEST_MOUNT"
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') Incremental backup completed successfully" >> "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Incremental backup failed" >> "$LOG_FILE"
umount "$DEST_MOUNT"
exit 1
fi
# 卸载目标磁盘
umount "$DEST_MOUNT"
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') Disk UUID=$DEVICE_UUID unmounted successfully" >> "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Failed to unmount UUID=$DEVICE_UUID" >> "$LOG_FILE"
exit 1
fi
附带邮件通知
安装mailx
sudo yum install mailx -y
配置邮件发送
-
配置
/etc/mail.rc
或使用您公司邮箱的 SMTP 设置。 -
示例(以 163为例):在
/etc/mail.rc
中添加以下内容:在最后添加 ##改成自己的163邮箱 set from=12345678901@163.com set smtp=smtp.163.com ##改成自己的163邮箱 set smtp-auth-user=12345678901@163.com set smtp-auth-password=授权密码 set smtp-auth=login
测试:
第一种 mail -s "主题" username 邮件内容 ctrl+d 第二种 echo "hello" |mail -s "邮件主题" usename 第三种 发送附件 echo "hello" |mail -s "邮件主题" -a /file usename
改进脚本
#!/bin/bash
# 配置变量
SRC="/mnt/diskA/" # A 磁盘路径
DEST_MOUNT="/mnt/diskB" # B 磁盘挂载点
DEVICE_UUID="123e4567-e89b-12d3-a456-426614174000" # 替换为实际UUID
LOG_FILE="/var/log/backup.log" # 总体日志文件
RSYNC_LOG="/var/log/rsync.log" # rsync 同步详细日志
LOCK_FILE="/tmp/backup.lock" # 锁文件
EMAIL="your_email@example.com" # 接收通知的邮箱
# 排除文件和目录
EXCLUDES=("--exclude=temp/" "--exclude=*.log") # 配置排除的规则
# 并发检查
if [ -f "$LOCK_FILE" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Script already running" >> "$LOG_FILE"
echo "Backup script is already running. Exiting..." | mail -s "Backup Failed" "$EMAIL"
exit 1
fi
touch "$LOCK_FILE"
trap "rm -f $LOCK_FILE" EXIT
# 发送备份开始通知
echo "Backup started at $(date)" | mail -s "Backup Started" "$EMAIL"
# 挂载磁盘
if ! mount | grep -q "$DEST_MOUNT"; then
mount -U "$DEVICE_UUID" "$DEST_MOUNT"
if [ $? -ne 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Failed to mount UUID=$DEVICE_UUID" >> "$LOG_FILE"
echo "Failed to mount disk UUID=$DEVICE_UUID at $(date)" | mail -s "Backup Failed" "$EMAIL"
exit 1
fi
fi
# 确保目标目录存在
mkdir -p "$DEST_MOUNT"
# 同步数据
rsync -av --delete "${EXCLUDES[@]}" --log-file="$RSYNC_LOG" "$SRC" "$DEST_MOUNT"
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') Incremental backup completed successfully" >> "$LOG_FILE"
echo "Backup completed successfully at $(date)" | mail -s "Backup Success" "$EMAIL"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Incremental backup failed" >> "$LOG_FILE"
echo "Backup failed during rsync operation at $(date)" | mail -s "Backup Failed" "$EMAIL"
umount "$DEST_MOUNT"
exit 1
fi
# 卸载磁盘
umount "$DEST_MOUNT"
if [ $? -eq 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') Disk UUID=$DEVICE_UUID unmounted successfully" >> "$LOG_FILE"
else
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: Failed to unmount UUID=$DEVICE_UUID" >> "$LOG_FILE"
echo "Failed to unmount disk UUID=$DEVICE_UUID at $(date)" | mail -s "Backup Failed" "$EMAIL"
exit 1
fi
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 奇怪的阿峰
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果