#!/usr/bin/env bash set -euo pipefail # 支持两种模式: # 1) 本机 mysql/mysqldump: # MYSQL_HOST MYSQL_PORT MYSQL_USER MYSQL_PASSWORD MYSQL_DATABASE # 2) 容器内执行(推荐在无本地 mysql 客户端时使用): # MYSQL_CONTAINER= MYSQL_HOST="${MYSQL_HOST:-127.0.0.1}" MYSQL_PORT="${MYSQL_PORT:-3306}" MYSQL_USER="${MYSQL_USER:-root}" MYSQL_PASSWORD="${MYSQL_PASSWORD:-}" MYSQL_DATABASE="${MYSQL_DATABASE:-wx_service}" MYSQL_CONTAINER="${MYSQL_CONTAINER:-}" BACKUP_DIR="${BACKUP_DIR:-/var/backups/wx_service}" KEEP_DAYS="${KEEP_DAYS:-7}" OPS_ALERT_WEBHOOK="${OPS_ALERT_WEBHOOK:-}" ALERT_TITLE="${ALERT_TITLE:-[wx_service] 数据备份失败}" send_alert() { local message="$1" if [[ -z "${OPS_ALERT_WEBHOOK}" ]]; then echo "ALERT: ${message}" >&2 return fi curl -fsS -X POST "${OPS_ALERT_WEBHOOK}" \ -H "Content-Type: application/json" \ -d "{\"title\":\"${ALERT_TITLE}\",\"message\":\"${message}\"}" >/dev/null || true } dump_cmd() { if [[ -n "${MYSQL_CONTAINER}" ]]; then if [[ -n "${MYSQL_PASSWORD}" ]]; then docker exec "${MYSQL_CONTAINER}" mysqldump -h127.0.0.1 -P"${MYSQL_PORT}" -u"${MYSQL_USER}" "-p${MYSQL_PASSWORD}" --single-transaction --quick --set-gtid-purged=OFF "${MYSQL_DATABASE}" else docker exec "${MYSQL_CONTAINER}" mysqldump -h127.0.0.1 -P"${MYSQL_PORT}" -u"${MYSQL_USER}" --single-transaction --quick --set-gtid-purged=OFF "${MYSQL_DATABASE}" fi return fi if [[ -n "${MYSQL_PASSWORD}" ]]; then mysqldump -h"${MYSQL_HOST}" -P"${MYSQL_PORT}" -u"${MYSQL_USER}" "-p${MYSQL_PASSWORD}" --single-transaction --quick --set-gtid-purged=OFF "${MYSQL_DATABASE}" else mysqldump -h"${MYSQL_HOST}" -P"${MYSQL_PORT}" -u"${MYSQL_USER}" --single-transaction --quick --set-gtid-purged=OFF "${MYSQL_DATABASE}" fi } mkdir -p "${BACKUP_DIR}" timestamp="$(date +%Y%m%d_%H%M%S)" outfile="${BACKUP_DIR}/${MYSQL_DATABASE}_${timestamp}.sql.gz" if ! dump_cmd | gzip -9 > "${outfile}"; then send_alert "MySQL 备份失败,数据库=${MYSQL_DATABASE}" exit 1 fi find "${BACKUP_DIR}" -type f -name "${MYSQL_DATABASE}_*.sql.gz" -mtime +"${KEEP_DAYS}" -delete || true echo "backup created: ${outfile}"