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"