#!/bin/bash # MySQL 全量备份脚本(Linux 容器内运行) # 用法: backup-mysql.sh --service [--keep ] set -euo pipefail # ---------- 参数解析 ---------- SERVICE="" KEEP_DAYS=7 while [[ $# -gt 0 ]]; do case "$1" in --service) SERVICE="${2:-}" shift 2 ;; --keep) KEEP_DAYS="${2:-7}" shift 2 ;; -h|--help) echo "Usage: $0 --service [--keep ]" >&2 echo " --service 目标微服务数据库名(必填,如 iam/core-edu/content/msg/classes)" >&2 echo " --keep 保留天数(默认 7)" >&2 exit 0 ;; *) echo "[ERROR] 未知参数: $1" >&2 exit 1 ;; esac done # ---------- 参数校验 ---------- if [[ -z "$SERVICE" ]]; then echo "[ERROR] --service 参数必填" >&2 exit 1 fi if ! [[ "$KEEP_DAYS" =~ ^[0-9]+$ ]] || [[ "$KEEP_DAYS" -lt 1 ]]; then echo "[ERROR] --keep 必须为正整数" >&2 exit 1 fi # ---------- 环境变量 ---------- : "${MYSQL_HOST:=mysql}" : "${MYSQL_PORT:=3306}" : "${MYSQL_USER:=root}" : "${MYSQL_PASSWORD:?MYSQL_PASSWORD 环境变量未设置}" BACKUP_ROOT="/backups" BACKUP_DIR="${BACKUP_ROOT}/${SERVICE}" TIMESTAMP="$(date +%Y%m%d-%H%M%S)" BACKUP_FILE="${BACKUP_DIR}/${TIMESTAMP}.sql.gz" # ---------- 日志函数 ---------- log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2 } # ---------- 主流程 ---------- log "[INFO] 开始备份服务: ${SERVICE} (保留 ${KEEP_DAYS} 天)" mkdir -p "$BACKUP_DIR" log "[INFO] 执行 mysqldump -> ${BACKUP_FILE}" if ! mysqldump \ --host="$MYSQL_HOST" \ --port="$MYSQL_PORT" \ --user="$MYSQL_USER" \ --password="$MYSQL_PASSWORD" \ --single-transaction \ --routines \ --triggers \ --databases "$SERVICE" \ 2>/dev/null \ | gzip -c > "$BACKUP_FILE"; then log "[ERROR] mysqldump 失败 (service=${SERVICE})" rm -f "$BACKUP_FILE" exit 1 fi # 校验产物非空 if [[ ! -s "$BACKUP_FILE" ]]; then log "[ERROR] 备份文件为空: ${BACKUP_FILE}" exit 1 fi FILE_SIZE="$(stat -c %s "$BACKUP_FILE" 2>/dev/null || stat -f %z "$BACKUP_FILE")" log "[INFO] 备份完成: ${BACKUP_FILE} (${FILE_SIZE} bytes)" # ---------- 清理过期备份 ---------- log "[INFO] 清理超过 ${KEEP_DAYS} 天的旧备份" find "$BACKUP_DIR" -type f -name '*.sql.gz' -mtime +${KEEP_DAYS} -print -delete \ | while read -r old_file; do log "[INFO] 已删除: ${old_file}" done log "[INFO] 备份流程结束: ${SERVICE}" exit 0