简介
Flyway是一款开源的数据库版本管理工具,可以实现管理并跟踪数据库变更,支持数据库版本自动升级,而且不需要复杂的配置,能够帮助团队更加方便、合理的管理数据库变更。
使用Flyway,你可以将数据库的变更(如创建表、添加列、修改数据等)作为一系列迁移脚本进行管理。每个迁移脚本都有一个唯一的版本号,Flyway会按照版本号的顺序依次执行这些脚本,从而将数据库迁移到所需的状态。
Flyway的工作原理
Flyway在第一次执行时,会创建一个默认名为flyway_schema_history的历史记录表,这张表会用来跟踪或记录数据库的状态,然后每次项目启动时都会自动扫描在resources/db/migration下的文件的版本号并且通过查询flyway_schema_history来判断是否有新增文件,从而判断是否进行迁移。
默认的查找 migration 的路径为 classpath:db/migration ,对应 SQL 文件可放置在src/main/resources/db/migration 下,Java 类可放置在 src/main/java/db/migration 下。
Flyway的校验版本号算法
flyway在升级数据库时会先计算之前已经升级过的脚本的checksum值和数据库的checkSum值进行比对,如果老脚本发生了变化后checkSum校验就会失败,从而抛出异常,checkSum计算算法为(CRC32 (循环冗余校验码)算法)。
新增的脚本则会和数据库中的版本号进行比较,如果小于数据库存储的最后一个版本号,也不会继续执行。
Flyway脚本命名规则
1.仅需要执行一次的,以大写“V”开头,V+版本后(版本号间的数字以“.” 或者“ _ ”分隔开,“ _ ”会自动编译成 “ . ” )+" __"+文件描述+后缀名
2.需要执行多次的,以大写“R”开头,命名如R__clean.sql ,R的脚本只要改变了就会执行,R不带版本号
注意:V开头的比R开头的优先级要高
接下来开始整合
1、在pom中引入依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>10.4.1</version>
</dependency>
2、在application.yml配置
flyway配置详解
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
spring:
flyway:
# 是否启用flyway
enabled: true
# 编码格式,默认UTF-8
encoding: UTF-8
# 迁移sql脚本文件存放路径,默认db/migration
locations: classpath:db/migration
# 迁移sql脚本文件名称的前缀,默认V
sql-migration-prefix: V
# 迁移sql脚本文件名称的分隔符,默认2个下划线__
sql-migration-separator: __
# 迁移sql脚本文件名称的后缀
sql-migration-suffixes: .sql
# 迁移时是否进行校验,默认true
validate-on-migrate: true
# flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是false 理论上作为默认配置是不科学的。
clean-disabled: true
# 如果数据库不是空表,需要设置成 true,否则启动报错
baseline-on-migrate: true
3、在resources新建文件夹db/migration
放入脚本文件,启动项目即可。
Flyway Maven插件
对于需要每次都启动项目可能会觉得麻烦,其实还有另外一种办法,插件
注意:数据库路径中的符号 & 需要用 & 代替
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>7.15.0</version>
<configuration>
<url>jdbc:mysql://loclhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
</url>
<user>root</user>
<password>dwchd2020</password>
<driver>com.mysql.cj.jdbc.Driver</driver>
</configuration>
</plugin>
插件命令说明
1.baseline:
对已经存在数据库Schema结构的数据库一种解决方案。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以在已有表结构的数据库中实现添加Metadata表。
2.clean:
清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用,但在生产环境务必禁用。
3.info:
用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本。
4.repair:
repair操作能够修复metaData表,该操作在metadata出现错误时很有用。
5.undo:
撤销操作,社区版不支持。
6.validate:
验证已经apply的Migrations是否有变更,默认开启的,原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。
7.migrate:
将未应用的迁移脚本应用到目标数据库中
插件命令注意事项
1.flyway执行migrate必须在空白的数据库上进行,否则报错
2.对于已经有数据的数据库,必须先baseline,然后才能migrate。
3.clean操作是删除数据库的所有内容,包括baseline之前的内容。
4.尽量不要修改已经执行过的SQL,即便是R开头的可反复执行的SQL,它们会不利于数据迁移。
5.当需要做数据迁移的时候,更换一个新的空白数据库,执行下migrate命令,所有的数据库更改都可以一步到位地迁移过去
注意事项总结
1.报错后需要删除flyway_schema_history中记录,否则启动失败
2.V的优先级高于R,假如三个V迁移脚本和一个R(无论新建还是修改)一起执行,其中一个V报错,则V会全部执行完成且记录到flyway_schema_history中,而R不执行且不记录,删除表中报错记录后,查询启动,则执行原错误V和未执行的R
3.多个要执行的R中,如果出现了其中一个出现了错误,则在其后的R都不执行
4.R的执行顺序根据命名来进行排序
5.一个文件中ddl并不由一个事务管理,比如创建三个表,中间创建表语句报错,则第一个表还是会创建成功并且提交事务
6.已经执行过的迁移文件(V)不能修改,否则报错
7.同一个迁移文件下同表内DDL无法回滚,DML可回滚, 从报错点开始不往下执行,Flyway使用数据库锁机制
8.版本号相同会报错(Found more than one migration with version 1.0.0.9)
9.同一个迁移文件下假设都是dml,那么如果中间出现错误,所有的dml语句都会回滚
10.删除sql文件后启动会报错。
11.如果不手动创建元数据表,则需要进行以下配置,用于自动创建
validate-on-migrate: true
12.如果数据库不是空表,则需进行以下配置,否则启动报错
baseline-on-migrate: true
13.clean命令会删除数据库中所有表,包括数据,结构等,这是不合理的,所以需要进行以下配置
clean-disabled: true (该配置由于默认值不合理,所以在V9版本中修改默认值由false为true)
14.使用flyway要注意版本兼容问题,springboot与flyway,flyway与数据库版本,否则启动报错
15.如果启动的时候像忽略某些迁移文件,可进行以下参数配置
baseline-version=20240108,以忽略 20240108 版本以及之前的所有 migration
16.多人开发中,如果一个人提交V2一个人提交V1,而V2先入库执行了,那么V1入库就不会执行,如果需要执行则需进行如下配置,但是不建议这么做
out-of-order=true