DCTS/docs/database.md
Asfmq b91f1e4fa5 feat(server,dashboard): 引入多工作流数据隔离、安全中间件与前端 ESM 模块化重构
- server: 实现按 workflow_name 的多工作流数据隔离与旧数据库平滑迁移机制
- server: 新增 API Key 认证(auth)、限流中间件(rate_limit)与运维备份接口(admin)
- server: 统一 AppError 错误处理体系,重构调度器 scheduler 支持工作流级重置与抢占
- node: 节点 ID 缺失时自动生成随机 UUID,原生支持 `docker compose --scale node=N` 动态扩容
- dashboard: 前端模块化重构(state/api/components),升级 CSS 变量设计系统与 Toast 通知
- docker/docs: 更新 /healthz 健康检查、部署脚本 IP 配置及数据库设计文档
2026-07-28 21:54:02 +08:00

5.1 KiB
Raw Blame History

DCTS 数据库设计 (Database Schema)

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


1. 数据库分库架构

erDiagram
    WORKFLOWS ||--o{ GRID_POINTS : contains
    GRID_POINTS ||--o{ TASK_HISTORY : logs
    NODES ||--o{ TASK_QUEUE : executes
    
    subgraph PrimaryDB ["主数据库 (dcts.db)"]
        WORKFLOWS {
            string name PK
            string description
            text yaml_config
            string status
            datetime created_at
        }
        GRID_POINTS {
            string point_id PK
            string workflow_name FK
            double teff
            double logg
            double he_abund
            double c_abund
            double n_abund
            double o_abund
            string status
            datetime updated_at
        }
        TASK_HISTORY {
            string id PK
            string point_id FK
            string node_id
            boolean success
            text conv_info_json
            datetime duration_sec
        }
        NODES {
            string node_id PK
            string hostname
            integer cpu_cores
            string status
            datetime last_heartbeat
        }
    end

    subgraph QueueDB ["队列库 (dcts_queue.db / mq)"]
        TASK_QUEUE {
            string task_id PK
            string workflow_name
            string payload_json
            string status
            string assigned_node
            integer retry_count
            datetime claimed_at
        }
    end

2. 表结构定义 (Schema Specification)

2.1 workflows (工作流配置表)

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

  • name (VARCHAR(64) PRIMARY KEY):工作流唯一标志(如 sdB_cno)。
  • description (TEXT):描述信息。
  • yaml_config (TEXT):完整的参数网格定义与物理配置 YAML 内容。
  • status (VARCHAR(32)):状态:idle / running / paused / completed
  • created_at (DATETIME DEFAULT CURRENT_TIMESTAMP):创建时间。

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

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

  • node_id (VARCHAR(64) PRIMARY KEY):节点唯一标识。
  • hostname (VARCHAR(128)):节点主机名或 IP。
  • cpu_cores (INTEGER):节点 CPU 核心数。
  • status (VARCHAR(32))online / offline / busy
  • last_heartbeat (DATETIME):最后一次心跳上报时间。

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

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

  • task_id (VARCHAR(128) PRIMARY KEY):任务 ID。
  • workflow_name (VARCHAR(64)):工作流。
  • payload_json (TEXT):任务所含参数 payload。
  • status (VARCHAR(32))pending(就绪) / running(计算中) / completed(完成) / failed(失败)。
  • assigned_node (VARCHAR(64)):当前抢占该任务的节点 ID。
  • retry_count (INTEGER DEFAULT 0):失败或超时重发次数。
  • claimed_at (DATETIME):抢占时间戳(用于超时释放判定)。

3. 并发与事务安全设计

  1. WAL (Write-Ahead Logging) 模式SQLite 连接自动启用 PRAGMA journal_mode=WAL;PRAGMA busy_timeout=5000;,解决多线程/多进程读写锁竞争。
  2. 连接池机制:借助 r2d2 + r2d2_sqlite 维护异步连接池,防止高并发下数据库句柄冲突。
  3. 原子 Claim 事务:任务抢占在单个 SQLite 事务中完成(UPDATE task_queue SET status='running', assigned_node=? WHERE status='pending' ... LIMIT 1),保证绝对防重领。