生產環境數據無價,備份策略必須「多層次、可驗證、可自動化」。本文提供成熟的 Shell 腳本方案:每周全量邏輯備份 + 每日兩次二進制日志增量備份,配合 crontab 定時執行。
| 類型 | 頻率 | 工具 | 保留策略 | 用途 |
|---|---|---|---|---|
| 全量邏輯備份 | 每周 1 次(如周六深夜) | mysqldump + 壓縮 | 保留 4 週 | 災難恢復基線、跨版本遷移 |
| 二進制日志增量備份 | 每日 2 次(如 12:30, 23:30) | mysqladmin flush-logs + 複製 | 保留 2 週 | 時間點恢復(PITR)、減少 RPO |
full_backup.sh#!/bin/bash
# 配置區
DB_USER="root"
DB_PASS="your_password"
DB_NAME="your_database"
BACKUP_DIR="/backup/mysql/full"
DATE=$(date +%Y_%m_%d_%H%M%S)
FILE_PREFIX="${BACKUP_DIR}/${DATE}"
# 執行備份
mysqldump -u${DB_USER} -p${DB_PASS} \
--single-transaction \
--flush-logs \
--master-data=2 \
--routines --triggers --events \
${DB_NAME} > ${FILE_PREFIX}.sql
# 壓縮並清理
gzip ${FILE_PREFIX}.sql
# 可選:刪除 28 天前備份
find ${BACKUP_DIR} -name "*.gz" -mtime +28 -delete
echo "[$(date)] Full backup completed: ${FILE_PREFIX}.sql.gz"
關鍵參數解析:
--single-transaction:InnoDB 熱備不鎖表,保證一致性視圖--flush-logs:切換 binlog,配合 --master-data=2 記錄 binlog 位點(註釋形式)--master-data=2:輸出 CHANGE MASTER TO 註釋,便於從庫搭建incr_backup.sh#!/bin/bash
# 前置條件:my.cnf 已啟用 log_bin,且 binlog 格式建議 ROW 或 MIXED
MYSQL_USER="root"
MYSQL_PASS="your_password"
MYSQL_BIN_DIR="/var/lib/mysql" # datadir,binlog 所在目錄
BACKUP_DIR="/backup/mysql/incremental"
DATE=$(date +%Y_%m_%d_%H%M%S)
# 1. 切換 binlog,產生新文件
mysqladmin -u${MYSQL_USER} -p${MYSQL_PASS} flush-logs
# 2. 找出上一個 binlog 文件(即剛切換前的文件)
cd ${MYSQL_BIN_DIR}
# 假設 binlog 命名為 mysql-bin.000001 格式
LAST_BINLOG=$(ls -1 mysql-bin.* | sort -V | tail -2 | head -1)
if [[ -f "${LAST_BINLOG}" ]]; then
cp ${LAST_BINLOG} ${BACKUP_DIR}/
gzip ${BACKUP_DIR}/${LAST_BINLOG}
echo "[$(date)] Incremental backup: ${LAST_BINLOG}.gz"
else
echo "[$(date)] ERROR: No binlog found to backup" >&2
exit 1
fi
# 3. 清理 14 天前增量備份
find ${BACKUP_DIR} -name "*.gz" -mtime +14 -delete
注意:
BACKUP_DIR 存在且 MySQL 進程有讀權限md5sum)並上傳異地存儲# 編輯 crontab(root 用戶)
crontab -e
# 全量備份:每周六 02:00
0 2 * * 6 /backup/scripts/full_backup.sh >> /var/log/mysql_full_backup.log 2>&1
# 增量備份:每日 12:30 和 23:30
30 12,23 * * * /backup/scripts/incr_backup.sh >> /var/log/mysql_incr_backup.log 2>&1
備份未經恢復驗證等於廢紙。建議每季度演練一次:
gunzip -c full_backup.sql.gz | mysql -u root -pmysqlbinlog binlog.00000X.gz | mysql -u root -pbinlog_row_image=MINIMAL 減少 binlog 體積openssl 或 gpg)並異地存儲(OSS/S3/異地機房)