#!/usr/bin/env bash # 一次性数据目录迁移:results→seeds、archive→result(目录重命名后的历史数据搬迁)。 # # 背景:data 目录重新规划后,两个子目录改名: # data/results/ → data/seeds/ (server 种子库;原名 results 误导,实际只存种子) # data/archive/ → data/result/ (node 完整计算结果归档;原名 archive 不够准确) # 本脚本把已落盘的旧目录搬到新位置,并修正 DB 的 seeds.file_path 审计字段。 # # 关键事实(已确认): # - download_seed 端点不读 seeds.file_path(从 seeds_dir 重拼路径),故 DB 迁移失败 # 不影响功能;但保持审计一致仍建议执行。 # - 迁移需在 server 停机时进行(mv 整目录 + 写 DB)。 # # 用法: # ./scripts/migrate_data_dirs.sh # dry-run,只看将做什么 # ./scripts/migrate_data_dirs.sh --apply # 实际执行 # # 环境变量: # DCTS_DATA_DIR 数据根目录(默认 data) # DCTS_DB_PATH 主库路径(默认 data/dcts.db,相对 DCTS_DATA_DIR) set -euo pipefail DATA_DIR="${DCTS_DATA_DIR:-data}" DB_PATH="${DCTS_DB_PATH:-${DCTS_DATA_DIR:-data}/dcts.db}" APPLY=0 if [[ "${1:-}" == "--apply" ]]; then APPLY=1 fi run_or_echo() { # dry-run 时打印命令,--apply 时执行 if [[ $APPLY -eq 1 ]]; then eval "$1" else echo " [dry-run] $1" fi } echo "数据根目录: $DATA_DIR" echo "主库路径: $DB_PATH" echo "模式: $([[ $APPLY -eq 1 ]] && echo ' APPLY(实际执行)' || echo ' dry-run(只预览)')" echo "------------------------------------------------" moved=0 # 1. results → seeds OLD_RESULTS="${DATA_DIR}/results" NEW_SEEDS="${DATA_DIR}/seeds" if [[ -d "$OLD_RESULTS" ]]; then echo "[1/2] 发现旧目录 $OLD_RESULTS" if [[ -d "$NEW_SEEDS" ]]; then echo " ⚠️ 目标 $NEW_SEEDS 已存在!不会自动合并,请手动处理后重跑。" else run_or_echo "mv '$OLD_RESULTS' '$NEW_SEEDS'" moved=$((moved + 1)) echo " → results 重命名为 seeds" fi else echo "[1/2] 旧目录 $OLD_RESULTS 不存在,跳过" fi # 2. archive → result OLD_ARCHIVE="${DATA_DIR}/archive" NEW_RESULT="${DATA_DIR}/result" if [[ -d "$OLD_ARCHIVE" ]]; then echo "[2/2] 发现旧目录 $OLD_ARCHIVE" if [[ -d "$NEW_RESULT" ]]; then echo " ⚠️ 目标 $NEW_RESULT 已存在!不会自动合并,请手动处理后重跑。" else run_or_echo "mv '$OLD_ARCHIVE' '$NEW_RESULT'" moved=$((moved + 1)) echo " → archive 重命名为 result" fi else echo "[2/2] 旧目录 $OLD_ARCHIVE 不存在,跳过" fi # 3. DB seeds.file_path 审计字段修正(非功能性,但保持一致) echo "------------------------------------------------" if [[ -f "$DB_PATH" ]] && command -v sqlite3 >/dev/null 2>&1; then # 统计待更新的行数(results→seeds) STMT_COUNT="SELECT COUNT(*) FROM seeds WHERE file_path LIKE '%/results/%';" if [[ $APPLY -eq 1 ]]; then cnt=$(sqlite3 "$DB_PATH" "$STMT_COUNT" 2>/dev/null || echo "0") else # dry-run:尝试只读,读不到就标"无法预览" cnt=$(sqlite3 "file:${DB_PATH}?mode=ro" "$STMT_COUNT" 2>/dev/null || echo "?") fi echo "[3/3] DB seeds.file_path 含旧路径的行数: $cnt" if [[ "$cnt" != "0" && "$cnt" != "?" ]]; then # 把路径中的 /results/ 替换为 /seeds/ run_or_echo "sqlite3 \"$DB_PATH\" \"UPDATE seeds SET file_path = REPLACE(file_path, '/results/', '/seeds/') WHERE file_path LIKE '%/results/%';\"" echo " → 已修正 seeds.file_path 审计路径" fi else echo "[3/3] 跳过 DB 迁移:$DB_PATH 不存在或无 sqlite3 命令" echo " (download_seed 不读此列,不影响功能;可后续手动执行 UPDATE)" fi echo "------------------------------------------------" if [[ $APPLY -eq 1 ]]; then echo "✅ 完成:迁移了 $moved 个目录" else echo "✅ dry-run 完成。加 --apply 实际执行。" echo " ⚠️ 执行前请先停掉 server(mv 整目录 + 写 DB 需停机)。" fi