MySQL 資料庫自動備份腳本
功能簡介
此腳本 db_backup.sh 用於每日自動備份本機與 Docker MySQL 資料庫,並進行壓縮與清理過期備份,確保資料安全與節省磁碟空間。
功能特色
-
支援本機與 Docker MySQL
-
自動取得本機所有非系統資料庫並逐一備份
-
可設定特定 Docker 資料庫清單進行備份
-
-
gzip 壓縮
-
備份檔自動壓縮為
.sql.gz格式 -
壓縮完成後驗證檔案完整性
-
-
過期清理
-
自動刪除超過設定保留天數的舊備份
-
-
錯誤提示
-
備份或壓縮失敗時會顯示錯誤訊息
-
檔案位置
-
腳本位置:
/root/db_backup.sh -
備份目錄:
/root/backup/db -
紀錄檔:
/root/db_backup.log
自動排程(cron)
每日凌晨 1 點自動執行:
0 1 * * * /root/db_backup.sh >> /root/db_backup.log 2>&1
使用方式
手動執行:
bash /root/db_backup.sh
程式碼
#!/usr/bin/env bash
set -Eeuo pipefail
# === 共用參數設定 ===
USER="root"
PASSWORD="password"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
BACKUP_DIR="/root/backup/db"
CONTAINER="my_mysql57"
# 需備份的 Docker 資料庫(用空白分隔)
DOCKER_DATABASES="lianhung_crm lianhung_haccp"
# mysqldump 參數(可自行增減)
MYSQLDUMP_OPTS="--single-transaction --quick --lock-tables=false --routines --events --triggers"
# === 前置檢查 ===
command -v mysql >/dev/null 2>&1 || { echo "❌ 找不到 mysql 指令"; exit 1; }
command -v mysqldump >/dev/null 2>&1 || { echo "❌ 找不到 mysqldump 指令"; exit 1; }
command -v gzip >/dev/null 2>&1 || { echo "❌ 找不到 gzip 指令"; exit 1; }
command -v docker >/dev/null 2>&1 || { echo "⚠️ 找不到 docker 指令(將略過 Docker 備份)"; }
# 建立備份目錄
mkdir -p "$BACKUP_DIR"
echo "=== MySQL 資料庫備份開始:$DATE ==="
# === 本機 MySQL 資料庫逐一備份 ===
echo "取得本機 MySQL 資料庫清單..."
DATABASES=$(mysql -u"$USER" -p"$PASSWORD" -e "SHOW DATABASES;" \
| grep -Ev "^(Database|information_schema|performance_schema|mysql|sys)$" || true)
if [ -n "${DATABASES:-}" ]; then
for DB in $DATABASES; do
FILE="$BACKUP_DIR/local_${DB}_${DATE}.sql.gz"
echo "開始備份本機資料庫 $DB -> $FILE"
# 將 dump 丟給 gzip 壓縮
if mysqldump -u"$USER" -p"$PASSWORD" $MYSQLDUMP_OPTS "$DB" | gzip -9 > "$FILE"; then
# 驗證壓縮檔完整性
if gunzip -t "$FILE"; then
echo "✅ 本機資料庫 $DB 備份並壓縮成功"
else
echo "❌ 本機資料庫 $DB 壓縮檔驗證失敗:$FILE"
fi
else
echo "❌ 本機資料庫 $DB 備份失敗"
fi
done
else
echo "⚠️ 未找到可備份的本機資料庫(可能只有系統資料庫)。"
fi
# === Docker MySQL 指定資料庫備份 ===
if command -v docker >/dev/null 2>&1; then
# 檢查容器是否存在且運行
if docker ps --format '{{.Names}}' | grep -qx "$CONTAINER"; then
for DB in $DOCKER_DATABASES; do
FILE="$BACKUP_DIR/docker_${DB}_${DATE}.sql.gz"
echo "開始備份 Docker 資料庫 $DB (容器:$CONTAINER) -> $FILE"
if docker exec "$CONTAINER" mysqldump -u"$USER" -p"$PASSWORD" $MYSQLDUMP_OPTS "$DB" | gzip -9 > "$FILE"; then
if gunzip -t "$FILE"; then
echo "✅ Docker 資料庫 $DB 備份並壓縮成功"
else
echo "❌ Docker 資料庫 $DB 壓縮檔驗證失敗:$FILE"
fi
else
echo "❌ Docker 資料庫 $DB 備份失敗"
fi
done
else
echo "⚠️ 找不到執行中的容器:$CONTAINER(已略過 Docker 備份)"
fi
fi
# === 清理超過保留天數的備份 ===
echo "清理超過 $RETENTION_DAYS 天的備份..."
find "$BACKUP_DIR" -type f -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
echo "✅ 全部備份完成:$DATE"
No comments to display
No comments to display