3. Flyway 核心概念:迁移、校验、基线、撤销与重复迁移
Flyway 作为数据库版本控制工具,其核心操作围绕五个关键概念展开。理解这些概念是设计可靠迁移架构的基础。本章将逐一剖析每个概念的定义、触发时机、适用场景及最佳实践。
3.1 迁移(Migration)
迁移是 Flyway 管理数据库变更的基本单元,本质是一个包含 SQL 或 Java 代码的版本化文件。Flyway 通过扫描指定路径下的迁移文件,按版本号顺序依次执行,从而将数据库从当前状态演进到目标状态。
迁移分为两种类型:
| 类型 | 命名模式 | 特点 | 典型场景 |
|---|---|---|---|
| 版本化迁移 | V<版本号>__<描述>.sql |
每个版本仅执行一次,不可重复执行 | DDL 变更、新增表、修改字段 |
| 重复迁移 | R__<描述>.sql |
每次校验时重新执行,内容可覆盖 | 视图、存储过程、函数、物化视图 |
命名规范要点:
- 版本号建议使用整数递增(如
V1__init.sql、V2__add_users.sql),避免使用小数点导致排序混乱。 - 描述部分使用下划线分隔单词,保持语义清晰。
- 迁移文件一旦提交到版本控制,禁止修改内容,否则会导致校验失败。
3.2 校验(Validate)
校验是 Flyway 确保数据库状态与迁移历史一致性的核心机制。每次执行 flyway migrate 或 flyway validate 命令时,Flyway 会对比已应用的迁移文件与当前文件系统中的迁移文件,检测是否存在篡改、缺失或版本冲突。
校验规则包括:
- 校验和(Checksum)匹配:对已执行的迁移文件重新计算校验和,与
flyway_schema_history表中记录的校验和对比。不一致则报错。 - 版本唯一性:检查所有迁移文件的版本号是否重复。
- 描述一致性:已执行迁移的描述必须与文件系统中的描述一致。
- 迁移顺序:确保文件系统中的迁移版本顺序与历史记录中的执行顺序一致。
常见校验失败场景:
- 开发人员修改了已提交的迁移文件内容。
- 多人同时提交了相同版本号的迁移文件。
- 迁移文件被删除或重命名。
3.3 基线(Baseline)
基线用于将 Flyway 引入一个已有数据库实例。当数据库已存在部分表或数据时,通过设置基线版本,Flyway 会将该版本标记为“已应用”,从而跳过对已有结构的迁移,只管理基线版本之后的变更。
基线操作的核心参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
flyway.baseline-version |
指定基线版本号,该版本及之前的迁移被视为已执行 | 1 |
flyway.baseline-description |
基线版本的描述信息 | Baseline |
flyway.baseline-on-migrate |
当目标数据库非空且无历史表时,自动执行基线 | false |
基线最佳实践:
- 在项目初期就引入 Flyway,避免后期需要基线操作。
- 基线版本号应低于第一个迁移文件的版本号,例如基线设为
0,第一个迁移从V1__开始。 - 执行基线前,务必确认数据库当前状态与基线描述一致,避免状态漂移。
3.4 撤销(Undo)
撤销操作用于回滚已执行的版本化迁移。Flyway 通过执行与迁移文件对应的撤销文件(命名模式为 U<版本号>__<描述>.sql)来撤销变更。撤销文件需要开发者手动编写,Flyway 不会自动生成。
撤销的局限性:
- 非默认功能:Flyway Teams 版(商业版)才支持撤销,社区版不提供此功能。
- 手动维护成本高:每个迁移文件都需要对应的撤销文件,且撤销逻辑必须精确还原。
- 不推荐用于生产环境:撤销可能导致数据丢失或约束冲突,官方建议使用向前迁移(创建新的迁移来修复问题)替代撤销。
撤销 vs 向前迁移:
| 对比维度 | 撤销(Undo) | 向前迁移(Forward Migration) |
|---|---|---|
| 安全性 | 低,可能丢失数据 | 高,保留完整变更历史 |
| 维护成本 | 高,需维护成对文件 | 低,只需新增迁移 |
| 团队协作 | 易冲突,版本线复杂 | 线性演进,清晰可控 |
| Flyway 版本 | 仅 Teams 版 | 所有版本 |
3.5 重复迁移(Repeatable Migration)
重复迁移是一种特殊类型的迁移,其文件命名以 R__ 开头,不包含版本号。每次执行 flyway migrate 时,如果重复迁移文件的内容(校验和)发生变化,Flyway 会重新执行该迁移。
重复迁移的典型用途:
- 视图(View):视图定义经常需要调整,使用重复迁移可以随时更新。
- 存储过程(Stored Procedure):业务逻辑变更时,直接修改迁移文件即可。
- 函数(Function):与存储过程类似,适合频繁迭代。
- 物化视图(Materialized View):刷新逻辑或查询结构调整。
- 参考数据(Reference Data):需要定期更新的静态数据。
重复迁移执行顺序:
- Flyway 先执行所有未应用的版本化迁移(按版本号升序)。
- 然后执行所有校验和发生变化的重复迁移(按文件名排序)。
- 重复迁移的执行顺序在
flyway_schema_history表中记录为installed_rank,但版本号字段为空。
3.6 核心概念关系总结
五个核心概念在 Flyway 迁移生命周期中相互配合,形成完整的数据库版本管理闭环:
| 概念 | 触发时机 | 核心作用 | 依赖关系 |
|---|---|---|---|
| 迁移 | migrate 命令 | 执行数据库变更 | 校验通过后执行 |
| 校验 | migrate / validate 命令 | 确保迁移文件未被篡改 | 依赖历史表记录 |
| 基线 | baseline 命令 | 初始化已有数据库 | 在首次 migrate 前执行 |
| 撤销 | undo 命令(Teams 版) | 回滚版本化迁移 | 依赖对应的撤销文件 |
| 重复迁移 | migrate 命令(校验和变化时) | 管理可重复变更对象 | 在版本化迁移之后执行 |
架构设计建议:
- 将 DDL 变更(建表、加字段)放在版本化迁移中,确保每个变更可追溯。
- 将视图、存储过程等逻辑对象放在重复迁移中,降低维护成本。
- 在 CI/CD 流水线中强制开启校验,防止篡改历史迁移文件。
- 生产环境禁用撤销,使用向前迁移策略处理回滚需求。