SQL Flyway 的 sql migration 的 repeatable 与 versioned 混合使用

6次阅读

flyway 中 versioned 和 repeatable 迁移可混合使用,但需严格区分职责:versioned(如 v1.0__init.sql)一次性执行、版本递增、管理结构变更;repeatable(如 r__update_views.sql)每次校验哈希后重执行、管理视图/函数/动态数据;执行顺序为先 versioned(升序)、后 repeatable(字母序),禁止在 repeatable 中修改表结构或拆分同一功能。

SQL Flyway 的 sql migration 的 repeatable 与 versioned 混合使用

Flyway 中的 repeatableversioned 迁移可以混合使用,但需明确各自职责、执行顺序和约束条件,否则容易引发不可预期的行为(如重复执行、版本冲突、校验失败)。

两者的核心区别必须清楚

Versioned migration(带版本号,如 V1.0__init.sql): – 一次性执行,成功后记录到 flyway_schema_history 表; – 版本号严格递增,不可重复、不可跳过、不可降级; – 用于定义数据库结构(建表、改列)、初始数据(INSERT 静态配置)等“只做一次”的变更。

Repeatable migration(无版本号,以 R__ 开头,如 R__update_views.sql): – 每次 flyway migrate 都会执行(或重新执行),只要其内容哈希值变化; – 不记录独立版本行,而是以 type = 'REPEATABLE' 形式在历史表中存一条记录,并持续更新 checksum; – 适合管理视图、函数、存储过程、批量配置数据(如权限集、国家字典)等“可演进、需同步”的对象

混合使用的合理场景与推荐模式

典型组合方式:

  • Versioned 负责 DDL 基线:建库、建表、加索引、设约束;
  • Repeatable 负责逻辑封装与动态数据:视图定义、物化视图刷新逻辑、角色权限脚本、多环境通用配置表填充(如 config 表中的开关项);
  • 避免用 Repeatable 替代 Versioned 的结构变更:比如不要用 R__add_column_user_email.sql 去加字段——这绕过了版本控制,会导致协作混乱和回滚困难。

执行顺序与依赖规则

Flyway 总是按以下固定顺序执行迁移:

  1. 所有 versioned 迁移(按版本号升序);
  2. 所有 repeatable 迁移(按文件名字母序,R__a.sqlR__b.sql 前);

注意:

  • Repeatable 迁移之间不能有显式依赖(Flyway 不支持 R__depends_on_R__.sql);若存在逻辑依赖(如先建视图 A,再建基于 A 的视图 B),应合并为一个 R__views.sql 文件;
  • Versioned 迁移可安全引用 repeatable 产出的对象(如 V2.0 中的存储过程调用 R__views 定义的视图),因为 versioned 总是先执行;
  • Repeatable 迁移中不应修改已被 versioned 迁移创建的表结构(如 ALTER TABLE),否则 checksum 变化可能掩盖真实 DDL 演进路径,不利于审计和还原。

常见陷阱与规避建议

❌ 错误做法:

  • 把同一个业务功能拆成 V__ 和 R__ 两部分(如 V3.0 建表 + R__insert_default_data),导致数据初始化不可重现或环境不一致;
  • 在 repeatable 脚本中写 DROP TABLE if EXISTSCREATE OR REPLACE TABLE ——这些语句在多数数据库不支持,且违背 schema 管理原则;
  • 反复修改 R__ 脚本并期望 Flyway 自动重放(它确实会),但未验证下游依赖(如应用层缓存、etl 任务)是否兼容新逻辑;
  • 启用 flyway.cleanOnValidationError=true 后混用 repeatable,可能因 checksum 不匹配触发误清库。

✅ 推荐做法:

  • 将 repeatable 脚本视为“声明式”而非“命令式”:只保证最终状态正确(如 CREATE OR REPLACE VIEWTRUNCATE + INSERT 配置表);
  • 对关键 repeatable 迁移加注释说明适用范围(如 “仅适用于 postgresql 14+”,“需配合应用 v2.5+ 使用”);
  • CI 流程中增加校验:比对本地 R__ 文件哈希与目标环境历史表中的 checksum,提前发现未同步变更;
  • 必要时用 flyway repair 修复 repeatable 的 checksum(仅当确认内容已正确部署且历史记录损坏时)。
text=ZqhQzanResources