資料庫備份是資安最後一道防線。本文提供 Windows Bat、Linux Shell 兩大平台的自動備份腳本,涵蓋 mysqldump 邏輯備份、xtrabackup 物理熱備份、壓縮、加密、定時任務、還原驗證全流程,可直接落地生產環境。
| 策略 | 頻率 | 保留 | 工具 | 適用場景 |
|---|---|---|---|---|
| 全量邏輯備份 | 每日 1 次(低峰) | 7-30 天 | mysqldump | 中小型庫(< 50GB)、需跨版本遷移 |
| 增量邏輯備份 | 每小時/每 15 分鐘 | 7 天 | mysqldump --flush-logs / binlog | RPO < 1 小時 |
| 全量物理熱備份 | 每日/每週 | 7-30 天 | xtrabackup / mariabackup | 大型庫(> 50GB)、要求極速恢復 |
| 增量物理備份 | 每小時 | 7 天 | xtrabackup --incremental | 大型庫、RPO < 1 小時 |
@echo off
REM ==== 配置區 ====
set MYSQL_BIN="C:\Program Files\MySQL\MySQL Server 8.0\bin"
set DB_USER=root
set DB_PASS=your_strong_password
set DB_NAME=my_database
set BACKUP_DIR=D:\MySQL_Backup
set KEEP_DAYS=7
REM ================
set YMD=%date:~0,4%%date:~5,2%%date:~8,2%
set HMS=%time:~0,2%%time:~3,2%%time:~6,2%
set HMS=%HMS: =0%
set FILE_NAME=%DB_NAME%_%YMD%_%HMS%.sql
mkdir "%BACKUP_DIR%\%YMD%" 2>nul
"%MYSQL_BIN%\mysqldump.exe" -u%DB_USER% -p%DB_PASS% --single-transaction --routines --triggers --events --quick --hex-blob %DB_NAME% > "%BACKUP_DIR%\%YMD%\%FILE_NAME%"
if %errorlevel% neq 0 (
echo [ERROR] Backup failed at %date% %time%
exit /b 1
)
echo [OK] Backup saved to %BACKUP_DIR%\%YMD%\%FILE_NAME%
REM 刪除舊備份
forfiles /p "%BACKUP_DIR%" /s /m *.* /d -%KEEP_DAYS% /c "cmd /c del @path" 2>nul
@echo off
set FILE_NAME=%DB_NAME%_%YMD%_%HMS%.sql
set ZIP_FILE=%FILE_NAME%.zip
set ENC_FILE=%ZIP_FILE%.enc
REM 1. 備份
"%MYSQL_BIN%\mysqldump.exe" ... > "%BACKUP_DIR%\%FILE_NAME%"
REM 2. 壓縮 (需安裝 7-Zip)
"C:\Program Files\7-Zip\7z.exe" a -tzip "%BACKUP_DIR%\%ZIP_FILE%" "%BACKUP_DIR%\%FILE_NAME%"
del "%BACKUP_DIR%\%FILE_NAME%"
REM 3. AES-256 加密 (需 OpenSSL)
openssl enc -aes-256-cbc -salt -pbkdf2 -in "%BACKUP_DIR%\%ZIP_FILE%" -out "%BACKUP_DIR%\%ENC_FILE%" -pass pass:YourEncryptionKey
del "%BACKUP_DIR%\%ZIP_FILE%"
REM 4. 上傳至 S3/Azure Blob/GCS (略)
REM aws s3 cp "%BACKUP_DIR%\%ENC_FILE%" s3://my-bucket/mysql-backup/
#!/bin/bash
# /usr/local/bin/mysql_backup.sh
# 每日 02:00 執行:0 2 * * * /usr/local/bin/mysql_backup.sh >> /var/log/mysql_backup.log 2>&1
set -euo pipefail
# 配置
MYSQL_USER="root"
MYSQL_PASS="your_strong_password"
MYSQL_HOST="127.0.0.1"
MYSQL_PORT="3306"
DB_NAME="my_database"
BACKUP_DIR="/backup/mysql"
KEEP_DAYS=7
DATE=$(date +%F_%H-%M-%S)
FILE_NAME="${DB_NAME}_${DATE}.sql.gz"
# 建立目錄
mkdir -p "${BACKUP_DIR}/$(date +%F)"
# 備份並壓縮
mysqldump -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASS} \
--single-transaction --routines --triggers --events --quick --hex-blob \
${DB_NAME} | gzip > "${BACKUP_DIR}/$(date +%F)/${FILE_NAME}"
# 驗證備份檔案
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
echo "[$(date)] ERROR: mysqldump failed" >&2
exit 1
fi
echo "[$(date)] OK: Backup saved to ${BACKUP_DIR}/$(date +%F)/${FILE_NAME}"
# 清理舊備份
find "${BACKUP_DIR}" -type f -name "*.sql.gz" -mtime +${KEEP_DAYS} -delete
#!/bin/bash
# /usr/local/bin/xtrabackup_full.sh
# 需安裝 percona-xtrabackup-80
BACKUP_DIR="/backup/xtrabackup"
FULL_DIR="${BACKUP_DIR}/full_$(date +%F_%H-%M-%S)"
INCR_BASE="${BACKUP_DIR}/full_latest"
mkdir -p "${FULL_DIR}"
# 全量備份
xtrabackup --backup --target-dir="${FULL_DIR}" \
--user=root --password='your_strong_password' \
--compress --compress-threads=4 \
--parallel=4 --slave-info --safe-slave-backup
# 更新最新全量備份連結
ln -sfn "${FULL_DIR}" "${INCR_BASE}"
# 備份完成後需 prepare(可延後到恢復前)
# xtrabackup --prepare --target-dir="${FULL_DIR}"
#!/bin/bash
# /usr/local/bin/xtrabackup_incr.sh
# 每小時執行:0 * * * * /usr/local/bin/xtrabackup_incr.sh
INCR_DIR="/backup/xtrabackup/incr_$(date +%F_%H-%M-%S)"
INCR_BASE="/backup/xtrabackup/full_latest"
mkdir -p "${INCR_DIR}"
xtrabackup --backup --target-dir="${INCR_DIR}" \
--incremental-basedir="${INCR_BASE}" \
--user=root --password='your_strong_password' \
--compress --parallel=2
# 解壓並還原
gunzip -c backup_2024-01-15_02-00-00.sql.gz | mysql -u root -p my_database
# 或指定字元集
mysql -u root -p --default-character-set=utf8mb4 my_database < backup.sql
# 1. 停止 MySQL
systemctl stop mysql
# 2. 清空資料目錄(備份原目錄以防萬一)
mv /var/lib/mysql /var/lib/mysql.bak
mkdir /var/lib/mysql && chown mysql:mysql /var/lib/mysql
# 3. Prepare 備份(合併增量)
xtrabackup --prepare --target-dir=/backup/xtrabackup/full_latest
# 若有增量:依序 prepare --apply-log-only 最後一個不加 --apply-log-only
# 4. 恢復
xtrabackup --copy-back --target-dir=/backup/xtrabackup/full_latest
# 5. 修正權限並啟動
chown -R mysql:mysql /var/lib/mysql
systemctl start mysql
sha256sum,上傳雲端前後比對。CHECKSUM TABLE 比對源庫。企業級 MySQL 備份體系 = 邏輯備份(跨版本、審計)+ 物理熱備份(大庫、快速恢復)。Windows 用 Bat + 排程器,Linux 用 Shell + Cron + xtrabackup。**備份未驗證等於沒備份**,請務必建立定期恢復演練機制。