在 Ubuntu/Linux 環境下,通過 Shell 腳本 + mysqldump + crontab 實現每日自動全量備份,支援壓縮、遠程同步、保留策略。
# 建立備份儲存目錄
mkdir -p /mysqldata/backup
# 建立備份腳本
cat > /usr/local/bin/backup_mysql.sh << 'EOF'
#!/bin/bash
# MySQL 每日全量備份腳本
set -euo pipefail
# === 配置區 ===
DB_USER="root"
DB_PASS="your_strong_password" # 建議用 .my.cnf 或密鑰文件避免明文
DB_HOST="localhost"
BACKUP_DIR="/mysqldata/backup"
RETENTION_DAYS=7 # 保留 7 天
DATE_FMT=$(date +%F_%H-%M-%S)
FILE_NAME="mysql_full_${DATE_FMT}.sql"
COMPRESS_CMD="gzip -9"
# ===============
mkdir -p "${BACKUP_DIR}"
# 執行備份
mysqldump \
--host="${DB_HOST}" \
--user="${DB_USER}" \
--password="${DB_PASS}" \
--all-databases \
--single-transaction \
--routines \
--triggers \
--events \
--master-data=2 \
--flush-logs \
> "${BACKUP_DIR}/${FILE_NAME}"
# 壓縮
${COMPRESS_CMD} "${BACKUP_DIR}/${FILE_NAME}"
# 清理舊備份
find "${BACKUP_DIR}" -type f -name "mysql_full_*.sql.gz" -mtime +${RETENTION_DAYS} -delete
echo "[$(date)] Backup completed: ${FILE_NAME}.gz"
EOF
chmod +x /usr/local/bin/backup_mysql.sh
# 編輯 root 的 crontab
crontab -e
# 每天凌晨 03:01 執行
1 3 * * * /usr/local/bin/backup_mysql.sh >> /var/log/mysql_backup.log 2>&1
# /root/.my.cnf (權限 600)
[client]
user=root
password=your_strong_password
host=localhost
# 腳本中移除 --password 參數,mysqldump 自動讀取
# 腳本末尾追加
rsync -avz --delete \
-e "ssh -i /root/.ssh/backup_key -o StrictHostKeyChecking=no" \
"${BACKUP_DIR}/" \
backup_user@backup-server:/remote/backup/mysql/
/usr/local/bin/backup_mysql.sh 檢查輸出與生成檔案。tail -f /var/log/mysql_backup.log。gunzip -c backup.sql.gz | mysql -u root -p test_restore 測試恢復。| 問題 | 原因 | 解決 |
|---|---|---|
| crontab 不執行 | 環境變數缺失 (PATH) | 腳本內使用絕對路徑或開頭 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
| mysqldump 權限不足 | 缺少 PROCESS/LOCK TABLES/RELOAD 權限 | 授權:GRANT PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup'@'localhost'; |
| 備份檔案過大 | 無壓縮/保留策略失效 | 啟用 gzip/zstd 壓縮 + find -mtime 清理 |
| 備份期間業務卡頓 | 鎖表/單執行緒導出 | 使用 --single-transaction (InnoDB) + 從庫備份 |