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 时,它会执行以下流程:

  1. 扫描:读取配置的迁移脚本路径(如 classpath:db/migration),解析所有脚本的版本号、描述、类型和 checksum。
  2. 比对:查询 flyway_schema_history 表,获取当前数据库已执行的迁移列表,与扫描到的脚本进行比对。
  3. 执行:按版本号升序执行所有 未执行 的版本化迁移,以及所有 checksum 已变化 的可重复迁移。
  4. 记录:每成功执行一个脚本,立即向 flyway_schema_history 表插入一条记录,包括版本号、checksum、执行时间等。

下面通过一张流程图展示 Flyway 的版本控制核心逻辑:

Flyway 版本控制核心流程 ① 扫描迁移脚本 ② 查询 flyway_schema_history ③ 比对版本与 checksum ④ 按顺序执行未迁移脚本 ⑤ 写入执行记录 关键校验点 • 版本号不能重复 • checksum 必须匹配 • 执行顺序严格升序 • 失败后自动回滚当前脚本

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 与应用代码版本匹配。

1.4 本章小结