首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 全量與增量備份實戰:基於 Binlog 的自動化腳本方案

     編輯:MySQL 資料庫相關知識

前言:備份策略的核心——全量 + 增量

資料庫備份的黃金法則是「全量備份奠基,增量備份補齊」。全量備份提供基準恢復點,增量備份(Binlog)記錄每一筆變更,兩者結合可實現任意時間點恢復(PITR)。本文提供一套在 Linux 上可直接落地的自動化腳本方案,涵蓋 Binlog 啟用、增量/全量備份腳本編寫、定時任務配置及保留策略。

一、啟用 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

腳本核心邏輯:

  1. mysqladmin flush-logs 產生新的 Binlog 檔案(切換序號)。
  2. 讀取 logindex.index 獲取所有 Binlog 清單。
  3. 略過「當前正在寫入」的最新檔案,只備份已完成的舊檔案。
  4. 檢查目標目錄是否已存在同名檔案,避免重複複製。
  5. 記錄操作日誌至 /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 節省空間。
  • 只保留最近 5 份全量備份(可依需求調整)。
  • 全量備份完成後清空 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

四、配置 Crontab 定時任務

# /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。

五、恢復演練建議

  1. 找到目標時間點前最近的一份全量備份 YYYYMMDD.sql.tgz 解壓還原。
  2. 依序應用該全量備份之後、目標時間點之前的所有 Binlog 檔案(mysqlbinlog binlog.xxx | mysql -u... -p...)。
  3. 定期演練恢復流程,驗證備份可用性與 RTO/RPO 指標。

這套方案已在生產環境穩定運行多年,關鍵在於「全量切 Binlog + 刪舊 Binlog」的原子性操作,配合保留策略,既保證資料安全又控制磁碟佔用。根據業務重要性,可將全量頻率調為每日、增量頻率調為每小時。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved