利用 MySQL 二進制日誌記錄所有 DML/DDL 變更,定期 FLUSH LOGS 切換日誌檔案,備份新產生的 binlog 檔案即為增量備份。
[mysqld]
log_bin = mysql-bin
binlog_format = ROW -- 推薦 ROW,語句級不準確
expire_logs_days = 14 -- 自動清理舊日誌
max_binlog_size = 1G -- 單檔上限
server_id = 1 -- 必須唯一
sync_binlog = 1 -- 每次提交刷盤 (核心業務)
#!/bin/bash
# full_backup.sh
BACKUP_DIR="/backup/mysql"
DATE=$(date +%F_%H%M)
mysqldump --single-transaction --flush-logs --master-data=2 --all-databases \
--routines --triggers --events \
| gzip > "${BACKUP_DIR}/full_${DATE}.sql.gz"
# 記錄 binlog 位置 (輸出檔頭部註解)
# -- Position to start replication or point-in-time recovery from
# -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000023', MASTER_LOG_POS=154;
--flush-logs:全備前切換新 binlog,確保增量從此檔開始--master-data=2:在輸出註解記錄 binlog 位置 (不加 CHANGE MASTER 語句)#!/bin/bash
# incr_backup.sh
BINLOG_DIR="/var/lib/mysql"
BACKUP_DIR="/backup/mysql/binlog"
mkdir -p "$BACKUP_DIR"
# 1. 切換 binlog (產生新檔,舊檔固化)
mysqladmin -uroot -p'password' flush-logs
# 2. 複製「上一個」binlog 檔案到備份目錄
# 邏輯:flush-logs 後,最新的是 .000024,需備份 .000023
LATEST=$(ls -1 ${BINLOG_DIR}/mysql-bin.* | tail -1)
PREV=$(ls -1 ${BINLOG_DIR}/mysql-bin.* | tail -2 | head -1)
cp "$PREV" "${BACKUP_DIR}/$(basename $PREV)_$(date +%F_%H%M)"
# 3. 同步複製 index 檔 (可選)
cp "${BINLOG_DIR}/mysql-bin.index" "${BACKUP_DIR}/mysql-bin.index_$(date +%F_%H%M)"
# 1. 還原週日全備
gunzip -c /backup/mysql/full_2024-01-07_0200.sql.gz | mysql -uroot -p
# 2. 依序重放增量 binlog
mysqlbinlog /backup/mysql/binlog/mysql-bin.000023_2024-01-08_0200 | mysql -uroot -p
mysqlbinlog /backup/mysql/binlog/mysql-bin.000024_2024-01-09_0200 | mysql -uroot -p
mysqlbinlog /backup/mysql/binlog/mysql-bin.000025_2024-01-10_0200 | mysql -uroot -p
# 3. 若故障發生在增量備份之間,可進一步重放當前活躍 binlog
mysqlbinlog /var/lib/mysql/mysql-bin.000026 | mysql -uroot -p
# 僅恢復到特定時間 (如誤刪表發生在 10:30)
mysqlbinlog --start-datetime="2024-01-10 02:00:00" \
--stop-datetime="2024-01-10 10:30:00" \
/var/lib/mysql/mysql-bin.000026 | mysql -uroot -p
# 或按位置
mysqlbinlog --start-position=154 --stop-position=123456 \
/var/lib/mysql/mysql-bin.000026 | mysql -uroot -p
rsync -avz /backup/mysql/ remote:/backup/mysql/mysqlbinlog --verify-binlog-checksum、增量檔 sha256sumgtid_mode=ON 簡化增量定位,無需手動記錄文件/位置| 錯誤 | 原因 | 解決 |
|---|---|---|
ERROR 1236: Could not find first log file name in binary log index file | binlog 已被 purge/expire | 縮短 expire_logs_days、異地歸檔、改用 GTID |
| 重放卡住/極慢 | 大事務、無索引 UPDATE/DELETE | 拆分大事務、確保 WHERE 走索引、調大 max_allowed_packet |
| 主鍵衝突 | 重放重複、或自增衝突 | 檢查 auto_increment_increment/offset、使用 GTID 去重 |