55 lines
1.8 KiB
Bash
Executable File
55 lines
1.8 KiB
Bash
Executable File
#!/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; }
|
|
if command -v sha256sum >/dev/null; then
|
|
checksum_command=(sha256sum)
|
|
elif command -v shasum >/dev/null; then
|
|
checksum_command=(shasum -a 256)
|
|
else
|
|
echo "未找到 sha256sum 或 shasum" >&2
|
|
exit 1
|
|
fi
|
|
|
|
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 \
|
|
--no-tablespaces \
|
|
--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")" && "${checksum_command[@]}" "$(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"
|