Files
DCTS/docs/database.md
T
fmq cd370d88e7 feat(all): 任务引擎双阶段解耦、僵尸涡旋修复、动态 CPU 配额与前端详情页重构
将 TLUSTY/SYNSPEC 拆为各自独立的 enabled/policy/strategies 阶段,
以策略链自动弹栈取代单级 seed_step 布尔回退;定向修复 2026-08-02
僵尸任务涡旋事故;新增节点并发配额热调;前端详情页从 1412 行巨型
视图拆为薄控制器 + detail 子模块,并补齐工具层与单测。

引擎与调度(task_engine_decoupling_design.md)
- models.rs: 新增 StagePolicy / EngineStageConfig / TaskSpec 阶段字段、
  normalize_compat() 校正旧版在途消息策略链、failed_stage 归因
- scheduler.rs: resolve_dispatchable_chain 派发门控、
  trigger_strategy_fallback 按 failed_stage 精确弹栈;启动期
  force_recompute/skip_converged(默认)/skip_failed 三策略
- db.rs: tasks 表 +7 列持久化阶段配置;终态守卫
  (mark_grid_point_running 仅 pending/queued→running;
  record_task_report 拒绝迟到失败翻黑 converged);策略弹栈快照

僵尸涡旋修复(runbook-20260802-zombie-vortex-fix.md)
- 全链路跨库活性交叉校验:派发/claim/孤儿回收/回退统一查 MQ 队列活性,
  活则放行、死则清僵尸,结构性消除"每点重复派发"
- stop/重启卫生:清队列同步 delete_tasks_by_ids,杜绝遗留 pending 行
- report_task: 幂等吸收 + 409 区分迟到冗余结果,仅 state_changed 时回退
- MQ: NULL workflow_name 回填 __legacy__、requeue 后迟到上报被 403 竞态修复

动态 CPU 配额(dynamic_cpu_slots_design.md)
- admin.rs: POST /admin/nodes/:id/quota(Option<Option<i32>> 区分
  缺字段/显式 null);nodes 表 +admin_max_slots
- worker.rs: effective_max_slots = min(admin, physical),心跳下发原子生效

科学产物保全(tlusty_result_artifacts.md)
- runner.rs: SYNSPEC 启动前快照 fort.12/fort.14 → .bfac/.emflux 防覆盖
- 半失败点(大气收敛+光谱失败)改判 Failed 并写入 note;仅 SYNSPEC
  场景不再恒判失败;撤销归档 LRU 200 上限改为永久保留
- executor.rs: 透传 synspec_params 数值参数(此前固定 None)

前端(dashboard/)
- workflowDetail.js 1412→328 行,拆出 views/detail/{ctx,overview,
  pointsTable,parSets,pointPanel}.js,AbortController 治理监听/请求生命周期
- 删除 wfActions.js,新增 wfEnginePanel.js(双阶段三维配置编辑面板)
- 新增 utils/{errors,format,icons,polling,yamlStage}.js 纯函数模块
- 路由级动态 import 代码分割;节点配额三点菜单 + Modal 管理
- 首次引入 node:test 单测(format/polling/yamlStage/psCache,644 行)
- 系统性补齐 a11y:skip-link、ARIA、Tab 键盘漫游、toast 关闭、退出动画

文档与工具
- 新增 6 篇设计/调研:引擎解耦、动态配额、涡旋 runbook、
  光谱正确性分析、收敛判断、产物归档
- PIPELINE/design/api/database 等协同重写为分布式 C/S 架构口径
- scripts/fetch_results.sh 跨节点产物备份;import_results 按 cno 升序导入
- workflows/sdB_cno.yaml: 新增 tlusty/synspec_stage 配置块,修正 wstart 笔误
2026-08-04 23:40:52 +08:00

13 KiB
Raw Blame History

DCTS 数据库设计 (Database Schema)

DCTS 采用轻量级、零配置、高并发安全的 SQLite 双数据库架构:主状态库 dcts.db 存储网格结构与历史记录;队列库 dcts_queue.dbmq 驱动管理原子任务状态机。


1. 数据库分库架构

