Flyway平滑迁移依赖对脚本类型、执行时机和校验机制的理解:V脚本禁止修改,须用新版本修复;clean-disabled:true必须显式配置于生产环境;R脚本仅适用于视图等可重复创建对象;多数据源需为每个源独立配置Flyway实例。

Flyway 能做到数据库 Schema 自动化版本控制,但“平滑迁移”不靠工具本身,而靠你对脚本类型、执行时机和校验机制的理解与约束。
为什么 V 脚本不能改,改了就启动失败
Flyway 启动时会读取 flyway_schema_history 表,比对每个已执行的 V 脚本的 checksum(基于文件内容计算)。一旦你修改了已执行过的 V2__add_user_table.sql,下次启动就会报错:Validate failed: Migration checksum mismatch。这不是 bug,是防误操作的核心机制。
常见错误现象:
- 开发中临时改了 SQL,测试通过后直接提交,导致 CI 环境或同事拉代码后项目起不来
- 把
V脚本当成普通 SQL 文件反复编辑,没意识到它已“固化”在历史记录里
正确做法:
- 已发布的
V脚本绝对禁止修改 —— 无论改动多小 - 修复用新版本:比如原
V2__add_user_table.sql少了个字段,应新增V2_1__add_phone_column_to_user.sql(注意小数点版本合法) - 生产环境上线前,务必在预发库执行
flyway validate命令,提前暴露 checksum 不一致问题
clean-disabled: true 是生产环境的生死线
clean-disabled: true 必须显式配置在生产环境的 application-prod.yml 中。它禁用 flyway clean 命令 —— 否则任意人调用该命令会清空整个库表结构。
容易踩的坑:
- 本地
application-dev.yml开启了clean-disabled: false,但忘了在生产配置里覆盖,导致上线包携带危险能力 - 使用 Spring Boot Actuator 暴露了 Flyway Endpoint(如
/actuator/flyway),未鉴权就允许远程触发clean - CI/CD 流水线脚本中硬编码了
mvn flyway:clean,未做环境判断,推到生产分支就执行
建议:
- 所有环境配置中显式声明
clean-disabled,不依赖默认值 - 生产部署包启动前,加一道检查:grep -q "clean-disabled: false" application-prod.yml && exit 1
- 禁用 Actuator 的 Flyway Endpoint,或至少设置
management.endpoint.flyway.show-details=never
R 脚本不是“万能补丁”,它只适合无状态对象
R 脚本(如 R__create_summary_view.sql)会被每次启动时重新执行,但它**不参与版本排序**,也不写入 flyway_schema_history 的 version 字段。这意味着它无法替代 V 脚本做 DDL 变更。
适用场景有限:
- 视图(VIEW)、函数(FUNCTION)、存储过程(PROCEDURE)等可重复创建的对象
- 初始化少量基础配置数据(如系统字典),且确保 SQL 内含
INSERT IGNORE或ON DUPLICATE KEY UPDATE
千万别用 R 脚本干这些事:
- ALTER TABLE 添加字段 —— 多次执行会报 “duplicate column” 错误
- CREATE TABLE —— 如果表已存在,直接失败(除非加
IF NOT EXISTS,但依然不可靠) - 任何依赖前置
V脚本已执行的逻辑(R 脚本执行顺序不确定)
多数据源下,Flyway 不会自动猜你要迁哪个库
JeecgBoot 的 DynamicRoutingDataSource 支持多数据源,但 Flyway 默认只作用于主数据源(@Primary 标记的 DataSource)。如果你有 ds_order 和 ds_report 两个库,必须手动为每个数据源配置独立的 Flyway Bean。
否则现象:
- 只有主库执行了迁移,从库 schema 落后,应用运行时报表不存在
- 多个数据源共用同一张
flyway_schema_history表,造成版本混乱甚至锁表失败
实操要点:
- 每个非主数据源需定义独立
Flyway实例,并指定dataSource和table(如flyway_report_schema_history) - SQL 脚本目录按数据源隔离:如
classpath:flyway/sql/mysql/order/和classpath:flyway/sql/mysql/report/ - 避免跨数据源的联合迁移逻辑 —— Flyway 不支持事务跨库,出错无法回滚
真正的平滑,来自对 V 脚本的一次性承诺、对 clean-disabled 的物理封锁、对 R 脚本能力边界的清醒认知,以及多数据源下显式的逐个声明 —— 工具不会替你做决策,它只忠实地执行你写下的规则。

















