1. Flyway 概述:Flyway 是什么、核心价值、版本迁移的基本概念与工作流程

1.1 什么是 Flyway

Flyway 是一款开源的数据库版本控制工具,采用 “约定优于配置” 的设计哲学,通过版本化的 SQL 脚本或 Java 迁移类,对数据库 Schema 进行可重复、可追溯的变更管理。它本质上是一个 数据库 Schema 的 Git,让每一次 DDL/DML 变更都像代码提交一样被记录、校验和回放。

核心定位:Flyway 不是 ORM 框架的附属品,而是一个独立于应用框架的数据库 CI/CD 组件,支持 Spring Boot、Quarkus、Micronaut 以及纯 Java/命令行环境。
维度 说明
工具类型 数据库 Schema 版本管理工具(Database Migration Tool)
输入形式 SQL 脚本(.sql)或 Java 迁移类(Java-based Migration)
状态追踪 在目标数据库中自动创建 flyway_schema_history 元数据表
运行模式 命令行、Java API、Maven/Gradle 插件、Spring Boot 自动配置
支持数据库 MySQL、PostgreSQL、Oracle、SQL Server、MariaDB、H2 等 20+ 种

1.2 核心价值

  • 可重复性:开发、测试、生产环境执行同一套迁移脚本,消除“在我机器上能跑”的 Schema 差异。
  • 可追溯性:每次迁移的校验和(Checksum)、执行时间、执行人、脚本内容全部记录在 flyway_schema_history 表中,形成完整的审计链路。
  • 幂等性:通过版本号唯一性保证同一脚本不会重复执行;失败时支持清理(Clean)和修复(Repair)操作。
  • CI/CD 集成:可嵌入构建流水线,在应用部署前自动完成 Schema 升级,避免人工漏跑或错跑脚本。
  • 团队协作:多人并行开发时,通过版本号冲突检测和基线(Baseline)机制,减少 Schema 合并冲突。
实践建议:在微服务架构中,每个服务独立维护自己的 Flyway 迁移目录,避免跨服务的 Schema 耦合。Flyway 只管理本服务对应的数据库 Schema,不处理跨库分布式事务。

1.3 版本迁移的基本概念

概念 说明
迁移(Migration) 一次 Schema 变更的单元,可以是 SQL 脚本或 Java 类
版本号(Version) 迁移的唯一标识,格式如 1.0、2.1.3,决定执行顺序
描述(Description) 迁移的简短说明,如 create_user_table,用于日志和元数据
校验和(Checksum) 迁移内容的 SHA-256 哈希值,用于检测脚本是否被篡改
基线(Baseline) 对已有数据库打上版本标记,使 Flyway 从该版本开始管理后续迁移
撤销(Undo) 回滚指定版本的迁移(企业版功能,社区版不支持)
重复迁移(Repeatable Migration) 每次校验和变化时重新执行的迁移,适用于视图、函数、存储过程

迁移文件命名规范:

前缀 + 版本号 + 分隔符 + 描述 + 后缀

示例:
V1__create_user_table.sql
V2_1__add_email_column.sql
V3__insert_initial_data.sql
R__my_view.sql          (重复迁移,无版本号)
U1__undo_create_user_table.sql  (撤销迁移,企业版)
避坑提示:版本号不要使用纯数字如 V1、V2,建议使用语义化版本如 V1.0、V1.1,避免在版本回退或补丁时出现排序歧义。Flyway 按版本号字符串的自然排序执行,V10 会在 V9 之后执行,但 V1.10 会在 V1.9 之后执行。

1.4 工作流程

Flyway 的迁移执行遵循 “检查 → 校验 → 执行 → 记录” 的闭环流程,具体步骤如下:

  1. 扫描:Flyway 扫描配置的迁移路径(默认 classpath:db/migration),解析所有迁移文件的版本号和校验和。
  2. 校验:读取目标数据库的 flyway_schema_history 表,对比已执行迁移的校验和是否与本地文件一致。不一致则抛出异常,阻止迁移。
  3. 排序:按版本号升序排列未执行的迁移,确定执行顺序。
  4. 锁定:在集群或多实例部署场景下,通过数据库锁(或表锁)确保同一时刻只有一个实例执行迁移,避免并发冲突。
  5. 执行:依次执行每个迁移脚本。SQL 迁移在事务内执行(如果数据库支持 DDL 事务);Java 迁移由开发者控制事务边界。
  6. 记录:每个迁移执行成功后,在 flyway_schema_history 表中插入一条记录,包含版本号、描述、校验和、执行时间、脚本内容(可选)。
  7. 完成:所有待执行迁移执行完毕后,释放锁,返回迁移结果。
Flyway 版本迁移工作流程 1. 扫描迁移路径 2. 校验历史记录 3. 排序待执行迁移 4. 获取数据库锁 5. 逐版本执行迁移 6. 写入历史记录 7. 释放锁,完成 校验失败场景 • 本地校验和 ≠ 历史记录 • 已执行迁移被删除 • 版本号冲突 → 抛出异常,阻止迁移 锁机制说明 • 基于数据库表锁 • 防止多实例并发迁移 • 锁超时默认 60 秒

1.5 迁移类型对比

类型 命名模式 执行时机 典型用途
版本化迁移(Versioned) V{version}__{description}.sql 每个版本仅执行一次 建表、加字段、加索引、数据迁移
重复迁移(Repeatable) R__{description}.sql 每次校验和变化时执行 视图、函数、存储过程、物化视图
撤销迁移(Undo) U{version}__{description}.sql 手动触发撤销指定版本 回滚 DDL 变更(企业版)
Java 迁移 实现 JavaMigration 接口 按版本号顺序执行 复杂数据转换、调用外部 API、条件迁移
最佳实践:生产环境中优先使用版本化 SQL 迁移,保持迁移脚本的声明式和可读性。仅在需要复杂业务逻辑(如数据清洗、调用第三方服务)时才使用 Java 迁移。重复迁移适合管理视图和函数,避免每次修改都生成新的版本号。

1.6 元数据表结构

flyway_schema_history 表是 Flyway 的“大脑”,记录了所有迁移的执行历史。其核心字段如下:

字段名 类型 说明
installed_rank INT 执行顺序序号
version VARCHAR 迁移版本号(可空,重复迁移为空)
description VARCHAR 迁移描述
type VARCHAR 迁移类型:SQL、JDBC、SPRING_JDBC
script VARCHAR 迁移脚本名称
checksum INT 脚本内容的校验和
installed_by VARCHAR 执行迁移的数据库用户
installed_on TIMESTAMP 执行时间
execution_time INT 执行耗时(毫秒)
success BOOLEAN 是否执行成功
关键提醒:永远不要手动修改 flyway_schema_history 表。如果迁移失败需要修复,应使用 Flyway 的 repair 命令清除失败的记录,而不是直接 DELETE 或 UPDATE。手动篡改元数据会导致校验和不一致,引发后续迁移异常。