Files
railwaysystem/docs/database-v2/05_execution_contract.md
T

7.0 KiB
Raw Blame History

RailwaySystem 数据库 V2 迁移执行契约 (Execution Contract)

适用范围:数据库 V2 迁移在测试环境与未来生产环境中的正式执行规范 技术基线:KingbaseES V009R003C018 (database=training, schema=public, database_mode=mysql) 核心原则:双门禁强准入 (Gate A/B)、单文件显式事务、纯 SQL 执行器兼容、失败即刻熔断


1. 执行器与客户端兼容规范

为杜绝因客户端专有指令导致的语法中断或解析失败,物理迁移 SQL 已全面实施去客户端化:

  1. 纯标准 SQL 语法:
    • 彻底移除 \echo、\set、DELIMITER 等特定客户端(如 psql/ksql/mysql)专有元命令;
    • 进度提示统一采用 PL/pgSQL 标准内置机制:RAISE NOTICE '...';
    • 失败阻断统一采用标准异常中断:RAISE EXCEPTION '...'。
  2. 多客户端适配兼容性:
    • 支持通过 Kingbase 原生命令行工具 ksql 执行:ksql -U kingbase -d training -f xxx.sql;
    • 支持通过通用数据库客户端(如 DBeaver、Navicat、DataGrip)以“执行脚本文件”模式执行;
    • 支持通过自动化运维流水线或 JDBC Runner 顺序执行。

2. 迁移编排流水线与事务边界

迁移必须严格按照以下阶段顺序串行执行。任何前置 Gate 失败或 Stage 报错,必须立即停止,绝对禁止跳步骤继续!

graph TD
    GateA[Gate A: 000_tx_capability_probe.sql] -->|PASS| GateB[Gate B: 000_preflight.sql]
    GateB -->|PASS| S1[Stage 1: 001_backup_current_schema.sql]
    S1 --> S2[Stage 2: 002_create_new_tables.sql]
    S2 --> S3[Stage 3: 003_alter_master_tables.sql]
    S3 --> S4[Stage 4: 004_rebuild_business_tables.sql]
    S4 --> S5[Stage 5: 005_constraints.sql]
    S5 --> S6[Stage 6: 006_indexes.sql]
    S6 -.->|跳过字典初始化| S7[Stage 7: 008_migrate_teacher.sql]
    S7 --> S8[Stage 8: 009_drop_legacy_score.sql]
    S8 --> S9[Stage 9: 010_verify.sql]
    S9 --> Done[迁移完成 交付测试验收]

详细阶段契约表

阶段 脚本文件 事务边界 失败处理与影响
Gate A 000_tx_capability_probe.sql 探针显式事务 强阻断:实证探测实例 DDL 回滚能力。若表残留立即抛出异常并中止,严禁进入后续阶段
Gate B 000_preflight.sql 纯只读骨架断言 强阻断:集合差集校验 14旧表PK、24旧表FK、7组UNIQUE、6个identity主键、9触发器与行数基线,任何不符立即中止
Stage 1 001_backup_current_schema.sql BEGIN ... COMMIT 强阻断:全量快照 14 张表至 bak_v1_*;若已存在备份表则阻断;失败全单回滚
Stage 2 002_create_new_tables.sql BEGIN ... COMMIT 创建 V2 新增 8 张表;严禁 IF NOT EXISTS;失败事务回滚,新表全部撤销
Stage 3 003_alter_master_tables.sql BEGIN ... COMMIT 调整 8 张主数据表;移除旧触发器与阻断外键,添加 V2 新列;失败事务回滚
Stage 4 004_rebuild_business_tables.sql BEGIN ... COMMIT 断言 0 行后重构 5 张业务表;失败事务回滚,原表结构保持不变
Stage 5 005_constraints.sql BEGIN ... COMMIT 集中注入 13 组 UNIQUE、26 组 FK (NO ACTION)、9 组 CHECK;失败事务回滚
Stage 6 006_indexes.sql BEGIN ... COMMIT 创建外键索引、排课多维复合索引及双非空部分唯一索引;失败事务回滚
- 007_dicts.sql - 【本迁移流水线跳过不执行】 业务字典留待应用接口及权限配置阶段接入
Stage 7 008_migrate_teacher.sql BEGIN ... COMMIT 迁移并断言教师 1 行数据,固化 NOT NULL,安全清理旧列;失败事务回滚
Stage 8 009_drop_legacy_score.sql BEGIN ... COMMIT 断言 0 行后下线旧表 train_score_info;失败事务回滚,旧表完好保留
Stage 9 010_verify.sql 纯只读深度断言 强阻断:定义级全量验收 21 表、UNIQUE 列清单、FK NO ACTION、CHECK 表达式、12 Identity、默认值及系统表零受损

3. 已冻结的核心架构决策 (技术负责人正式拍板)

在数据库 V2 迁移及后续业务开发中,以下两项设计原则已作为已冻结架构决策执行:

决策 A:排课与住宿并发控制

  • 决策结论:一期绝不引入外部排课引擎或复杂时间区间调度框架。
  • 技术实现:
    1. 数据库层面配置针对性复合检索索引(idx_lesson_teacher_time, idx_lesson_classroom_time, idx_lesson_site_time);
    2. 业务层面由排课与住宿分配 Service 在单个本地事务内执行区间交叉检索;
    3. 必要时使用 SELECT ... FOR UPDATE 悲观锁锁定宿位或教师日历,保障并发一致性。

决策 B:跨培训班核心业务一致性 (防串班)

  • 决策结论:绝不为了防止串班而在考勤、成绩、自主学习时长等细粒度业务表冗余增加 plan_id 反范式列,严格保持数据库 V2 的 3NF 规范化设计。
  • 技术实现: 由应用层业务 Service 在写入和处理业务时强制校验一致性链条:
    • checkin.enrollment.plan_id = lesson.plan_course.plan_id (考勤打卡班级一致)
    • student_score.enrollment.plan_id = score_item.plan_id (成绩录入班级一致)
    • 当 score_item.plan_course_id IS NOT NULL 时,score_item.plan_id = plan_course.plan_id
    • study_duration.enrollment.plan_id = plan_course.plan_id (学习记录班级一致) 任何不一致均由 Service 抛出业务异常阻断入库。

4. 失败处理与应急回滚规范

  1. 单点失败即刻熔断:
    • 若流水线中任何一个脚本执行报错,严禁跳过该步骤继续执行后续脚本!
    • 单文件具备 BEGIN ... COMMIT,当前失败脚本的所有物理改动会自动回滚撤销。
  2. 应急回滚调用准则:
    • 若在 Stage 2 ~ Stage 8 中途发生不可调和的异常,必须立即暂停,并由 DBA 评估调用 rollback/ 脚本;
    • 回滚流水线严格按照:001_rollback_new_tables.sql -> 002_rollback_modified_tables.sql -> 003_restore_legacy_score.sql 倒序执行;
    • 回滚完毕后,必须运行 000_preflight.sql 校验是否完全恢复至 Phase 0.5 精确基线。