erDiagram
    WORKFLOWS ||--o{ GRID_POINTS : contains
    GRID_POINTS ||--o{ TASKS : logs
    WORKFLOWS ||--o{ WORKFLOW_PROGRESS_SNAPSHOTS : samples
    NODES ||--o{ TASK_QUEUE : executes
    NODES ||--o| NODE_CREDENTIALS : authenticates
    SEEDS }o--o{ GRID_POINTS : hot-starts

    subgraph PrimaryDB ["主数据库 (dcts.db)"]
        WORKFLOWS {
            string name PK
            string description
            text config_yaml
            string status
            datetime created_at
            datetime updated_at
        }
        GRID_POINTS {
            integer id PK
            string name
            string workflow_name FK
            double teff
            double logg
            double loghe
            double logc
            double logn
            double logo
            double cno_sum
            integer wave
            string status
            integer attempt_count
            string success_method
            double last_elapsed_sec
        }
        TASKS {
            string task_id PK
            string point_name
            string node_id
            string task_type
            string seed_point_name
            string status
            double max_relc
            boolean atmosphere_has_nan
            integer retry_count
            datetime created_at
            datetime started_at
            datetime completed_at
            string error_message
            string workflow_name
            boolean tlusty_enabled
            string tlusty_policy
            text tlusty_strategies
            boolean synspec_enabled
            string synspec_policy
            text synspec_strategies
            string atmosphere_ref
            double elapsed_sec
        }
        NODES {
            string node_id PK
            integer max_slots
            integer active_slots
            string status
            double cpu_usage
            double memory_usage
            datetime last_heartbeat
            string registration_secret
            integer admin_max_slots
        }
        NODE_CREDENTIALS {
            string node_id PK
            string token_hash
            datetime issued_at
            integer revoked
            string raw_token_pending
        }
        SEEDS {
            integer id PK
            string point_name UK
            double teff
            double logg
            double loghe
            double logc
            double logn
            double logo
            string file_path
            boolean is_clean
        }
        WORKFLOW_PROGRESS_SNAPSHOTS {
            integer id PK
            string workflow_name
            datetime ts
            integer total
            integer pending
            integer queued
            integer running
            integer converged
            integer failed
        }
    end

    subgraph QueueDB ["队列库 (dcts_queue.db / mq)"]
        TASK_QUEUE {
            string task_id PK
            string payload
            string status
            datetime created_at
            datetime claimed_at
            string workflow_name
            string claimed_by_node_id
            integer wave
        }
    end

2. 表结构定义 (Schema Specification)

2.1 workflows (工作流配置表)

存储用户定义的计算网格配置及整体状态。

  • name (TEXT PRIMARY KEY):工作流唯一标志(如 sdB_cno)。
  • description (TEXT):描述信息。
  • config_yaml (TEXT NOT NULL):完整的参数网格定义与物理配置 YAML 内容。
  • status (TEXT NOT NULL DEFAULT 'idle')idle(就绪)→ initializing(原子抢占加载中)→ running(运行中)/ 回退 idlerunningpaused(暂停)/ completed(全部网格点收敛)。
  • created_at / updated_at (DATETIME NOT NULL):创建 / 最后更新时间。

2.2 grid_points (网格点物理参数表)

存储多维笛卡尔积展开后的每一个独立参数点。

  • id (INTEGER PRIMARY KEY AUTOINCREMENT):自增主键。
  • name (TEXT NOT NULL):点物理唯一名(由 6 维参数生成,如 t35000_g5.5_he-1_c-2_n-2_o-2)。
  • workflow_name (TEXT NOT NULL):所属工作流。多工作流分区键——同一物理点可属于多个工作流, 与 name 共同构成复合唯一约束 UNIQUE(workflow_name, name)
  • teff, logg, loghe, logc, logn, logo (REAL NOT NULL)6 维物理参数。
  • cno_sum (REAL NOT NULL)CNO 丰度之和(调度排序用)。
  • wave (INTEGER NOT NULL DEFAULT 0):按 cno_sum 分组的批次波次(调度优先级用)。
  • status (VARCHAR(32))pending / queued / running / converged / failed
  • attempt_count (INTEGER):失败重试计数(仅观测用)。
  • success_method (VARCHAR(32)):收敛时的成功手段 (cold_run 冷启动成功 / seed_step 种子步进成功 / imported 历史导入)。
  • last_elapsed_sec (REAL):最近一次尝试的墙钟耗时(详情页 ETA 估算用,兼容旧数据回退)。

多工作流分区(per-workflow partitioninggrid_pointstask_queue 均按 workflow_name 隔离。 调度、状态更新、stale 重投、stop_workflow 重置都限定在单个工作流内,互不影响。 历史旧库(无 workflow_name 列)在启动时自动迁移:表重建为复合唯一结构,旧行 workflow_name 标记为 __legacy__,不干扰新工作流查询。

2.3 tasks (任务尝试记录表)

每次派发/尝试生成一行,记录任务的阶段配置快照与执行结果(详情页/归因/回退弹栈的数据源)。

  • task_id (VARCHAR(128) PRIMARY KEY):任务 IDUUID)。
  • point_name (TEXT NOT NULL):网格点权威名(源精度,非 params 重推)。
  • node_id (TEXT):执行节点 ID。
  • task_type (VARCHAR(32)):兼容字段,等于 tlusty_strategies[0]cold_run / seed_step),供旧节点识别。
  • seed_point_name (TEXT):种子步进时注入的近邻种子点(GET /api/seed/<name> 下载依据)。
  • status (VARCHAR(32))pending / claimed / running / completed / failed / timeout
  • max_relc (REAL):最终最大相对变化(收敛判据量)。
  • atmosphere_has_nan (BOOLEAN):最终大气是否含 >10% NaN 行(无效化标记)。
  • retry_count (INTEGER):重试计数。
  • created_at / started_at / completed_at (DATETIME):创建 / 开始 / 完成时间。
  • error_message (TEXT):失败原因(含 synspec 错误/超时等)。
  • workflow_name (TEXT):所属工作流(多工作流分区键)。
  • 阶段独立配置快照(派发时落库)tlusty_enabled (BOOLEAN)、tlusty_policy (TEXT)、 tlusty_strategies (JSON)、synspec_enabled (BOOLEAN)、synspec_policy (TEXT)、 synspec_strategies (JSON)、atmosphere_ref (TEXT,显式大气来源点)。 回退时弹 *_strategies 链首(见 task_engine_decoupling_design.md §4.2),policy/策略链取派发时快照。
  • elapsed_sec (REAL):任务墙钟耗时(详情页 ETA 估算优先用此值)。

2.4 nodes (计算节点心跳与状态表)

  • node_id (TEXT PRIMARY KEY):节点唯一标识(未指定 DCTS_NODE_ID 时自动生成 node-<uuid>)。
  • max_slots (INTEGER NOT NULL):节点声明的最大并发计算槽位数(即 DCTS_MAX_SLOTS,领用上限)。
  • active_slots (INTEGER NOT NULL DEFAULT 0):当前正在执行的任务数,随 claim 自增、report 完结自减。
  • status (VARCHAR(32) NOT NULL DEFAULT 'online')pending_approval(注册待审批)/ online(在线)/ offline(心跳超时离线)/ disabled(管理员手动停用,保持心跳但不再分发任务)/ rejected
  • cpu_usage / memory_usage (REAL NOT NULL DEFAULT 0.0):心跳上报的 CPU/内存使用率(仅观测展示用,不参与任务分发决策)。
  • last_heartbeat (DATETIME NOT NULL):最后一次心跳上报时间,后台线程据此判定 online → offline
  • registration_secret (TEXT):节点注册时下发的一次性凭据,用于 /node/check_status 取走专属 token 的二次鉴权。
  • admin_max_slots (INTEGER,可空):管理员强制并发槽位配额(NULL = 无限制,沿用物理 max_slots),经心跳响应下发给节点动态生效。

2.5 node_credentials (节点 L2 鉴权凭据表)

  • node_id (TEXT PRIMARY KEY):关联 nodes.node_id
  • token_hash (TEXT NOT NULL):节点专属 token 的 SHA-256 哈希(不存明文)。
  • issued_at (DATETIME NOT NULL):颁发时间。
  • revoked (INTEGER NOT NULL DEFAULT 0):吊销标记(重新颁发 token 时旧行吊销)。
  • raw_token_pending (TEXT):暂存待确认的明文 token(颁发流程过渡用,确认后清除)。

2.6 seeds (种子缓存池表)

全局共享的已收敛大气 .7 索引(跨工作流复用,种子步进热启动数据源)。

  • id (INTEGER PRIMARY KEY AUTOINCREMENT)。
  • point_name (TEXT UNIQUE NOT NULL):种子点权威名(源精度,与磁盘文件名一致)。
  • teff, logg, loghe, logc, logn, logo (REAL NOT NULL):6 维物理参数(种子匹配距离计算用)。
  • file_path (TEXT NOT NULL).7 大气文件在 seeds_dir 的路径。
  • is_clean (BOOLEAN NOT NULL DEFAULT 1):大气是否干净(无 NaN)——仅干净种子可被匹配(reload_seed_cache 只加载 is_clean=1)。

运行期维护内存 seed_cache + seed_indexexact_family 桶索引),find_best_seed_from_db 先查桶索引(O(1)~O(小)),未命中退化为全量 global 扫描(见 seed_finder.rs / design.md §3)。

2.7 workflow_progress_snapshots (工作流进度时间序列表)

后台定期(每分钟)为每个 running 工作流记录进度计数,供详情页进度曲线与 ETA 估算。

  • id (INTEGER PRIMARY KEY AUTOINCREMENT)。
  • workflow_name (TEXT NOT NULL)。
  • ts (DATETIME NOT NULL DEFAULT (datetime('now'))):采样时间。
  • total / pending / queued / running / converged / failed (INTEGER NOT NULL):该时刻各状态计数。

2.8 task_queue (分布式任务队列表 - mq)

驱动分布式抢占与超时重试的核心表,使用 SQLite WAL 模式确保高吞吐并发安全(详见 sqlite_queue.rs)。

  • task_id (VARCHAR(128) PRIMARY KEY):任务 IDUUID)。
  • payload (TEXT NOT NULL):序列化的 TaskSpec(含 point_name / params / task_type / seed_point_name / workflow_name / tlusty_config / synspec_config 等)。
  • status (TEXT NOT NULL)pending(就绪待领用)/ claimed(已被某 node 领用,计算中)。
  • created_at (DATETIME NOT NULL):推入队列时间(同 wave 内 FIFO 排序键)。
  • claimed_at (DATETIME):被领用的时间戳(requeue_stale_tasks 据此判定超时回投)。
  • workflow_name (TEXT):所属工作流(多工作流分区键)。
  • claimed_by_node_id (TEXT):领用方节点 IDclaim 时写入,report 阶段据此校验归属,防跨节点伪造)。
  • wave (INTEGER NOT NULL DEFAULT 0):难度波次(pop_task 出队第一排序键,低 wave 优先)。

任务完成后由 remove_task 直接从本表删除(不保留 completed/failed 终态行),历史记录落在主库 tasks 表。超时的 claimed 行由 requeue_stale_tasks 改回 pending 重投。


3. 并发与事务安全设计

  1. WAL (Write-Ahead Logging) 模式SQLite 连接自动启用 PRAGMA journal_mode=WAL;PRAGMA busy_timeout=15000;,解决多线程/多进程读写锁竞争。
  2. 连接池机制:借助 r2d2 + r2d2_sqlite 维护异步连接池,防止高并发下数据库句柄冲突。
  3. 原子 Claim 事务:任务抢占在单个 IMMEDIATE 事务内完成——先 SELECT ... WHERE status='pending' ORDER BY wave ASC, created_at ASC LIMIT 1 取队首,再 UPDATE SET status='claimed', claimed_by_node_id=?,提交后返回。事务保证同一任务不会被两个 node 同时领用;遇到 SQLITE_BUSY/LOCKED 最多退避重试 5 次(详见 pop_task)。
  4. 凭据零明文存储node_credentials.token_hash 只存 SHA-256 哈希;节点注册的一次性 registration_secret 也仅在审批前短期有效,避免数据库泄漏直接泄露有效 token。