Flyway迁移脚本异步执行通信机制与容错设计 - 第1节
1.1 Flyway 是什么
Flyway 是一款开源的数据库迁移工具,它采用 约定优于配置 的设计哲学,将数据库 Schema 的版本变更纳入代码化、可重复、可追溯的管理流程。在微服务与分布式架构中,数据库 Schema 的变更往往成为发布瓶颈——多个服务同时修改各自数据库结构,一旦顺序错乱或脚本遗漏,就会导致生产事故。Flyway 正是为解决这一痛点而生。
核心定位:Flyway 不是 ORM 框架,也不是数据库客户端,而是一个 数据库版本控制系统,类似于 Git 管理代码文件,Flyway 管理 SQL 脚本的版本与执行顺序。
1.1.1 适用场景
- 持续集成/持续交付(CI/CD):将数据库变更与应用程序代码一同构建、测试、部署。
- 多环境一致性:开发、测试、预发、生产环境执行完全相同的迁移脚本,消除环境差异。
- 团队协作:多人并行开发时,通过版本号自动合并迁移顺序,避免冲突。
- 回滚与修复:支持可重复迁移和撤销迁移(需付费版),快速修复 Schema 问题。
1.2 核心概念
理解 Flyway 必须掌握三个核心概念:Migration(迁移脚本)、Schema History Table(Schema 历史表)、版本控制原理。下面通过表格和图示逐一说明。
1.2.1 Migration(迁移脚本)
Migration 是描述数据库变更的脚本文件,通常以 SQL 或 Java 编写。Flyway 根据命名约定自动识别脚本的版本号、描述和类型。
| 脚本类型 | 命名格式 | 示例 | 执行特点 |
|---|---|---|---|
| 版本化迁移 | V<版本号>__<描述>.sql |
V1.0.1__create_user_table.sql |
每个版本只执行一次,按版本号升序执行 |
| 可重复迁移 | R__<描述>.sql |
R__grant_permissions.sql |
每次内容变更(checksum 变化)时重新执行 |
| 撤销迁移 | U<版本号>__<描述>.sql |
U1.0.1__drop_user_table.sql |
需 Flyway Teams 版支持,用于回滚 |
| Java 迁移 | 实现 JavaMigration 接口 |
V2__MigrateData.java |
适合复杂数据迁移或调用外部 API |
命名规范提示:版本号使用
. 分隔的数字,如 1.0.1,Flyway 按 数值顺序 而非字符串顺序排序,因此 V1.10 会排在 V1.9 之后,不会出现字符串排序的“9 大于 10”问题。
1.2.2 Schema History Table(Schema 历史表)
Flyway 会在目标数据库中自动创建一张名为 flyway_schema_history 的表(可自定义表名),用于记录所有已执行的迁移脚本信息。这张表是 Flyway 实现 幂等性 和 状态追踪 的基础。
| 字段名 | 类型 | 说明 |
|---|---|---|
installed_rank |
INT | 执行顺序编号,从 1 开始递增 |
version |
VARCHAR | 迁移脚本的版本号,如 1.0.1 |
description |
VARCHAR | 脚本描述,取自文件名中的描述部分 |
script |
VARCHAR | 脚本文件名,如 V1.0.1__create_user_table.sql |
checksum |
INT | 脚本内容的 CRC32 校验和,用于检测脚本是否被修改 |
installed_by |
VARCHAR | 执行迁移的数据库用户 |
installed_on |
TIMESTAMP | 执行时间 |
execution_time |
INT | 执行耗时(毫秒) |
success |
BOOLEAN | 执行是否成功,1 表示成功,0 表示失败 |
关键约束:如果已执行的脚本内容被修改(checksum 变化),Flyway 默认会拒绝执行并报错,防止意外覆盖历史迁移。这是 Flyway 保证 迁移不可变 的核心机制。
1.3 版本控制原理
Flyway 的版本控制原理可以概括为 “扫描 → 比对 → 执行 → 记录” 四个步骤。每次运行 Flyway 时,它会执行以下流程:
- 扫描:读取配置的迁移脚本路径(如
classpath:db/migration),解析所有脚本的版本号、描述、类型和 checksum。 - 比对:查询
flyway_schema_history表,获取当前数据库已执行的迁移列表,与扫描到的脚本进行比对。 - 执行:按版本号升序执行所有 未执行 的版本化迁移,以及所有 checksum 已变化 的可重复迁移。
- 记录:每成功执行一个脚本,立即向
flyway_schema_history表插入一条记录,包括版本号、checksum、执行时间等。
下面通过一张流程图展示 Flyway 的版本控制核心逻辑:
1.3.1 版本号排序规则
Flyway 对版本号的排序采用 数值分段比较 算法,而非简单的字符串字典序。例如:
V1.0.9→V1.0.10(正确,9 < 10)V1.10→V1.9(错误,10 > 9,但字符串排序会认为 9 > 10)
Flyway 内部将版本号按 . 拆分为整数数组,逐位比较,因此 1.10 大于 1.9,符合语义预期。
1.3.2 幂等性与状态机
Flyway 通过 flyway_schema_history 表维护一个 状态机,确保迁移脚本的幂等执行:
- 未执行:脚本版本号不在历史表中 → 需要执行。
- 已执行且成功:脚本版本号在历史表中,且
success = 1→ 跳过。 - 已执行但失败:脚本版本号在历史表中,且
success = 0→ 需要修复后重新执行(需先执行flyway repair清理失败记录)。 - 可重复迁移:即使已执行,如果 checksum 发生变化,也会重新执行。
生产环境最佳实践:始终将迁移脚本纳入 Git 版本管理,与应用程序代码一同发布。CI/CD 流水线中,在部署应用前先执行
flyway migrate,确保数据库 Schema 与应用代码版本匹配。