#!/usr/bin/env bash set -euo pipefail BACKUP_DIR="${BACKUP_DIR:-./backups}" MYSQL_HOST="${MYSQL_HOST:-127.0.0.1}" MYSQL_PORT="${MYSQL_PORT:-3307}" MYSQL_USER="${MYSQL_USER:-ai_kb}" MYSQL_DATABASE="${MYSQL_DATABASE:-ai_knowledge_base_v2}" BACKUP_RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-14}" : "${MYSQL_PASSWORD:?必须通过 MYSQL_PASSWORD 配置数据库密码}" command -v mysqldump >/dev/null || { echo "未找到 mysqldump" >&2; exit 1; } command -v gzip >/dev/null || { echo "未找到 gzip" >&2; exit 1; } command -v shasum >/dev/null || { echo "未找到 shasum" >&2; exit 1; } mkdir -p "$BACKUP_DIR" timestamp="$(date +%Y%m%d_%H%M%S)" output_file="$BACKUP_DIR/${MYSQL_DATABASE}_${timestamp}.sql.gz" temporary_file="${output_file}.tmp" trap 'rm -f "$temporary_file"' EXIT MYSQL_PWD="$MYSQL_PASSWORD" mysqldump \ --host="$MYSQL_HOST" \ --port="$MYSQL_PORT" \ --user="$MYSQL_USER" \ --single-transaction \ --quick \ --routines \ --triggers \ --events \ --set-gtid-purged=OFF \ --default-character-set=utf8mb4 \ "$MYSQL_DATABASE" | gzip -9 > "$temporary_file" gzip -t "$temporary_file" test -s "$temporary_file" mv "$temporary_file" "$output_file" (cd "$(dirname "$output_file")" && shasum -a 256 "$(basename "$output_file")" > "$(basename "$output_file").sha256") if [[ "$BACKUP_RETENTION_DAYS" =~ ^[0-9]+$ ]] && (( BACKUP_RETENTION_DAYS > 0 )); then find "$BACKUP_DIR" -type f \( -name "${MYSQL_DATABASE}_*.sql.gz" -o -name "${MYSQL_DATABASE}_*.sql.gz.sha256" \) \ -mtime "+$BACKUP_RETENTION_DAYS" -delete fi echo "备份完成:$output_file" echo "校验文件:${output_file}.sha256"