這是一個實用的 MySQL 備份自動化腳本,採用「每 7 天全量備份 + 每日增量備份」的混合策略。全量備份使用 mysqldump 導出所有資料庫,增量備份則透過 mysqlbinlog 解析二進制日誌,只備份變更部分,大幅節省儲存空間與備份時間。
#!/bin/bash
# MySQL 混合備份腳本
BACKUP_DIR="/mydata/data1/backup"
if [ ! -d "$BACKUP_DIR" ]; then
mkdir -p "$BACKUP_DIR"
fi
cd "$BACKUP_DIR"
腳本會檢查過去 7 天內是否已存在全量備份檔案(檔名含 all.sql)。若不存在,則執行全量備份;若存在,則改為增量備份。
# 查找 7 天內的全量備份檔
file=$(find . -type f -mtime -7 -name "*all.sql")
if [ -z "$file" ]; then
echo "開始全量備份所有資料庫..."
backupfile=$(date +%F-%H-%M-%S)
mysqldump -uroot --lock-all-tables --flush-logs --master-data=2 --all-databases \
> "$BACKUP_DIR/${backupfile}-all.sql"
if [ $? -eq 0 ]; then
echo "全量備份完成,檔案:${backupfile}-all.sql"
else
echo "全量備份失敗!"
fi
else
# 執行增量備份邏輯...
fi
增量備份的關鍵在於找到「倒數第二個」二進制日誌檔(最新的正在寫入,不可備份)。腳本透過解析檔名後綴編號,找出最大值 a 與次大值 b,b 即為目標檔案。
cd ..
echo "全量備份已存在,開始增量備份..."
# 找出最大編號 a
a=1
for file in $(ls | grep mysql-bin | grep -v index); do
num=$(echo $file | cut -d. -f2)
[ $num -gt $a ] && a=$num
done
# 找出次大編號 b(即倒數第二個)
b=1
for file in $(ls | grep mysql-bin | grep -v index); do
num=$(echo $file | cut -d. -f2)
if [ $num -gt $b -a $num -ne $a ]; then
b=$num
tmp=$file
fi
done
# 使用 mysqlbinlog 導出 SQL
file1=$(echo $tmp | cut -d. -f1)
file2=$(echo $tmp | cut -d. -f2)
mysqlbinlog $tmp > "$BACKUP_DIR/${file1}-${file2}.sql"
if [ $? -eq 0 ]; then
echo "增量備份完成,檔案:${file1}-${file2}.sql"
fi
mysql_backup.sh 並賦予執行權限:chmod +x mysql_backup.shcrontab -e 設定每日凌晨執行:0 2 * * * /path/to/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1log-bin 並設定合適的 expire_logs_days權限需求:執行腳本的使用者需具備 RELOAD、LOCK TABLES、REPLICATION CLIENT、SUPER 權限。
鎖表影響:--lock-all-tables 會造成全域鎖定,大型資料庫建議改用 --single-transaction(僅限 InnoDB)。
Binlog 格式:建議使用 ROW 或 MIXED 格式,確保增量備份資料一致性。