架構:週日 03:00 全量備份,週一~六 03:00 增量備份。增量基於 Binlog,全量用 mysqldump。所有操作記錄至 bak.log。
DBFullyBak.sh#!/bin/bash
BakDir=/home/mysql/backup
LogFile=/home/mysql/backup/bak.log
Date=$(date +%Y%m%d)
Begin=$(date +"%Y年%m月%d日 %H:%M:%S")
cd $BakDir
DumpFile=$Date.sql
GZDumpFile=$Date.sql.tgz
# --single-transaction 保證一致性(InnoDB)
# --flush-logs 切換 binlog,便於增量基準
# --delete-master-logs 清理舊 binlog(謹慎使用)
/usr/local/mysql/bin/mysqldump -uroot -p123456 \
--quick --all-databases --flush-logs --delete-master-logs --single-transaction \
> $DumpFile
tar czvf $GZDumpFile $DumpFile
rm $DumpFile
Last=$(date +"%Y年%m月%d日 %H:%M:%S")
echo "開始:$Begin 結束:$Last $GZDumpFile succ" >> $LogFile
# 清理增量目錄,新週重新開始
cd $BakDir/daily
rm -f *
DBDailyBak.sh#!/bin/bash
BakDir=/home/mysql/backup/daily
BinDir=/home/mysql/data
LogFile=/home/mysql/backup/bak.log
BinFile=/home/mysql/data/mysql-bin.index
/usr/local/mysql/bin/mysqladmin -uroot -p123456 flush-logs
Counter=$(wc -l $BinFile | awk '{print $1}')
NextNum=0
for file in $(cat $BinFile); do
base=$(basename $file)
NextNum=$((NextNum + 1))
if [ $NextNum -eq $Counter ]; then
echo "$base skip!" >> $LogFile # 當前寫入中 binlog 跳過
else
dest=$BakDir/$base
if [ -e $dest ]; then
echo "$base exist!" >> $LogFile
else
cp $BinDir/$base $BakDir
echo "$base copying" >> $LogFile
fi
fi
done
echo "$(date +"%Y年%m月%d日 %H:%M:%S") Bakup succ!" >> $LogFile
# 每週日 03:00 全量
0 3 * * 0 /root/DBFullyBak.sh >/dev/null 2>&1
# 週一~六 03:00 增量
0 3 * * 1-6 /root/DBDailyBak.sh >/dev/null 2>&1
mysql-bin.index 記錄所有 binlog 文件名,腳本遍歷複製除最新外的所有flush-logs 產生新 binlog,確保增量切分點清晰--delete-master-logs 會刪除已備份的 binlog,**確認從庫同步無誤後再用**sh -n /root/DBFullyBak.sh # 無輸出即語法正確