- deploy/qa-db/: qdrant/neo4j systemd 裸进程安装脚本+unit模板+整库替换(replace_db.sh) * 数据双制品模型: <部署根>/qa-db 与 install 分开传输, 支持频繁整库替换 * 免编译(官方静态二进制/tarball)+本地 bin/ 离线分发+国内镜像回退 * 端口 27433/27434+19888/19885(127.0.0.1), 175 docker 容器(27333/19788)为其他项目共享不动 - backend_guard.py: 移除精确计数相等校验(数据库会整库替换/持续更新, 不得锁死版本) 保留身份校验(release/collection/kb_version/标签/关系类型), 计数仅随 health 返回 - qa/scripts/start.sh: reranker 模型路径回退(install/models/bge-reranker-base) - build_all.sh: qa-db 脚本+reranker 模型入包; .gitignore: qa-db/bin 离线载体 - DEPLOY_FLOW.md: §0/§5.0/§5.0b/§6.0b/§7 QA 数据库裸进程标准 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
75 lines
2.7 KiB
Bash
Executable File
75 lines
2.7 KiB
Bash
Executable File
#!/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"
|