Files
DCTS/docs/database.md
T
fmq 1bfa240cb0 feat(all): 源精度命名体系、工作流可观测台、节点停用管理与白名单归档
核心变更:

  1. GridAxisValue 源精度命名
     - 新增 GridAxisValue 类型,携带 f64 数值 + YAML 源书写文本(Deref 透明兼容算术)
     - config.rs 绕过 serde_yaml 归一化,逐 token 捕获轴值原文(logg: 5.0 → g5.0)
     - runner/executor/scheduler 全链路改用 DB TEXT 列权威 point_name,
       修复 REAL 列回读丢精度导致的 model_name 错配

  2. 工作流执行可观测台
     - 新增 stats/progress/points 三组 API(进度时间序列、经验速率 ETA、
       停滞预警、逐点明细分页、收敛性热力图数据)
     - 新增 workflow_progress_snapshots 表 + tasks/grid_points 耗时列
     - runner 携带 last_iter/worst_depth/n_depths 进 conv.json
     - 前端新增 hash 路由、工作流详情页(概览/网格点/收敛分析三 Tab)、YAML 编辑器

  3. 节点停用/启用管理
     - 新增 disabled 状态 + disable/enable API;停用节点保持心跳但停止分发,
       worker 空闲待命而非退出;移除 revoke API,token 失效统一走重发覆盖;
       移除 host_name 字段

  4. 白名单结果归档
     - 新增 result_filter 模块,只归档有语义产物,丢弃 Tlusty 中间单元(~2MB/模型)
     - executor 原子写入归档 + 200 点 LRU 上限

  5. 历史数据导入
     - sync_seeds 重写为 import_results:经 /admin/import_seed 标记 converged +
       按新版命名迁移产物树

  6. 部署与目录重规划
     - data/results→seeds、data/archive→result + migrate_data_dirs.sh
     - deploy.sh 增强(SSH 复用、Profile、远程 env);Dockerfile 瘦身

  7. 文档同步更新 api/database/architecture/deployment
2026-07-31 01:34:05 +08:00

132 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DCTS 数据库设计 (Database Schema)
> DCTS 采用轻量级、零配置、高并发安全的 **SQLite** 双数据库架构:主状态库 `dcts.db` 存储网格结构与历史记录;队列库 `dcts_queue.db` 由 `mq` 驱动管理原子任务状态机。
---
## 1. 数据库分库架构
```mermaid
erDiagram
WORKFLOWS ||--o{ GRID_POINTS : contains
GRID_POINTS ||--o{ TASKS : logs
NODES ||--o{ TASK_QUEUE : executes
subgraph PrimaryDB ["主数据库 (dcts.db)"]
WORKFLOWS {
string name PK
string description
text config_yaml
string status
datetime created_at
datetime updated_at
}
GRID_POINTS {
string name PK
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
}
TASKS {
string task_id PK
string point_name FK
string node_id
string task_type
string status
double max_relc
integer retry_count
datetime created_at
}
NODES {
string node_id PK
integer max_slots
integer active_slots
string status
double cpu_usage
double memory_usage
datetime last_heartbeat
}
}
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`(运行中)/ 回退 `idle``running``paused`(暂停)/ `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`):按 cno_sum 分组的批次波次(调度优先级用)。
- `status` (`VARCHAR(32)`)`pending` / `queued` / `running` / `converged` / `failed`
- `attempt_count` (`INTEGER`):失败重试计数(仅观测用)。
- `success_method` (`VARCHAR(32)`):收敛时的成功手段 (`cold_run` 冷启动成功 / `seed_step` 种子步进成功)。
> **多工作流分区(per-workflow partitioning**`grid_points` 与 `task_queue` 均按 `workflow_name` 隔离。
> 调度、状态更新、stale 重投、`stop_workflow` 重置都限定在单个工作流内,互不影响。
> 历史旧库(无 `workflow_name` 列)在启动时自动迁移:表重建为复合唯一结构,旧行 `workflow_name`
> 标记为 `__legacy__`,不干扰新工作流查询。
### 2.3 `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`
### 2.4 `task_queue` (分布式任务队列表 - `mq`)
驱动分布式抢占与超时重试的核心表,使用 SQLite `WAL` 模式确保高吞吐并发安全(详见 [`sqlite_queue.rs`](file:///home/fmq/program/tlusty/tl208-s54/dcts/crates/mq/src/sqlite_queue.rs#L65))。
- `task_id` (`VARCHAR(128) PRIMARY KEY`):任务 IDUUID)。
- `payload` (`TEXT NOT NULL`):序列化的 [`TaskSpec`](file:///home/fmq/program/tlusty/tl208-s54/dcts/crates/common/src/models.rs)(含 point_name / params / task_type / seed_point_name / workflow_name 等)。
- `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`](file:///home/fmq/program/tlusty/tl208-s54/dcts/crates/mq/src/sqlite_queue.rs#L274) 改回 `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`](file:///home/fmq/program/tlusty/tl208-s54/dcts/crates/mq/src/sqlite_queue.rs#L145))。