7.0 KiB
7.0 KiB
RailwaySystem 数据库 V2 迁移执行契约 (Execution Contract)
适用范围:数据库 V2 迁移在测试环境与未来生产环境中的正式执行规范 技术基线:KingbaseES V009R003C018 (
database=training,schema=public,database_mode=mysql) 核心原则:双门禁强准入 (Gate A/B)、单文件显式事务、纯 SQL 执行器兼容、失败即刻熔断
1. 执行器与客户端兼容规范
为杜绝因客户端专有指令导致的语法中断或解析失败,物理迁移 SQL 已全面实施去客户端化:
- 纯标准 SQL 语法:
- 彻底移除
\echo、\set、DELIMITER等特定客户端(如 psql/ksql/mysql)专有元命令; - 进度提示统一采用 PL/pgSQL 标准内置机制:
RAISE NOTICE '...'; - 失败阻断统一采用标准异常中断:
RAISE EXCEPTION '...'。
- 彻底移除
- 多客户端适配兼容性:
- 支持通过 Kingbase 原生命令行工具
ksql执行:ksql -U kingbase -d training -f xxx.sql; - 支持通过通用数据库客户端(如 DBeaver、Navicat、DataGrip)以“执行脚本文件”模式执行;
- 支持通过自动化运维流水线或 JDBC Runner 顺序执行。
- 支持通过 Kingbase 原生命令行工具
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:排课与住宿并发控制
- 决策结论:一期绝不引入外部排课引擎或复杂时间区间调度框架。
- 技术实现:
- 数据库层面配置针对性复合检索索引(
idx_lesson_teacher_time,idx_lesson_classroom_time,idx_lesson_site_time); - 业务层面由排课与住宿分配 Service 在单个本地事务内执行区间交叉检索;
- 必要时使用
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. 失败处理与应急回滚规范
- 单点失败即刻熔断:
- 若流水线中任何一个脚本执行报错,严禁跳过该步骤继续执行后续脚本!
- 单文件具备
BEGIN ... COMMIT,当前失败脚本的所有物理改动会自动回滚撤销。
- 应急回滚调用准则:
- 若在 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 精确基线。
- 若在 Stage 2 ~ Stage 8 中途发生不可调和的异常,必须立即暂停,并由 DBA 评估调用