数据库版本管理工具利器——flyway详解
首先关于什么是flyway?以及使用场景(Java对数据库版本控制的主要有两个工具:Flyway、
Liquibase)可自行百度,狗子们用了都说好!
1、demo
flyway的广泛使用已被springboot自动装配集成,进入spring官网https://start.spring.io/创建以下依赖
idea直接进入生成好的项目内application.yml进行如下配置(数据库使用高性能postgresql)
> spring:
datasource:
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://localhost:5432/flyway_demo
username: postgres
password: postgres
flyway:
enabled: true
默认的db.migration目录下添加符合标准命名的sql脚本
create table f_user(id serial primary key,userName varchar(60) not null,password varchar(60) not null,sex char(1));
insert into f_user (userName,password,sex) values('admin','admin','1');
idea界面如是
项目启动,查看数据库,自动生成如下两张表(业务表自己创建的f_user, flyway内置表flyway_schema_history)
至此,一个简单的数据库版本管理工具已集成好,能够自动的帮你管理业务sql的执行
Flyway用’schema_version_history’数据表存放数据库schema的历史记录,跟踪数据库结构的变更;
由于刚开始数据库为空,Flyway找不到schema_version_history数据表,所以Flyway找不到它,就在数据库中创建了此表,
之后我们则需要在项目中定义Migration,通常用SQL或Java定义。
如下图所示,Flyway在运行时会顺序执行上图中的Migration1和Migration 2来实现对数据库的更新;同时’schema_version_history’表也会记录下这两次修改。
2、使用注意事项
- 配置项
- 打开源码springboot自动装配的配置映射对象FlywayProperties
常用属性配置
1、enabled:是否打开flyway管理
2、locations:执行的sql脚本路径,默认classpath:db/migration
3、encoding:sql脚本字符集编码
4、table:生成的校验表名字,默认flyway_schema_history如上图生成的校验表截图
5、sqlMigrationSeparator:sql命名的标准分隔符默认__
6、sqlMigrationPrefix:标准版本控制的sql脚本命名前缀
7、repeatableSqlMigrationPrefix:可重复执行的sql脚本命名前缀
8、placeholderReplacement:是否进行el变量替换
配置对象如此多的属性,为啥列举如上?经常使用,项目测试躲过坑,执行报错经历,特殊场景需求,下面一一道来:
table
校验默认生成的表明,但是要知道flyway自己也留下小坑,在5.0.0版中将flyway.table的默认值更改为flyway_schema_history ,原来的默认值叫schema_version,还记得曾几何时大版本的升级,由于此处不兼容安装升级失败整个提测流程打回!
placeholderReplacement
sql脚本中符合el表达式变量替换中的${}特殊字符,想想看mybatis中sql防注入的入参变量,如果开关打开脚本执行会报错导致升级失败,设置为false能解决sql脚本中类似的特殊字符,集合配置项placeholderPrefix默认值(“${)”)、placeholderSuffix的默认值(“}”)具体情况使用
sqlMigrationPrefix
控制版本的标准命名前缀默认为"V",跟笔者开头的demo相对应,此脚本有以下特性:
1、sql只执行一次
2、生成校验值checksum,只要当前sql脚本变动,与之前入库执行的sql不一样,checksum值校验不成功,升级失败
3、生成版本号version唯一和脚本命名规则中Add_new_table对应,命名规则(V类型对应下图第一个):
4、installed_by执行脚本的数据库连接用户名,以及sql执行结果success(t和f)
5、有序执行它采用 采用左对齐原则, 缺位用 0 代替 。举几个例子:
1.0.1.1 比 1.0.1 版本高。
1.0.10 比 1.0.9.4 版本高。
1.0.10 和 1.0.010 版本号一样高, 每个版本号部分的前导 0 会被忽略。
repeatableSqlMigrationPrefix
可重复执行的sql脚本命名前缀默认为“R”,命名规则如上图第三个,笔者测试先走一波再看结论
添加sql脚本——R__1.1updateuser.sql(注意命名标准)
create table f_user2(id serial primary key,userName varchar(60) not null,password varchar(60) not null,sex char(1));
insert into f_user2 (userName,password,sex) values('admin','admin','1');
启动服务,查看数据库结果
业务表f_user2成功创建,数据库记录多生成一条记录,缺少版本号version,其余校验值和V一致,该R开头sql表示为可重复执行的sql脚本,脱离version的版本校验约束,相当于补丁脚本,在所有V脚本执行后执行,同时也有checksum值校验,一旦内容发生变化,checksum值变动,但执行不会报错,会重新执行,脚本内容无变化时,不会执行
什么意思?容我操作一下
修改R__1.1updateuser.sql脚本内容 尾部添加如下
create table f_user2(id serial primary key,userName varchar(60) not null,password varchar(60) not null,sex char(1));
insert into f_user2 (userName,password,sex) values('admin','admin','1');
drop table f_user2;
create table f_user3(id serial primary key,userName varchar(60) not null,password varchar(60) not null,sex char(1));
项目启动,查看数据库结果
执行报错,R__1.1updateuser.sql脚本有变动会重新执行,业务sql脚本创建表若是永exists判断,会删除f_user2创建新的f_user3,之前的f_user2业务数据会无感知删除,还是有的一定风险,使用时可作为V版本的补丁脚本,单次执行完,不做变动,保证只执行一次,也不影响主版本version的升级!
除此之外还有命名途中的第二种U开头的脚本类型即回滚V类型的Undo模式,与version作用相反用于撤销具有相同版本的版本化迁移带来的影响。但是该回滚过于粗暴,过于机械化,一般不推荐使用。一般建议使用 Versioned 模式来解决。,版本号与V一致,创建以下U__1.1deleteuser.sql
drop table f_user;
Undo及基本操作命令info、clean、migrate、undo通过cmd命令行执行演示
本地安装flyway(下载地址)conf下的配置文件flyway.conf
flyway.url=jdbc:postgresql://localhost:5432/flyway_cmd
flyway.user=postgres
flyway.password=postgres
flyway.schemas=flyway_demo
flyway.encoding=UTF-8
flyway.locations=sql
脚本V1.1__createuser.sql放置安装目录sql文件夹下,cmd命令行执行
flyway info
继续添加脚本R__1.1updateuser.sql,cmd命令行执行可重复执行脚本
flyway migrate
继续添加脚本U1.1__createuser.sql,cmd命令行执行回滚脚本
flyway undo
至此查看数据库结果
三条执行记录,最后一条的回滚UNDO_SQL直接将V1.1__createuser.sql的操作删除
额外操作命令,cmd命令行执行清除脚本
flyway clean
数据库所有sql操作均被清除,还原成空库
flyway Baseline
初始化schema_version表,并插入一条原始verion=1
flyway Validate
迁移之前进行验证
flyway Repair
移除所有失败的迁移(升级),重置校验和删除schema_version失败记录
3、结束
flyway的使用注意情况
- 生产务必禁 spring.flyway.cleanDisabled=false
- 尽量避免使用 Undo 模式
- repeatableSql——R模式的sql修补功能
贴下所有的配置项详解如下:
flyway.baseline-description对执行迁移时基准版本的描述.
flyway.baseline-on-migrate当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
flyway.baseline-version开始执行基准迁移时对现有的schema的版本打标签,默认值为1.
flyway.check-location检查迁移脚本的位置是否存在,默认false.
flyway.clean-on-validation-error当发现校验错误时是否自动调用clean,默认false.
flyway.enabled是否开启flywary,默认true.
flyway.encoding设置迁移时的编码,默认UTF-8.
flyway.ignore-failed-future-migration当读取元数据表时是否忽略错误的迁移,默认false.
flyway.init-sqls当初始化好连接时要执行的SQL.
flyway.locations迁移脚本的位置,默认db/migration.
flyway.out-of-order是否允许无序的迁移,默认false.
flyway.password目标数据库的密码.
flyway.placeholder-prefix设置每个placeholder的前缀,默认${.
flyway.placeholder-replacementplaceholders是否要被替换,默认true.
flyway.placeholder-suffix设置每个placeholder的后缀,默认}.
flyway.placeholders.[placeholder name]设置placeholder的value
flyway.schemas设定需要flywary迁移的schema,大小写敏感,默认为连接默认的schema.
flyway.sql-migration-prefix迁移文件的前缀,默认为V.
flyway.sql-migration-separator迁移脚本的文件名分隔符,默认__
flyway.sql-migration-suffix迁移脚本的后缀,默认为.sql
flyway.tableflyway使用的元数据表名,默认为schema_version
flyway.target迁移时使用的目标版本,默认为latest version
flyway.url迁移时使用的JDBC URL,如果没有指定的话,将使用配置的主数据源
flyway.user迁移数据库的用户名
flyway.validate-on-migrate迁移时是否校验,默认为true.