Files
hfb_sys/scripts/backup-scheduler.sh
T
2026-08-17 00:17:42 +08:00

86 lines
3.0 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
umask 077
# 由宿主机 cron 每分钟调用。调度配置来自后台 system_configs,实际执行仍在宿主机,
# Web 后端不接触 Docker socket、备份载荷或客户端加密密码。
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=backup-common.sh
source "${SCRIPT_DIR}/backup-common.sh"
config_value() {
local key="$1" fallback="$2" value
value="$(backup_mysql_root_query "SELECT value FROM system_configs WHERE \`key\` = '${key}' LIMIT 1;" 2>/dev/null || true)"
value="${value//$'\n'/}"
printf '%s' "${value:-${fallback}}"
}
write_job_state() {
local status_dir="$1" type="$2" status="$3" message="$4"
mkdir -p "${status_dir}"
{
printf 'job_type=%q\n' "${type}"
printf 'job_status=%q\n' "${status}"
printf 'job_at=%q\n' "$(date -Iseconds)"
printf 'job_message=%q\n' "${message}"
} > "${status_dir}/last-job.env"
chmod 600 "${status_dir}/last-job.env"
}
run_job() {
local status_dir="$1" type="$2" script="$3"
shift 3
if "${script}" "$@"; then
write_job_state "${status_dir}" "${type}" success '执行成功'
"${SCRIPT_DIR}/backup-status.sh" write || true
return
else
# 必须在失败分支中立即读取退出码;if 语句本身在无 else 时会返回 0。
local code=$?
write_job_state "${status_dir}" "${type}" failed "执行失败(退出码 ${code}"
"${SCRIPT_DIR}/backup-status.sh" write || true
return "${code}"
fi
}
main() {
backup_require_cmd docker
backup_require_cmd flock
local backup_dir status_dir enabled hour minute interval now_hour now_minute
backup_dir="$(backup_require_env BACKUP_DIR)"
status_dir="${BACKUP_STATUS_DIR:-${backup_dir}/status}"
backup_validate_dir "${status_dir}"
backup_lock_or_exit "${backup_dir}/.scheduler.lock"
enabled="$(config_value 'backup.schedule_enabled' 'true')"
hour="$(config_value 'backup.full_hour' '4')"
minute="$(config_value 'backup.full_minute' '30')"
interval="$(config_value 'backup.binlog_interval_minutes' '1')"
[[ "${enabled}" == true || "${enabled}" == false ]] || { backup_error 'backup.schedule_enabled 必须为 true 或 false'; exit 1; }
[[ "${hour}" =~ ^[0-9]+$ && "${hour}" -le 23 && "${minute}" =~ ^[0-9]+$ && "${minute}" -le 59 ]] || {
backup_error '备份全量时间配置无效'
exit 1
}
[[ "${interval}" =~ ^[0-9]+$ && "${interval}" -ge 1 && "${interval}" -le 5 ]] || {
backup_error 'binlog 归档间隔必须为 1-5 分钟'
exit 1
}
if [[ "${enabled}" == false ]]; then
"${SCRIPT_DIR}/backup-status.sh" write || true
exit 0
fi
now_hour="$((10#$(date +%H)))"
now_minute="$((10#$(date +%M)))"
if ((now_minute % interval == 0)); then
run_job "${status_dir}" binlog "${SCRIPT_DIR}/archive-binlog.sh" archive
fi
if ((now_hour == hour && now_minute == minute)); then
run_job "${status_dir}" full "${SCRIPT_DIR}/backup-online.sh" full
fi
"${SCRIPT_DIR}/backup-status.sh" write || true
}
main "$@"