Flyway 完整使用指南 + 实战技巧
Flyway 是数据库版本管理工具,核心思想:用 SQL 脚本记录数据库变更,自动执行、版本化,解决多人开发、环境(开发/测试/生产)库结构不一致问题。
适用:MySQL、PostgreSQL、Oracle 等,Java 项目最常用,SpringBoot 直接集成。
一、核心概念(必须先懂)
-
版本脚本命名规范(硬性)
V
__ .sql
V:大写固定前缀VERSION:版本号,支持小数1/1.1/1.2.3,必须递增,不能重复__:两个下划线!!(分隔版本和描述,极易踩坑)- DESCRIPTION:描述,下划线分隔,不能空格
示例:
V1__init_table.sql # 初始化建表
V1.1__add_user_column.sql # 新增字段
V1.2__create_index.sql # 新建索引
还有两类:
U:Undo 回滚脚本(社区版不推荐用 ,企业版才稳定,后面会讲坑)
R:Repeatable 可重复脚本,每次变更都会执行,适合视图、存储过程、函数
- 元数据表
flyway_schema_history
Flyway 自动创建,记录:版本号、脚本名称、执行时间、成功状态。不要手动改这张表!
二、SpringBoot 集成最简使用(你大概率是这个场景)
1. Maven 依赖
<!-- flyway核心 -->
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>9.22.3</version>
</dependency>
<!-- MySQL驱动,按需 -->
2. application.yml 配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true
username: root
password: 123456
flyway:
enabled: true # 开启flyway
locations: classpath:db/migration # 脚本存放目录:resources/db/migration/
baseline-on-migrate: true # 已有老数据库时,自动基线(重点!)
validate-on-migrate: true # 校验脚本有没有被修改
clean-disabled: true # 生产环境禁止clean(删表!!)
3. 放脚本
在 resources/db/migration/ 下放 V1__xxx.sql
启动SpringBoot,Flyway自动执行未运行过的脚本,记录到历史表。
三、常用命令(独立CLI也可以用)
# 迁移,执行所有未跑脚本
flyway migrate
# 校验脚本是否篡改
flyway validate
# 查看版本状态
flyway info
# 基线(给已存在的老库打初始版本标记,不会执行SQL)
flyway baseline
# 清空数据库【⚠️ 生产绝对禁止!会drop所有表】
flyway clean
✅ 实战技巧 & 避坑(重点)
1. 脚本编写规范
- 一个脚本只做一次变更,不要混多个无关DDL
- 脚本里不要写 DROP TABLE,生产误执行灾难
- 脚本一旦提交到Git,绝对不能修改!>
Flyway 默认校验:如果已经执行过的V1脚本内容改动,启动直接报错。
✅ 正确做法:新增 V1.1 脚本,写ALTER,不要去改老V1。
- 不要在脚本写
SELECT这种查询,只写 DDL/DML(建表、改字段、初始数据)
2. 已有旧数据库接入Flyway(高频场景)
数据库已经有表了,不是空库:
- 执行
flyway baseline,标记当前库基线版本为V1 - 此时不会执行任何SQL ,只是在
flyway_schema_history插入一条版本记录 - 后续新增变更从 V1.1 开始写脚本
yml配置
baseline-on-migrate: true,首次启动自动基线,不用手动命令
3. Repeatable脚本 R 脚本
命名 R__view_user.sql
适合:视图、存储过程、函数。
特点:没有版本号,脚本MD5变化就重新执行。
适合场景:视图逻辑经常微调,不需要版本递增。
4. 回滚怎么处理?【大坑提醒】
❗ 社区版Flyway没有自动回滚!Undo脚本U是企业版功能,不要依赖!
✅ 最佳实践:正向迁移,不用回滚
如果上线出错:写一个新脚本
V1.3__rollback_v1.2_change.sql反向修复SQL,作为新版本提交。所有变更永远向前,不删旧脚本。
5. 多环境(dev/test/prod)技巧
- 脚本统一放在Git,所有环境共用一套脚本
- 禁止本地开发手动改库结构!所有库修改必须写Flyway脚本提交
- 测试环境验证脚本没问题,再部署生产,生产只执行 migrate
6. 踩坑清单
- 脚本名字
__写成单下划线,Flyway识别失败 - 脚本有中文,编码问题:SQL文件保存为 UTF-8
- 本地改了已经执行过的V脚本 → validate校验失败,启动报错
- 解决:不要修改已执行脚本;本地测试可以
flyway repair修复历史校验(生产慎用) flyway repair:修复历史表的md5,不要随便在生产跑
- 解决:不要修改已执行脚本;本地测试可以
- 生产千万不要开启
spring.flyway.clean-enabled=true,一键删库跑路 - 分布式多实例同时启动:Flyway自带锁,多个服务同时migrate不会重复执行,不用自己处理并发
7. 进阶小技巧
- 区分DDL和DML:建表改结构用V版本脚本;基础字典初始化数据也用V脚本;动态视图用R脚本
- 大表ALTER(上亿数据):
不要直接在Flyway脚本执行alter table add column锁表!
超大表在线变更建议单独工具(pt-online-schema-change),不要丢进Flyway自动执行。 - 关闭校验(不推荐生产):
validate-on-migrate: false,仅本地调试临时用 - 可以指定迁移目标版本:
flyway migrate -target=1.2只迁移到1.2版本,不执行更高版本
8. 和Liquibase简单对比(你选型参考)
- Flyway:SQL原生,简单上手,代码可读性高;缺点:社区版无回滚
- Liquibase:XML/YAML格式,支持回滚;缺点:语法繁琐,可读性差
如果你团队习惯手写原生SQL,优先Flyway