WHAT --Flyway是什么
Flyway是独立于数据库的应用、管理并跟踪数据库变更的使用Java编写的数据库版本管理工具。用通俗的话讲,Flyway可以像Git管理不同人的代码那样,管理不同人的sql脚本,从而做到数据库同步。
Flyway 具有如下特点:
使用简单(Simple to use)
通过 Flyway 能够轻松的实现控制迁移。
解决好一个问题(Solves one problem well)
Flyway 迁移数据库,开发人员就不会迁移出错了。
专为 CI/CD 设计(Made for CI/CD)
发布从未如此简单。Release have never been this easy。
官网 https://flywaydb.org/
2010-04-20 flyway 0.01版本发布
2019年 Redgate 收购
2021-04-01 flyway 7.7.2版本
Version control for your database
Robust schema evolution across all your environments.
With ease, pleasure, and plain SQL.
在所有环境中进行稳健的架构演变,轻松,愉快和简单的SQL。
WHY--为什么要用Flyway
开发人员在合作的时候经常遇到以下场景:
场景一:开发环境,多人共用一套数据库
开发正调试着,忽然代码报错“XX字段不存在”:谁TMD又把表结构给改了……
场景二:开发环境,每个人各自搭建自己的数据库
开发完一个功能,提交代码、更新,重启准备调试下,代码报错“XX表不存在”
吼一嗓子:谁又改表结构了?什么?每个人都要把xxx.sql执行一遍?
……
新员工:我要搭一套开发数据库,到底应该执行哪些SQL脚本?
场景三:开发转测试
测试:你看这个功能是不是有个Bug?
开发1:哦,你要执行一下这个SQL脚本。
测试:嗯,现在没问题了,但是怎么保证这个脚本没有Bug,我能再重现、测试一遍吗?
开发:额~,你重新搭一遍数据库吧……
场景四:搭建一套演示环境
执行SQL脚本1、SQL脚本2、SQL脚本3……启动服务失败!
什么?这个脚本N是测试版本的,war包是已经上线的版本?
删库再来一遍……
传统的解决方案就是在一个固定的文件夹中,将需要跑的SQL脚本放在里面。开发人员在合作的时候,A修改了数据库,在B遇到问题的时候,可能需要交流沟通一下,去跑需要的脚本。在项目上线的过程中,也是运维人员在规定的文件夹中,找到需要跑的SQL脚本。运行它们。
Flyway等migration工具就是要把开发人员和运维人员从以上这些场景的繁琐工作中解放出来,如果使用maven的话,那么在项目编译(SpringBoot运行Application)的时候,SQL数据库的改动就自动进入数据库,只要启动成功,开发或者运维人员对SQL数据库的migrate过程是无感知的,项目依然可以照常运行。
WHO--谁需要用Flyway;
架构人员:搭建框架初始数据库的;
开发人员:在flyway框架下做sql改动的;
WHERE--Flyway在项目中用在什么地方
项目初始化sql运行中;
只要项目中数据库改动;
项目升级过程中;
HOW--如何用Flyway
一、流程
- 项目启动时拉起Flyway,先检查数据库里面有没有Flyway元数据表,没有则创建,会在数据库表中默认新建一个数据表用于存储flyway的运行信息,默认的数据库名:flyway_schema_history;
- 检查Flyway元数据表中的记录,哪些脚本已经执行过,当前版本是什么;
- 可以看到执行数据库表后在checksum中储存一个数值,用于在之后运行过程中对比sql文件执行是否有变化,查找代码中的(名称满足规则的)数据库升级脚本,找出版本号大于(Flyway元数据)当前版本的脚本,逐个执行并记录执行结果到Flyway元数据表。
注意:
flyway在执行脚本时,会在源数据表中检查checksum值,并确定上次运行到哪一个脚本文件,本次执行时从下一条脚本文件开始执行。所以编写脚本的时候不要去修改原有的脚本内容,并且新的脚本版本号要连续。
二、命名规范:
sql 脚本存放目录:src/main/resources/db/migration
Flyway 将 SQL 文件分为 Versioned 、Repeatable 和 Undo 三种:
Versioned 用于版本升级, 每个版本有唯一的版本号并只能执行一次.
Repeatable 可重复执行, 当 Flyway检测到 Repeatable 类型的 SQL 脚本的 checksum 有变动, Flyway 就会重新应用该脚本. 它并不用于版本更新, 这类的 migration 总是在 Versioned 执行之后才被执行。
Undo 用于撤销具有相同版本的版本化迁移带来的影响。但是该回滚过于粗暴,过于机械化,一般不对应一个程序版本的多个脚本,从1开始,比如1.0.9版本,有多个任务:张三负责a任务(tapd号为1111111),李四负责b任务(tapd号为222222),他们的任务都涉及到db更新他们会分别创建两个脚本:
V1.0.9.0.1__1111111.sql
V1.0.9.0.2__222222.sql
说明:V大写,中间是两个下划线(__)
三、重要配置:
# flyway 配置
spring:
flyway:
# 启用或禁用 flyway
enabled: true
# flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是 false 理论上作为默认配置是不科学的。
clean-disabled: true
# SQL 脚本的目录,多个路径使用逗号分隔 默认值 classpath:db/migration
locations: classpath:db/migration
# metadata 版本控制信息表 默认 flyway_schema_history
table: flyway_schema_history
# 如果没有 flyway_schema_history 这个 metadata 表, 在执行 flyway migrate 命令之前, 必须先执行 flyway baseline 命令
# 设置为 true 后 flyway 将在需要 baseline 的时候, 自动执行一次 baseline。
baseline-on-migrate: true
# 指定 baseline 的版本号,默认值为 1, 低于该版本号的 SQL 文件, migrate 时会被忽略
baseline-version: 1
# 字符编码 默认 UTF-8
encoding: UTF-8
# 是否允许不按顺序迁移 开发建议 true 生产建议 false
out-of-order: false
# 需要 flyway 管控的 schema list,这里我们配置为flyway 缺省的话, 使用spring.datasource.url 配置的那个 schema,
# 可以指定多个schema, 但仅会在第一个schema下建立 metadata 表, 也仅在第一个schema应用migration sql 脚本.
# 但flyway Clean 命令会依次在这些schema下都执行一遍. 所以 确保生产 spring.flyway.clean-disabled 为 true
schemas: flyway
# 执行迁移时是否自动调用验证 当你的 版本不符合逻辑 比如 你先执行了 DML 而没有 对应的DDL 会抛出异常
validate-on-migrate: true
四、其他注意事项
1.当验证开启时(默认validate-on-migrate: true),修改已经提交的sql文件报错,正确的提交升级sql的
a. 已经提交的 flyway 脚本不可删除;
b. 已经提交的 flyway 脚本不可修改;
c. 已经提交的 flyway 脚本可重复执行;
- 命令行:
mvn flyway:baseline
基准(该命令创建的版本号未V1,所以开发的第一个版本不要叫V1.0或者V1.0.0等)
mvn flyway:migrate
迁移
mvn flyway:info
信息
mvn flyway:validate
校验
mvn flyway:clean
清除所有表
mvn flyway:undo
撤销(免费版不支持)
mvn flyway:repair
修复,只能撤销对应的sql执行记录,不能回滚整个sql脚本
3.如果一个脚本里既有错误又有正确,正确的会执行,执行到错误的为止。已经执行的不会回滚。