一個成熟的 MySQL 備份腳本需具備:**完全備份、壓縮存儲、異地同步、留存策略、失敗告警、定時自動化、可驗證恢復**。本文提供一個生產級 Shell 腳本,支援 `mysqldump` 邏輯備份,配置 `cron` 定時執行,內建 30 天舊備份清理與任務冪等安裝。
back_mysql.sh)#!/bin/bash
# MySQL 自動備份腳本
# 作者: csy 日期: 2015-11-11
# 功能: 邏輯備份單庫、壓縮、30天留存、cron任務自註冊
# ===== 變量配置區 (按實際環境修改) =====
BAK_CMD="/usr/bin/mysqldump"
BAK_HOST="localhost"
BAK_DB="csy" # 目標庫,多庫用 --databases db1 db2
BAK_USER="root"
BAK_PASS="123456" # 建議用 .my.cnf 或密碼文件替代明文
BAK_DIR="/tmp/mysqlbackup" # 備份目錄,建議掛載獨立磁碟/NFS
BAK_DATE=$(date +%F) # 2023-10-15
BAK_FILE="${BAK_DIR}/${BAK_DB}_${BAK_DATE}.sql"
# ===== 環境檢查 =====
if [[ $UID -ne 0 ]]; then
echo -e "\033[31m[ERROR] 必須用 root 執行\033[0m"; exit 1
fi
[[ ! -d $BAK_DIR ]] && mkdir -p $BAK_DIR && echo -e "\033[32m[INFO] 建立目錄 $BAK_DIR\033[0m"
# ===== 執行備份 =====
echo -e "\033[34m[INFO] 開始備份 $BAK_DB ...\033[0m"
$BAK_CMD -h"$BAK_HOST" -u"$BAK_USER" -p"$BAK_PASS" \
--single-transaction --routines --triggers --events --databases "$BAK_DB" \
> "$BAK_FILE"
if [[ $? -eq 0 ]]; then
gzip "$BAK_FILE" # 壓縮節省空間
echo -e "\033[32m[SUCCESS] 備份完成: ${BAK_FILE}.gz\033[0m"
else
echo -e "\033[31m[ERROR] 備份失敗,請檢查日誌\033[0m"; exit 1
fi
# ===== 清理 30 天前舊備份 =====
find "$BAK_DIR" -type f -name "*.gz" -mtime +30 -exec rm -f {} \;
echo -e "\033[36m[INFO] 清理 30 天前舊備份完成\033[0m"
# ===== 註冊 cron 任務 (冪等) =====
CRON_JOB="30 20 * * 5 $0 > /tmp/mysql_backup.log 2>&1" # 每周五 20:30
if ! crontab -l 2>/dev/null | grep -qF "$0"; then
(crontab -l 2>/dev/null; echo "$CRON_JOB") | crontab -
echo -e "\033[32m[INFO] 已註冊定時任務: $CRON_JOB\033[0m"
else
echo -e "\033[36m[INFO] 定時任務已存在,跳過註冊\033[0m"
fi
| 參數 | 作用 |
|---|---|
--single-transaction | InnoDB 熱備核心:啟動一致性快照,不鎖表,不阻塞寫入 |
--routines --triggers --events | 備份存儲過程、觸發器、事件調度器 |
--databases | 輸出帶 CREATE DATABASE、USE,便於直接導入 |
gzip | SQL 文本壓縮比通常 80%+,極大節省磁碟 |
-mtime +30 | 刪除修改時間超過 30 天的 .gz 文件 |
30 20 * * 5 | cron 表達式:每周五 20:30 執行(可改為每日 0 2 * * *) |
/root/.my.cnf [client] section 存密碼,腳本移除 -p 參數。rsync -avz /backup/ user@offsite:/backup/ 或上傳 S3/OSS。gunzip < file.gz | mysql -u root -p 恢復驗證,記錄 RTO/RPO。zabbix 監控備份文件大小、修改時間。mysqldump 或用 mydumper (多線程、一致性快照、壓縮輸出)。xtrabackup 物理備份,恢復速度比邏輯備份快 10 倍+。# 邏輯備份恢復 gunzip < csy_2023-10-15.sql.gz | mysql -uroot -p # 單庫恢復到新庫名 mysql -uroot -p -e "CREATE DATABASE csy_restore;" gunzip < csy_2023-10-15.sql.gz | mysql -uroot -p csy_restore # 物理備份恢復 (xtrabackup) xtrabackup --prepare --target-dir=/backup/full_2023-10-15 systemctl stop mysql rm -rf /var/lib/mysql/* xtrabackup --copy-back --target-dir=/backup/full_2023-10-15 chown -R mysql:mysql /var/lib/mysql systemctl start mysql
備份腳本只是起點,**「定期演練恢複、異地多副本、監控告警閉環」** 才是數據安全的鐵三角。將本腳本納入 Ansible/SaltStack 基礎設施代碼,新機器自動落地備份策略,讓「備而不用、用而不慌」成為常態。