Linux 下用 Trigger 实现备份与恢复的可落地方案
一、概念澄清与总体思路
二、事件触发备份 inotify + rsync 快照
#!/usr/bin/env bash
set -Eeuo pipefail
SRC="/data/www"
BASE="/backup/rsync_snap"
DATE=$(date +%F_%H%M%S)
LAST="$BASE/last"
CUR="$BASE/$DATE"
mkdir -p "$CUR"
RSYNC_OPTS=(-a --delete --link-dest="$LAST" --log-file="$BASE/rsync.log")
# 首次全量
if [[ ! -d "$LAST" ]]; then
rsync "${RSYNC_OPTS[@]}" "$SRC/" "$CUR/"
else
# 事件触发增量(配合 inotifywait 使用)
rsync "${RSYNC_OPTS[@]}" "$SRC/" "$CUR/"
fi
# 原子切换快照
ln -snf "$CUR" "$LAST"
# 清理 7 天前快照
find "$BASE" -maxdepth 1 -type d -mtime +7 -name '20*' -exec rm -rf {} +
inotifywait -m -r -e create,modify,delete,move \
--format '%e %w%f' /data/www | while IFS=' ' read -r evt file; do
/usr/local/bin/backup_inotify.sh
done
三、时间触发备份 cron + 组合策略
#!/usr/bin/env bash
set -Eeuo pipefail
SRC="/data"
DEST="/backup"
DATE=$(date +%F)
LOG="$DEST/backup_$DATE.log"
mkdir -p "$DEST"
# 每周日全量,其余日增量(基于上次全量)
if [[ $(date +%u) -eq 7 ]]; then
# 全量 tar.gz
tar czf "$DEST/full_$DATE.tar.gz" -C "$SRC" . >>"$LOG" 2>&1
# 更新全量标记
ln -snf "$DEST/full_$DATE.tar.gz" "$DEST/full_latest.tar.gz"
else
# 增量 tar.gz(基于上次全量快照)
tar czf "$DEST/incr_$DATE.tar.gz" -g "$DEST/snapshot.snar" -C "$SRC" . >>"$LOG" 2>&1
fi
# 保留策略:全量保留 4 周,增量保留 7 天
find "$DEST" -maxdepth 1 -name 'full_*.tar.gz' -mtime +28 -delete
find "$DEST" -maxdepth 1 -name 'incr_*.tar.gz' -mtime +7 -delete
echo "[$(date)] Backup finished, see $LOG"
# 每天 02:00 执行
0 2 * * * /usr/local/bin/backup_cron.sh
# 每天 04:00 同步到远程
0 4 * * * rsync -avz --delete /backup/ user@backup.example.com:/backup/
四、数据库备份与恢复要点
#!/usr/bin/env bash
set -Eeuo pipefail
DB_HOST="localhost"
DB_USER="backup"
DB_PASS="******"
DB_NAME="appdb"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%F_%H%M)
mkdir -p "$BACKUP_DIR"
mysqldump -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" --single-transaction --routines --triggers "$DB_NAME" \
> "$BACKUP_DIR/${DB_NAME}_${DATE}.sql"
# 保留 30 天
find "$BACKUP_DIR" -name '*.sql' -mtime +30 -delete
# 可选:同步到远程
rsync -avz "$BACKUP_DIR/" user@backup.example.com:/backup/mysql/
mysql -h"$DB_HOST" -u"$DB_USER" -p"$DB_PASS" "$DB_NAME" < /backup/mysql/appdb_2025-12-31_0200.sql
五、恢复流程与应急要点
rsync -a --delete /backup/rsync_snap/2025-12-30_0200/ /data/www/
tar xzf /backup/full_2025-12-28.tar.gz -C /
tar xzf /backup/incr_2025-12-29.tar.gz -C /
tar xzf /backup/incr_2025-12-30.tar.gz -C /
mysqlbinlog --start-datetime="2025-12-30 10:00:00" \
--stop-datetime="2025-12-30 10:15:00" \
/var/lib/mysql/mysql-bin.000001 | mysql -u root -p
sudo mount -o remount,ro /dev/sdX1
sudo dd if=/dev/sdX1 of=/backup/sdX1.img bs=4M