2. Flyway 核心概念:迁移、校验、基线、撤销、修复

Flyway 的运作围绕五个核心概念展开。理解这些概念是正确配置迁移脚本、避免版本混乱、实现自动化冒烟检查的前提。本章逐一拆解每个概念的定义、触发时机与工程意义。

2.1 迁移(Migration)

迁移是 Flyway 管理数据库版本变更的基本单元。每个迁移脚本对应一个版本号,Flyway 按版本号顺序依次执行,并将执行记录写入 flyway_schema_history 表。

迁移类型命名格式说明
版本化迁移(Versioned)V<版本号>__<描述>.sql每个版本只执行一次,不可重复执行
可重复迁移(Repeatable)R__<描述>.sql每次校验时若内容变更则重新执行
撤销迁移(Undo)U<版本号>__<描述>.sql回滚指定版本化迁移(需 Pro 版)
工程建议: 版本号建议使用整数或语义化版本(如 V1.0.1__add_user_table.sql),避免使用时间戳或随机字符串,确保排序可预测。
迁移脚本执行流程 扫描脚本目录 解析版本号 比对历史表 执行迁移 关键行为 • 版本化迁移:校验 checksum,已执行则跳过,未执行则按序执行 • 可重复迁移:每次校验时比对内容哈希,变更则重新执行

2.2 校验(Validate)

校验是 Flyway 确保迁移脚本与数据库状态一致性的核心机制。每次执行 flyway migrate 或 flyway validate 时触发,检查以下维度:

  • 脚本完整性: 已执行的迁移脚本是否在文件系统中被删除或修改。
  • 版本顺序: 脚本版本号是否出现跳跃、重复或降序。
  • 校验和(Checksum): 脚本内容是否被篡改(默认使用 CRC32)。
  • 描述一致性: 历史表中的描述与脚本文件名描述是否匹配。
冒烟检查关键点: 在 CI/CD 流水线中,flyway validate 应作为冒烟检查的第一步。若校验失败,立即中断流水线,避免脏数据写入生产环境。

2.3 基线(Baseline)

基线用于将已有数据库纳入 Flyway 管理,而不必从头执行所有历史迁移。执行 flyway baseline 后,Flyway 在 flyway_schema_history 表中插入一条基线记录,标记当前数据库状态。

参数默认值说明
flyway.baselineOnMigratefalse是否在迁移时自动基线化非空数据库
flyway.baselineVersion1基线版本号,低于此版本的脚本将被忽略
flyway.baselineDescriptionBaseline基线记录的描述文本
典型场景: 接手遗留项目时,数据库已有 50 张表。设置 baselineVersion=1.0,后续新脚本从 V1.1 开始,旧表状态由基线记录兜底。

2.4 撤销(Undo)

撤销迁移用于回滚已执行的版本化迁移。Flyway Pro 版支持此功能,社区版不包含。撤销脚本命名格式为 U<版本号>__<描述>.sql,与对应的 V 脚本成对出现。

  • 执行方式: flyway undo 按版本号降序撤销最近一次迁移。
  • 限制: 撤销脚本必须手动编写,Flyway 不自动生成反向 DDL。
  • 风险: 撤销可能造成数据丢失,生产环境建议优先使用前向迁移修复,而非回滚。
工程实践: 在开发/测试环境可启用撤销以快速迭代;生产环境建议关闭撤销功能,通过 flyway repair 或新增迁移脚本修复问题。

2.5 修复(Repair)

修复用于清理 flyway_schema_history 表中的异常记录,解决校验失败或迁移中断问题。执行 flyway repair 后:

  1. 删除所有失败的迁移记录(状态为 Failed 的行)。
  2. 移除已删除脚本对应的历史记录(文件系统中已不存在的脚本)。
  3. 重新对齐可重复迁移的校验和。
Repair 前后对比 修复前(异常状态) V1.0__init.sql → Success V1.1__add_index.sql → Failed V1.2__alter_table.sql → Success R__view.sql → Pending 修复后(干净状态) V1.0__init.sql → Success V1.2__alter_table.sql → Success R__view.sql → Pending (Failed 记录已删除)
使用限制: Repair 不会自动修复数据库结构,仅清理元数据表。若迁移脚本执行一半失败,需手动回滚部分 DDL 后再执行 Repair。

2.6 核心概念对比总结

概念触发命令主要作用是否修改数据库结构
迁移migrate执行版本化或可重复脚本是
校验validate检查脚本与历史表一致性否
基线baseline将已有数据库纳入管理否(仅插入记录)
撤销undo回滚指定版本迁移是
修复repair清理历史表异常记录否(仅清理元数据)