資料庫備份的黃金法則是「全量備份奠基,增量備份補齊」。全量備份提供基準恢復點,增量備份(Binlog)記錄每一筆變更,兩者結合可實現任意時間點恢復(PITR)。本文提供一套在 Linux 上可直接落地的自動化腳本方案,涵蓋 Binlog 啟用、增量/全量備份腳本編寫、定時任務配置及保留策略。
編輯 /etc/my.cnf,在 [mysqld] 區段加入:
[mysqld]
log-bin = "/home/mysql/logbin.log"
binlog-format = ROW
log-bin-index = "/home/mysql/logindex"
binlog_cache_size = 32M
max_binlog_cache_size = 512M
max_binlog_size = 512M
關鍵點:
binlog-format = ROW:記錄每行實際變更,避免 Statement 格式在主從複制或回放時的非確定性問題。/home/mysql 的擁有者必須為 mysql:mysql,否則 MySQL 無法寫入。修改後重啟 MySQL 服務生效。
binlogbak.sh建立備份目錄:
mkdir -p /home/mysql/backup/daily
腳本核心邏輯:
mysqladmin flush-logs 產生新的 Binlog 檔案(切換序號)。logindex.index 獲取所有 Binlog 清單。/home/mysql/backup/binlog.log。#!/bin/bash
export LANG=en_US.UTF-8
BakDir=/home/mysql/backup/daily
BinDir=/home/mysql
LogFile=/home/mysql/backup/binlog.log
BinFile=/home/mysql/logindex.index
mysqladmin -uroot -proot123 flush-logs
Counter=$(wc -l < "$BinFile")
NextNum=0
for file in $(cat "$BinFile"); do
base=$(basename "$file")
NextNum=$((NextNum + 1))
if [ $NextNum -eq $Counter ]; then
echo "$base skip!" >> "$LogFile"
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"
賦予執行權限:chmod a+x /home/mysql/binlogbak.sh
databak.sh特點:
mysqldump --single-transaction --flush-logs --delete-master-logs:單一交易保證一致性、刷新日誌切換 Binlog、刪除已備份的舊 Binlog(避免佔用磁碟)。.tgz 節省空間。daily 目錄下的增量檔案,因為新的全量已包含這些變更。#!/bin/bash
export LANG=en_US.UTF-8
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
mysqldump -uroot -proot123 --all-databases --flush-logs --delete-master-logs --single-transaction > "$DumpFile"
tar -czvf "$GZDumpFile" "$DumpFile"
rm "$DumpFile"
# 保留最近 5 份
count=$(ls -1 *.tgz 2>/dev/null | wc -l)
if [ $count -ge 5 ]; then
oldest=$(ls -1t *.tgz | tail -1)
rm -f "$oldest"
fi
Last=$(date '+%Y年%m月%d日 %H:%M:%S')
echo "開始:$Begin 結束:$Last $GZDumpFile succ" >> "$LogFile"
# 清空增量備份目錄
rm -f "$BakDir/daily"/*
賦予執行權限:chmod a+x /home/mysql/databak.sh
# /etc/crontab
# 每週日凌晨 3:00 執行全量備份
0 3 * * 0 root /home/mysql/databak.sh >/dev/null 2>&1
# 週一至週六凌晨 3:00 執行增量備份
0 3 * * 1-6 root /home/mysql/binlogbak.sh >/dev/null 2>&1
載入生效:crontab /etc/crontab,檢視:crontab -l。
YYYYMMDD.sql.tgz 解壓還原。mysqlbinlog binlog.xxx | mysql -u... -p...)。這套方案已在生產環境穩定運行多年,關鍵在於「全量切 Binlog + 刪舊 Binlog」的原子性操作,配合保留策略,既保證資料安全又控制磁碟佔用。根據業務重要性,可將全量頻率調為每日、增量頻率調為每小時。