#!/usr/bin/env bash # deploy/qa-db/replace_db.sh —— PlantAI QA 裸进程数据库整库替换(用户高频操作) # 用法(需 root;数据目录换新后属主会重对齐,按提示执行即可): # sudo -S bash replace_db.sh qdrant <新storage目录> # 替换 Qdrant 数据 # sudo -S bash replace_db.sh neo4j <新data目录> # 替换 Neo4j 数据 # 行为:停 unit → 旧目录 mv 为 .bak.<时间戳> → 新目录就位+属主对齐 → 启 unit → 探活 # → 通过后提示删除 .bak 与回滚命令。失败自动回滚。 # 配置默认与 install_qdrant.sh / install_neo4j.sh 一致: # QA_DB_ROOT 默认 <安装根>/qa-db;Qdrant HTTP 27433;Neo4j bolt 19888 set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" INSTALL_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" QA_DB_ROOT="${QA_DB_ROOT:-$INSTALL_ROOT/qa-db}" HTTP_PORT="${QDRANT_HTTP_PORT:-27433}" BOLT_PORT="${NEO4J_BOLT_PORT:-19888}" KIND="${1:-}" NEW_DIR="${2:-}" [[ $EUID -eq 0 ]] || { echo "需要 root:sudo -S bash $0 $*" >&2; exit 1; } case "$KIND" in qdrant) UNIT=qdrant-plantai; CUR="$QA_DB_ROOT/qdrant/storage"; OWNER="${SUDO_USER:-xzq}";; neo4j) UNIT=neo4j-plantai; CUR="$QA_DB_ROOT/neo4j/data"; OWNER="${SUDO_USER:-xzq}";; *) echo "用法: $0 qdrant|neo4j <新目录>"; exit 2;; esac [[ -n "$NEW_DIR" && -d "$NEW_DIR" ]] || { echo "新目录不存在:$NEW_DIR" >&2; exit 2; } systemctl is-active --quiet "$UNIT" || { echo "unit $UNIT 未运行,请先启动或检查"; exit 2; } TS="$(date +%Y%m%dT%H%M%S)" BAK="${CUR}.bak.$TS" echo "== 整库替换 $KIND ==" echo " 旧数据:$CUR" echo " 新数据:$NEW_DIR" echo " 备份为:$BAK" systemctl stop "$UNIT" sleep 3 rollback() { echo "[回滚] 恢复旧数据并重启" rm -rf "$CUR" mv "$BAK" "$CUR" chown -R "$OWNER:$OWNER" "$(dirname "$CUR")" 2>/dev/null || true systemctl start "$UNIT" exit 1 } if [[ -e "$CUR" ]]; then mv "$CUR" "$BAK"; fi mkdir -p "$(dirname "$CUR")" mv "$NEW_DIR" "$CUR" chown -R "$OWNER:$OWNER" "$CUR" systemctl start "$UNIT" || { echo "[失败] 启动失败,自动回滚"; rollback; } probe_ok=0 for _ in $(seq 1 90); do if [[ "$KIND" == qdrant ]] && curl -sf --max-time 2 "http://127.0.0.1:$HTTP_PORT/collections" >/dev/null 2>&1; then probe_ok=1; break elif [[ "$KIND" == neo4j ]] && (exec 3<>"/dev/tcp/127.0.0.1/$BOLT_PORT") 2>/dev/null; then exec 3>&- 2>/dev/null || true; probe_ok=1; break fi sleep 2 done if [[ $probe_ok -eq 0 ]]; then echo "[失败] 新库探活未通过,自动回滚" rollback fi echo "== 替换成功 ==" echo " 新库在线:$CUR" echo " 旧库备份:$BAK" echo " 确认稳定后删除备份:rm -rf $BAK" echo " 如需回滚:rm -rf $CUR && mv $BAK $CUR && systemctl restart $UNIT"