提交 da5fc0e1 authored 作者: 陈泽健's avatar 陈泽健

feat(health-check): 添加现场数据备份功能

- 实现 data_backup 函数,支持目录复制、可选 mysqldump 和打包功能
- 添加备份状态、目录、归档文件等关键信息的报告输出
- 支持新旧平台的目录结构适配
- 集成数据库备份功能,自动检测 umysql 容器并导出数据
- 更新报告生成逻辑,包含过程摘要和备份详情
- 实现交互式备份确认流程,支持用户选择是否执行备份
上级 e295400e
...@@ -1323,7 +1323,129 @@ check_emqx_container_exception() { ...@@ -1323,7 +1323,129 @@ check_emqx_container_exception() {
} }
# ------------------------------ # ------------------------------
# 17) 报告生成(Markdown)—增强:把 KV 也写入 # 17) 现场数据备份(对齐 ps1:目录复制 + 可选 mysqldump + 打包)
# - 本机版不做“下载到本地”,只在本机生成 tar.gz 并写入报告
# - 输出:
# bak.status = OK/WARN/FAIL/SKIP
# bak.dir = 备份目录
# bak.archive = 打包文件
# bak.items = 备份项列表
# bak.db.dump = 数据库备份文件(如有)
# ------------------------------
data_backup() {
local platform="$1"
local ts="$2"
section "现场数据备份(DataBackup)"
local base="/home/bakup"
local dir="${base}/health_bak_${ts}"
local items=()
local warnings=0
mkdir -p "$dir" || {
log ERROR "[BAK] 无法创建备份目录:$dir"
report_kv_set "bak.status" "FAIL"
report_kv_set "bak.dir" "$dir"
return 1
}
report_kv_set "bak.dir" "$dir"
copy_tree_if_exists() {
local src="$1"
local name="$2"
local dst="${dir}/${name}"
if [[ -e "$src" ]]; then
log INFO "[BAK] 复制:$src -> $dst"
mkdir -p "$(dirname "$dst")" 2>/dev/null || true
if command_exists rsync; then
rsync -a --delete --exclude 'node_modules' --exclude '.git' "$src" "$dst" >>"$LOG_FILE" 2>&1 || {
log WARN "[BAK] rsync 失败:$src"
warnings=$((warnings+1))
return 1
}
else
cp -a "$src" "$dst" >>"$LOG_FILE" 2>&1 || {
log WARN "[BAK] cp -a 失败:$src"
warnings=$((warnings+1))
return 1
}
fi
items+=("$name|$src")
return 0
fi
log WARN "[BAK] 不存在,跳过:$src"
warnings=$((warnings+1))
return 1
}
# 目录/文件清单(按 ps1 的传统平台思路)
if [[ "$platform" == "old" ]]; then
copy_tree_if_exists "/var/www/java" "var_www_java" || true
copy_tree_if_exists "/var/www/html" "var_www_html" || true
copy_tree_if_exists "/var/www/redis" "var_www_redis" || true
copy_tree_if_exists "/var/www/emqx" "var_www_emqx" || true
else
# 新平台:按实际目录结构做一个合理对齐(可按需调整)
copy_tree_if_exists "/data/services" "data_services" || true
copy_tree_if_exists "/data/middleware" "data_middleware" || true
copy_tree_if_exists "/data/third_party" "data_third_party"|| true
copy_tree_if_exists "/etc" "etc" || true
fi
# 数据库备份(如有 umysql 容器)
local db_dump="N/A"
if command_exists docker && docker ps --format '{{.Names}}' | grep -w umysql >/dev/null 2>&1; then
local dump_file="${dir}/mysql_dump_${ts}.sql"
log INFO "[BAK] 检测到 umysql 容器,尝试 mysqldump -> $dump_file"
if docker exec umysql sh -c 'command -v mysqldump >/dev/null 2>&1' >/dev/null 2>&1; then
# 这里尽量“全库导出”。账号密码差异较大,先尝试无密码/默认root,失败则记录WARN
if docker exec umysql sh -c "mysqldump -uroot --all-databases --single-transaction --quick --lock-tables=false" >"$dump_file" 2>>"$LOG_FILE"; then
db_dump="$dump_file"
log SUCCESS "[BAK] mysqldump 成功:$dump_file"
else
log WARN "[BAK] mysqldump 失败(可能需要密码/账号),已跳过(详见日志)"
rm -f "$dump_file" 2>/dev/null || true
warnings=$((warnings+1))
fi
else
log WARN "[BAK] umysql 容器内无 mysqldump,跳过数据库导出"
warnings=$((warnings+1))
fi
else
log INFO "[BAK] 未检测到 umysql 容器,跳过数据库导出"
fi
report_kv_set "bak.db.dump" "$db_dump"
# 打包
local archive="${base}/health_bak_${ts}.tar.gz"
log INFO "[BAK] 打包:$archive"
if tar -czf "$archive" -C "$dir" . >>"$LOG_FILE" 2>&1; then
log SUCCESS "[BAK] 打包完成:$archive"
report_kv_set "bak.archive" "$archive"
else
log ERROR "[BAK] 打包失败:$archive"
report_kv_set "bak.archive" "N/A"
report_kv_set "bak.status" "FAIL"
return 1
fi
if [[ "${#items[@]}" -gt 0 ]]; then
report_kv_set "bak.items" "$(printf "%s\n" "${items[@]}")"
else
report_kv_set "bak.items" ""
fi
if [[ "$warnings" -gt 0 ]]; then
report_kv_set "bak.status" "WARN"
else
report_kv_set "bak.status" "OK"
fi
return 0
}
# ------------------------------
# 18) 报告生成(Markdown)—增强:把 KV 也写入
# ------------------------------ # ------------------------------
write_report() { write_report() {
local server_ip="$1" local server_ip="$1"
...@@ -1349,6 +1471,19 @@ write_report() { ...@@ -1349,6 +1471,19 @@ write_report() {
w "- 脚本版本: $SCRIPT_VERSION" w "- 脚本版本: $SCRIPT_VERSION"
w "" w ""
# ✅ 新增:将旧的 REPORT_LINES(摘要/过程性输出)写入报告,避免丢失
if [[ "${#REPORT_LINES[@]}" -gt 0 ]]; then
w "## 过程摘要(REPORT_LINES)"
w ""
w "> 该段来自脚本过程汇总(report_add),用于补齐 ps1 风格的摘要输出。"
w ""
local rl
for rl in "${REPORT_LINES[@]}"; do
w "$rl"
done
w ""
fi
w "## 系统识别" w "## 系统识别"
w "" w ""
w '```' w '```'
...@@ -1709,12 +1844,21 @@ main() { ...@@ -1709,12 +1844,21 @@ main() {
section "现场数据备份(可选)" section "现场数据备份(可选)"
read -r -p "是否执行现场数据备份? (y/n) [默认:n]: " bak read -r -p "是否执行现场数据备份? (y/n) [默认:n]: " bak
if [[ "${bak:-n}" =~ ^[Yy]$ ]]; then if [[ "${bak:-n}" =~ ^[Yy]$ ]]; then
log WARN "[BAK] 现场数据备份:sh 版本暂未实现(建议复用 issue_handler.sh 或新增 DataBakup 实现)" if data_backup "$platform" "$TS"; then
log SUCCESS "[BAK] 现场数据备份完成:$(report_kv_get "bak.archive")"
else
log WARN "[BAK] 现场数据备份失败/部分失败(详见日志)"
fi
report_add "" report_add ""
report_add "## 现场数据备份" report_add "## 现场数据备份"
report_add "- 用户选择执行,但当前未实现(需补充 DataBakup)" report_add "- status: $(report_kv_get "bak.status")"
report_add "- dir: $(report_kv_get "bak.dir")"
report_add "- archive: $(report_kv_get "bak.archive")"
else else
log INFO "跳过现场数据备份" log INFO "跳过现场数据备份"
report_kv_set "bak.status" "SKIP"
report_kv_set "bak.dir" "N/A"
report_kv_set "bak.archive" "N/A"
report_add "" report_add ""
report_add "## 现场数据备份" report_add "## 现场数据备份"
report_add "- 用户选择跳过" report_add "- 用户选择跳过"
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论