feat:备份恢复完善用户密钥的流程

This commit is contained in:
waner
2026-05-07 10:46:25 +08:00
parent 11e6049ae2
commit 03d8ccce78
18 changed files with 599 additions and 15 deletions
@@ -24,6 +24,8 @@ PAYLOAD_DIR="${WORK_DIR}/payload"
STATUS_FILE="${WORK_DIR}/status.json"
LOG_FILE="${WORK_DIR}/restore.log"
MANIFEST="${PAYLOAD_DIR}/payload-manifest.json"
# Java 解包阶段会把 payload-manifest.json 转换成下面三份 TSV。
# shell 阶段只消费 TSV,避免在 bash 中解析复杂 JSON。
FILES_PLAN="${WORK_DIR}/restore-files.tsv"
DATABASES_PLAN="${WORK_DIR}/restore-databases.tsv"
MQ_PLAN="${WORK_DIR}/restore-mq.tsv"
@@ -41,6 +43,8 @@ write_status() {
local status="$1"
local phase="$2"
local message="$3"
# status.json 是 Java 查询接口和运维排障共同读取的轻量状态文件。
# 即使 TMS 服务被 stop,脚本仍会持续刷新这个文件,服务重启后可继续展示结果。
printf '{"status":"%s","phase":"%s","message":"%s","updatedAt":"%s"}\n' \
"$(json_escape "${status}")" \
"$(json_escape "${phase}")" \
@@ -70,6 +74,8 @@ require_env() {
restore_files() {
[[ -f "${FILES_PLAN}" ]] || return 0
# restore-files.tsv 每行格式:payload内相对路径<TAB>目标绝对路径。
# 目标路径白名单已在 Java 解包阶段校验,这里只负责按计划覆盖文件。
while IFS=$'\t' read -r entry_path restore_path || [[ -n "${entry_path:-}" ]]; do
[[ -n "${entry_path:-}" ]] || continue
[[ -n "${restore_path:-}" ]] || fail "restore file target is empty for ${entry_path}" "FILE"
@@ -86,6 +92,8 @@ restore_databases() {
[[ -s "${DATABASES_PLAN}" ]] || return 0
local script="${DB_RESTORE_SCRIPT_PATH:-}"
[[ -n "${script}" && -x "${script}" ]] || fail "DB_RESTORE_SCRIPT_PATH is not executable" "DATABASE"
# 数据库连接参数来自 Java 生成的 restore-env.sh;实际导入命令下沉到 restore-db.sh,
# 方便现场根据 MySQL/TiDB 客户端和账号策略调整实现。
require_env "DB_HOST" "DATABASE"
require_env "DB_PORT" "DATABASE"
require_env "DB_USER" "DATABASE"
@@ -113,6 +121,7 @@ replay_mq() {
[[ -s "${MQ_PLAN}" ]] || return 0
local script="${MQ_REPLAY_SCRIPT_PATH:-}"
[[ -n "${script}" && -x "${script}" ]] || fail "MQ_REPLAY_SCRIPT_PATH is not executable" "MQ_REPLAY"
# MQ replay 当前只接收 Java 生成的上下文文件,具体恢复 RabbitMQ/TLQ/CFMQ 的命令由现场脚本实现。
while IFS= read -r entry_path || [[ -n "${entry_path:-}" ]]; do
[[ -n "${entry_path:-}" ]] || continue
local context_file="${PAYLOAD_DIR}/${entry_path}"
@@ -144,11 +153,14 @@ chmod 700 "${WORK_DIR}" || true
if [[ -f "${ENV_FILE}" ]]; then
# shellcheck disable=SC1090
# restore-env.sh 由 LightweightRestoreApplierLauncher 生成,包含脚本路径、数据库连接和健康检查配置。
source "${ENV_FILE}"
fi
[[ -f "${MANIFEST}" ]] || fail "payload manifest not found" "PRECHECK"
# 从这里开始进入停机恢复窗口。TMS_SCRIPT_PATH stop/start 允许失败后继续,
# 因为某些部署环境可能由 systemd/外部平台接管服务状态,但文件/数据库/MQ 失败必须中断。
write_status "RUNNING" "SERVICE_STOP" "stopping services"
log "SERVICE_STOP"
if [[ -n "${TMS_SCRIPT_PATH:-}" && -x "${TMS_SCRIPT_PATH}" ]]; then