26 KiB
26 KiB
迁移管理
**本文引用的文件** - [GenerateBusinessMigrations.java](file://fms-api/config/migrations/tools/GenerateBusinessMigrations.java) - [RunBusinessMigrations.java](file://fms-api/config/migrations/tools/RunBusinessMigrations.java) - [VerifyBusinessMigration.java](file://fms-api/config/migrations/tools/VerifyBusinessMigration.java) - [ApplySimpleModuleRestore.java](file://fms-api/config/migrations/tools/ApplySimpleModuleRestore.java) - [016_create_base_tables.sql](file://fms-api/config/migrations/016_create_base_tables.sql) - [035_restore_simple_module_tree.sql](file://fms-api/config/migrations/035_restore_simple_module_tree.sql) - [G3HD.properties](file://fms-api/config/dbconfigs/G3HD.properties) - [G3HY2025.properties](file://fms-api/config/dbconfigs/G3HY2025.properties) - [application.yaml](file://fms-api/src/main/resources/application.yaml) - [OrgDataSourceFactory.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDataSourceFactory.java) - [OrgRoutingDataSource.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgRoutingDataSource.java) - [OrgDatabaseProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/database/OrgDatabaseProperties.java)目录
简介
本文件为 FMS 数据库迁移管理系统的权威文档,聚焦于版本化迁移工具的使用方法与最佳实践。仓库采用“按编号排序的 SQL 迁移脚本 + Java 工具类”的组合方式,实现业务表结构的生成、执行、验证与模块恢复等关键能力。尽管未集成 Flyway 框架,但通过严格的命名规范、顺序执行和校验机制,实现了与 Flyway 类似的版本控制与可追溯性目标。
项目结构
FMS 的迁移相关资产集中在 fms-api 模块下:
- 迁移脚本目录:config/migrations/*.sql(按数字前缀排序)
- 迁移工具类:config/migrations/tools/*.java
- 数据库配置:config/dbconfigs/*.properties(多环境/多库)
- 运行时配置:src/main/resources/application.yaml(连接池、路径等)
- 多数据源路由:src/main/java/cn/g3soft/fmsapi/database/*(运行时按组织切换数据源)
graph TB
A["应用配置<br/>application.yaml"] --> B["连接池与数据源工厂<br/>OrgDataSourceFactory.java"]
B --> C["动态数据源管理器<br/>OrgRoutingDataSource.java"]
D["迁移脚本目录<br/>config/migrations/*.sql"] --> E["运行器<br/>RunBusinessMigrations.java"]
D --> F["生成器<br/>GenerateBusinessMigrations.java"]
D --> G["校验器<br/>VerifyBusinessMigration.java"]
D --> H["模块恢复器<br/>ApplySimpleModuleRestore.java"]
I["数据库配置<br/>G3HD.properties / G3HY2025.properties"] --> E
I --> F
I --> G
I --> H
图表来源
- application.yaml:10-26
- OrgDataSourceFactory.java:15-50
- OrgRoutingDataSource.java:11-27
- RunBusinessMigrations.java:14-55
- GenerateBusinessMigrations.java:97-125
- VerifyBusinessMigration.java:32-55
- ApplySimpleModuleRestore.java:12-44
章节来源
核心组件
- GenerateBusinessMigrations:从旧系统元数据读取并生成“仅结构”的业务迁移脚本,输出到 config/migrations 目录,供后续执行与验证。
- RunBusinessMigrations:按固定顺序执行一组已审阅的迁移脚本,并在完成后输出目录统计信息。
- VerifyBusinessMigration:对已执行的迁移结果进行只读校验,包括表存在性、主键、类型、视图刷新等。
- ApplySimpleModuleRestore:将模块模型恢复到简化树形结构,支持 --verify-only 模式,事务内分批执行 GO 分隔的批,失败自动回滚。
章节来源
- GenerateBusinessMigrations.java:22-125
- RunBusinessMigrations.java:12-55
- VerifyBusinessMigration.java:19-55
- ApplySimpleModuleRestore.java:11-44
架构总览
迁移流程由“生成 -> 执行 -> 验证/恢复”构成闭环:
- 生成阶段:从旧库读取元数据,过滤排除表/视图,映射字段类型与约束,输出分域迁移脚本与验证脚本。
- 执行阶段:按编号顺序执行一组受控的迁移脚本,确保幂等与事务边界。
- 验证阶段:检查生成的表是否空、主键是否符合约定、ID 列类型是否为 bigint、遗留类型是否被清理、视图是否可刷新。
- 恢复阶段:在事务中执行模块树恢复脚本,支持预检与回滚。
sequenceDiagram
participant Dev as "开发者"
participant Gen as "GenerateBusinessMigrations"
participant Exec as "RunBusinessMigrations"
participant Ver as "VerifyBusinessMigration"
participant DB as "FMS 数据库"
Dev->>Gen : 运行生成器(读取旧库元数据)
Gen-->>DB : 查询表/视图/列信息
Gen-->>Dev : 输出迁移脚本(016..021, verify_business_schema.sql)
Dev->>Exec : 执行受控迁移列表
Exec->>DB : 依次执行SQL脚本(事务/幂等)
Exec-->>Dev : 输出APPLIED/CATALOG日志
Dev->>Ver : 运行校验器
Ver->>DB : 检查表/主键/类型/视图
Ver-->>Dev : PASS|catalog|...
图表来源
- GenerateBusinessMigrations.java:97-125
- RunBusinessMigrations.java:24-55
- VerifyBusinessMigration.java:32-55
详细组件分析
生成器:GenerateBusinessMigrations
- 功能要点
- 读取旧库元数据,过滤排除表/视图集合,按领域拆分生成脚本(基础资料、合同与文件、业务单据、财务、OA)。
- 生成视图脚本时,会移除遗留复数 ID 字段并修正语义化字段名。
- 生成验证脚本,包含期望的表/视图数量与常见不一致项检测。
- 关键策略
- 字段类型映射:统一时间类型为 datetime2(0),数值类型使用 decimal,文本类型根据 Unicode 提示选择 nvarchar/varchar。
- 主键与唯一键:子表使用 subid,主表使用 b_id;业务编码字段添加唯一约束。
- 索引策略:对引用列与审计列外的 _id 列创建复合索引以提升查询性能。
- 安全限制:脚本开头强制校验目标数据库名为 FMS,避免误操作其他库。
flowchart TD
Start(["开始"]) --> LoadCfg["加载旧库配置"]
LoadCfg --> Connect["连接旧库"]
Connect --> ScanMeta["扫描表/视图/列元数据"]
ScanMeta --> Filter{"是否纳入生成?"}
Filter --> |否| Skip["跳过"]
Filter --> |是| MapTypes["类型映射与约束生成"]
MapTypes --> WriteDomain["按领域写入SQL"]
WriteDomain --> WriteViews["生成视图脚本"]
WriteViews --> WriteVerify["生成验证脚本"]
WriteVerify --> End(["结束"])
图表来源
- GenerateBusinessMigrations.java:97-125
- GenerateBusinessMigrations.java:128-181
- GenerateBusinessMigrations.java:183-269
- GenerateBusinessMigrations.java:336-385
- GenerateBusinessMigrations.java:470-515
- GenerateBusinessMigrations.java:567-614
章节来源
- GenerateBusinessMigrations.java:22-125
- GenerateBusinessMigrations.java:128-181
- GenerateBusinessMigrations.java:183-269
- GenerateBusinessMigrations.java:336-385
- GenerateBusinessMigrations.java:470-515
- GenerateBusinessMigrations.java:567-614
执行器:RunBusinessMigrations
- 功能要点
- 硬编码一组受控的迁移脚本列表,按顺序执行。
- 每次执行后打印 APPLIED 日志,最后输出目录统计(表/视图计数)。
- 连接前校验数据库目录名必须为 FMS。
- 注意事项
- 该工具不记录历史执行状态,因此迁移脚本需具备幂等性(如 IF NOT EXISTS)。
- 生产部署建议配合外部编排或 CI/CD 保证顺序与重试策略。
sequenceDiagram
participant U as "用户"
participant R as "RunBusinessMigrations"
participant DB as "FMS 数据库"
U->>R : 启动执行
R->>DB : 校验数据库目录名
loop 遍历迁移脚本
R->>DB : 执行SQL
DB-->>R : 成功/异常
R-->>U : 输出APPLIED
end
R->>DB : 查询表/视图计数
R-->>U : 输出CATALOG
图表来源
章节来源
校验器:VerifyBusinessMigration
- 功能要点
- 解析迁移脚本中的 CREATE TABLE,提取预期表集合。
- 校验每张生成表:存在且为空、主键符合约定(subid/b_id)、ID 列为 bigint、无遗留类型、无遗留复数 ID 列。
- 校验核心业务表存在且用户/模块/字段/自动码等元数据未被破坏。
- 刷新所有非系统视图,确保依赖一致。
- 输出 PASS|catalog 统计。
flowchart TD
S["开始"] --> Parse["解析迁移脚本提取表名"]
Parse --> CheckTables{"逐表校验"}
CheckTables --> Exists{"存在且为空?"}
Exists --> |否| Fail["抛出异常"]
Exists --> |是| PK{"主键正确?"}
PK --> |否| Fail
PK --> Types{"ID列类型为bigint?"}
Types --> |否| Fail
Types --> Legacy{"无遗留类型/复数ID?"}
Legacy --> |否| Fail
Legacy --> Core{"核心元数据完整?"}
Core --> |否| Fail
Core --> Views{"刷新视图"}
Views --> Done["输出PASS"]
图表来源
- VerifyBusinessMigration.java:21-55
- VerifyBusinessMigration.java:70-88
- VerifyBusinessMigration.java:90-107
- VerifyBusinessMigration.java:109-135
- VerifyBusinessMigration.java:163-226
章节来源
- VerifyBusinessMigration.java:19-55
- VerifyBusinessMigration.java:70-88
- VerifyBusinessMigration.java:90-107
- VerifyBusinessMigration.java:109-135
- VerifyBusinessMigration.java:163-226
模块恢复器:ApplySimpleModuleRestore
- 功能要点
- 读取指定迁移脚本(035_restore_simple_module_tree.sql),按 GO 分割为批次执行。
- 开启事务,执行成功后提交,失败则回滚。
- 支持 --verify-only 参数仅做验证。
- 内置验证逻辑:检查 s_module.b_parent_id 是否存在、s_module_page 是否存在、无效父节点数量为 0 等。
- 适用场景
- 当模块架构需要回退到简化树形结构时使用。
sequenceDiagram
participant U as "用户"
participant AR as "ApplySimpleModuleRestore"
participant DB as "FMS 数据库"
U->>AR : 传入参数(--verify-only可选)
AR->>DB : 校验数据库目录名
alt 仅验证
AR->>DB : 执行验证查询
DB-->>AR : 返回验证结果
AR-->>U : 输出PASS
else 执行恢复
AR->>DB : 开启事务
loop 按GO分割批次
AR->>DB : 执行批次
DB-->>AR : 成功/异常
end
AR->>DB : 执行验证
DB-->>AR : 通过/失败
alt 通过
AR->>DB : 提交事务
AR-->>U : 输出APPLIED
else 失败
AR->>DB : 回滚事务
AR-->>U : 抛出异常
end
end
图表来源
- ApplySimpleModuleRestore.java:12-44
- ApplySimpleModuleRestore.java:47-83
- 035_restore_simple_module_tree.sql:1-22
章节来源
- ApplySimpleModuleRestore.java:11-44
- ApplySimpleModuleRestore.java:47-83
- 035_restore_simple_module_tree.sql:1-22
依赖关系分析
- 迁移脚本与工具类
- GenerateBusinessMigrations 依赖旧库配置(G3HY2025.properties)以读取元数据,输出迁移脚本至 config/migrations。
- RunBusinessMigrations 依赖 G3HD.properties 连接目标 FMS 库,按固定顺序执行 015..021 系列脚本。
- VerifyBusinessMigration 同样依赖 G3HD.properties,并对 016..020 系列脚本生成的表进行只读校验。
- ApplySimpleModuleRestore 依赖 G3HD.properties,执行 035 恢复脚本。
- 运行时数据源
- application.yaml 配置了 fms.database.config-dir 指向 ./config/dbconfigs,以及连接池参数。
- OrgDataSourceFactory 基于 Druid 构建数据源,启用 KeepAlive 与空闲连接探测,增强云环境稳定性。
- OrgRoutingDataSource 作为 @Primary 路由,依据当前组织上下文选择具体数据源。
graph LR
P["G3HD.properties"] --> R["RunBusinessMigrations"]
P --> V["VerifyBusinessMigration"]
P --> A["ApplySimpleModuleRestore"]
PY["G3HY2025.properties"] --> G["GenerateBusinessMigrations"]
Y["application.yaml"] --> DF["OrgDataSourceFactory"]
DF --> RD["OrgRoutingDataSource"]
图表来源
- RunBusinessMigrations.java:24-55
- VerifyBusinessMigration.java:32-55
- ApplySimpleModuleRestore.java:12-44
- GenerateBusinessMigrations.java:97-125
- application.yaml:10-26
- OrgDataSourceFactory.java:15-50
- OrgRoutingDataSource.java:11-27
章节来源
性能与一致性
- 幂等性与事务
- 迁移脚本普遍使用 IF NOT EXISTS 与 BEGIN TRANSACTION 包裹,确保重复执行安全与原子性。
- 生成器输出的脚本包含数据库名校验,防止误操作。
- 索引与查询优化
- 生成器为常用外键列创建复合索引,提升关联查询性能。
- 视图定义中移除遗留复数字段,减少不必要计算。
- 连接池与健康检查
- 连接池启用 keep-alive 与定期 ping,对抗云 NAT/防火墙回收空闲会话。
- 验证查询 SELECT 1 用于健康检查,降低连接失效风险。
- 数据一致性保障
- 校验器严格检查主键、ID 类型、遗留类型与视图依赖,确保迁移后结构一致。
- 恢复器在事务中执行,失败自动回滚,避免部分应用导致的数据不一致。
[本节提供通用指导,无需特定文件引用]
故障排查指南
- 无法在非 FMS 数据库执行
- 现象:抛出异常提示只能在 FMS 数据库执行。
- 原因:迁移脚本或工具在连接后校验 catalog 名称。
- 处理:确认配置文件指向正确的 FMS 数据库实例。
- 参考
- 生成表缺失或不为空
- 现象:校验器报告缺失生成表或生成表非空。
- 原因:迁移未执行或执行失败;或手动插入了数据。
- 处理:重新执行 RunBusinessMigrations,并确保脚本幂等;检查是否有非法数据写入。
- 参考
- 主键或 ID 类型不符合约定
- 现象:校验器报告主键不正确或 ID 列类型不是 bigint。
- 原因:迁移脚本未按要求生成或手动修改了结构。
- 处理:使用 GenerateBusinessMigrations 重新生成脚本并执行;禁止手工变更结构。
- 参考
- 遗留类型或复数字段残留
- 现象:校验器报告遗留类型或复数字段仍存在。
- 原因:迁移未覆盖或脚本未清理。
- 处理:检查迁移脚本是否包含清理逻辑;必要时补充 DROP/ALTER 语句。
- 参考
- 视图不可用或依赖缺失
- 现象:视图刷新失败或引用对象不存在。
- 原因:基础表/列变更导致视图失效。
- 处理:重新执行迁移后运行校验器,它会尝试刷新视图;若仍失败,检查视图定义与依赖。
- 参考
- 模块恢复失败
- 现象:ApplySimpleModuleRestore 抛出异常或验证失败。
- 原因:前置条件不满足(如缺少 s_module_page、b_parent_id 不存在、管理员用户缺失等)。
- 处理:先执行必要的前置迁移;使用 --verify-only 预检;查看错误号定位问题。
- 参考
章节来源
- RunBusinessMigrations.java:39-41
- VerifyBusinessMigration.java:47-49
- ApplySimpleModuleRestore.java:26-44
- VerifyBusinessMigration.java:70-88
- VerifyBusinessMigration.java:163-226
- VerifyBusinessMigration.java:109-125
- 035_restore_simple_module_tree.sql:11-30
结论
FMS 的迁移体系通过“编号脚本 + Java 工具类”的方式,实现了与 Flyway 类似的可追溯、可验证的版本化管理。其优势在于:
- 明确的执行顺序与受控脚本集,降低误操作风险。
- 强一致的校验环节,确保结构、类型与依赖的正确性。
- 灵活的生成与恢复能力,便于从旧系统迁移与架构回退。 在生产环境中,建议结合 CI/CD 流水线,将生成、执行、校验步骤固化为自动化任务,并保留完整的日志与产物,以便审计与回溯。
[本节为总结性内容,无需特定文件引用]
附录
迁移脚本命名规范与版本控制
- 命名规则:以三位数字前缀加描述性名称,例如 016_create_base_tables.sql。
- 版本控制:数字前缀决定执行顺序;新增脚本应插入合适位置,避免打乱既有顺序。
- 幂等性:脚本需支持重复执行,建议使用 IF NOT EXISTS、IF OBJECT_ID 判断与事务包裹。
- 参考示例
章节来源
执行顺序与依赖管理
- 受控执行:RunBusinessMigrations 维护固定脚本列表,确保依赖顺序。
- 依赖声明:新脚本如需依赖已有表/视图,应在脚本中显式检查存在性。
- 参考
章节来源
回滚机制与数据一致性
- 回滚策略:当前体系未提供自动回滚;建议在发布前充分验证,并通过备份与快照控制风险。
- 事务保护:迁移脚本与恢复脚本均使用事务,失败自动回滚。
- 参考
章节来源
迁移环境配置与多数据库支持
- 环境配置:通过 config/dbconfigs/*.properties 指定不同环境的数据库连接信息。
- 多数据源:运行时通过 OrgDataSourceFactory 与 OrgRoutingDataSource 按组织维度切换数据源。
- 参考
章节来源
- G3HD.properties:1-5
- G3HY2025.properties:1-5
- application.yaml:10-26
- OrgDataSourceFactory.java:15-50
- OrgRoutingDataSource.java:11-27
生产环境部署注意事项
- 权限与安全:确保迁移账号具备必要的 DDL/DML 权限,最小权限原则。
- 备份与回滚:部署前备份数据库;准备回滚方案(快照/备份恢复)。
- 监控与日志:收集迁移执行日志与校验结果,设置告警阈值。
- 连接池调优:根据负载调整连接池参数,保持 keep-alive 与验证查询开启。
- 参考
章节来源