Flyway 数据库版本管理

一、Flyway简介

Flyway是一款开源的数据库迁移工具,可以管理和版本化数据库架构。通过Flyway,可以跟踪数据库的变化,并将这些变化作为版本控制的一部分。Flyway支持SQL和NoSQL数据库,并且可以与现有的开发流程无缝集成,如持续集成(CI)和持续部署(CD)。

二、Flyway主要特性

Flyway的主要特性包括:

  1. 版本化迁移(Versioned Migrations):通过一系列的SQL脚本逐步更新数据库架构,每个迁移脚本都有一个唯一的版本号,例如V1__Initial_setup.sql。当Flyway运行时,它会检查数据库中的flyway_schema_history表,以确定哪些迁移脚本已经执行过了。如果发现有未执行的迁移脚本,Flyway将按照版本号的顺序执行它们。
  2. 回退迁移(Undo Migrations):是指在某些情况下,可能需要将数据库回滚到一个先前的状态。Flyway并没有内置的回退机制,但它提供了基础设施,允许你在迁移脚本中定义回退逻辑。通常是通过在迁移脚本中指定一个相反的迁移脚本来实现的。例如,如果你有一个迁移脚本V2__Add_new_column.sql,你可以创建一个对应的回退脚本R2__Drop_new_column.sql,其中R2表示这是一个回退脚本。在需要回滚时,Flyway会执行相应的回退脚本,将数据库回滚到上一个稳定的状态。
  3. 可重复迁移(Repeatable Migration):是与版本化迁移不同的另一种类型的迁移,它不依赖于版本号。这种迁移脚本通常用于那些不需要跟踪版本的变更,比如对数据库性能调优的脚本。Flyway会简单地将这些脚本视为一组独立的更改,并在每次运行时执行它们。
  4. 多数据库支持:Flyway支持多种关系型数据库,如MySQL、Oracle、PostgreSQL等,使得在不同数据库间迁移变得容易。
  5. 自动化迁移:Flyway可以在应用程序启动时自动执行迁移脚本,或者通过命令行手动执行,提高了迁移的效率和可靠性。
  6. 集成到开发流程:Flyway可以集成到持续集成(CI)和持续部署(CD)流程中,确保数据库结构随着应用程序的发展而保持同步。

三、Flyway的工作流程

Flyway的设计哲学是约定优于配置,这意味着它遵循一些预定义的规则来简化数据库迁移的过程。下面是Flyway的基本工作流程:

  1. 初始化:当你首次运行Flyway时,它会根据配置在数据库中创建一个名为flyway_schema_history的表,这个表用来记录所有的迁移活动,包括迁移的版本号、描述、执行的SQL文件名、执行时间和是否成功等信息。
  2. 扫描迁移脚本:Flyway会扫描指定的目录(通常是classpath:db/migration)以查找迁移脚本。这些脚本通常命名为V<version>__<description>.sql,其中<version>是迁移的版本号,<description>是对迁移的简短描述。
  3. 比较版本号:Flyway会比较数据库中的flyway_schema_history表记录的当前版本号与现有迁移脚本中的版本号。如果存在未执行的迁移脚本,Flyway将会执行它们。
  4. 执行迁移:对于每个需要执行的迁移脚本,Flyway会将其作为一个事务执行。如果在执行过程中出现错误,Flyway会回滚整个事务,并记录错误信息。
  5. 记录迁移结果:一旦迁移脚本执行完毕,无论是成功还是失败,Flyway都会在flyway_schema_history表中记录下迁移的结果。
  6. 重复执行:如果需要,你可以重复执行Flyway的迁移过程,以应用新的迁移脚本。Flyway会识别哪些迁移已经被执行过,并跳过它们。

四、与SpringBoot项目整合

4.1 添加依赖

到项目的pom文件中添加Flyway的依赖包。

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-mysql</artifactId>
    <version>8.5.13</version>
</dependency>
4.2 修改配置

到项目的application.yaml文件中添加Flyway的配置信息。

sping:
  flyway:
    #是否开启flyway,默认true
    enabled: true
    #当迁移时发现目标schema非空,而且没有元数据的表时,(即迭代中项目应为true)是否自动执行基准迁移,默认false.
    baseline-on-migrate: true
    # 是否允许无序运行迁移, 默认false,建议开发环境开启,生成环境关闭
    out-of-order: false
    #设定SQL脚本的目录,可以配置多个,比如为classpath:db/migration,filesystem:/sql-migrations,默认classpath:db/migration
    locations:
      - classpath:db/migration

常用配置项如下:

  • spring.flyway.enabled: 是否启用Flyway,默认为true。
  • spring.flyway.table: Flyway元数据表的名称,默认为flyway_schema_history。
  • spring.flyway.encoding: 迁移脚本文件的编码,默认为UTF-8。
  • spring.flyway.validate-on-migrate: 迁移时是否进行验证,默认为true。
  • spring.flyway.check-location: 是否检查迁移脚本的位置是否存在,默认为true。
  • spring.flyway.clean-disabled: 是否禁用Flyway的clean操作,默认为false。
  • spring.flyway.baseline-on-migrate: 当迁移时发现目标schema非空,并且没有元数据的表时,是否自动执行基准迁移,默认为false。
  • spring.flyway.baseline-version: 开始执行基准迁移时对现有schema的版本打标签,默认为1。
  • spring.flyway.locations: 迁移脚本的位置,默认为classpath:db/migration。
  • spring.flyway.sql-migration-prefix: 迁移文件的前缀,默认为V。
  • spring.flyway.sql-migration-suffix: 迁移脚本的后缀,默认为.sql。
  • spring.flyway.out-of-order: 是否允许无序的迁移,默认为false。
  • spring.flyway.schemas: 需要Flyway迁移的schema,默认为连接默认的schema。
4.3 编写sql脚本文件

sql脚本文件名称要符合flyway规范,命名规则如下:

  • 版本迁移脚本(Versioned Migrations):脚本文件名的前缀通常是V,后跟版本号(版本号之间可以用点.或下划线_分隔),版本号后面是__双下划线的分隔符,分隔符后面是文件描述,最后是文件后缀名。例如:V1__Initial_Setup.sqlV1.1.2__Initial_Setup.sqlV1.1.2_1__Initial_Setup.sql
  • 回退迁移(Undo Migrations):脚本文件名的前缀为U,前缀后面部分与版本迁移脚本的文件名相同。例如:U1__Initial_Setup.sqlU1.1.2__Initial_Setup.sqlU1.1.2_1__Initial_Setup.sql
  • 可重复迁移脚本(Repeatable Migrations):脚本文件名的前缀是R,由于不依赖版本号,所以后面可以直接跟分隔符和脚本名称。例如R__truncate_user_dml.sql

在这里插入图片描述
默认情况下sql脚本文件都放在src\main\resources\db\migration下:
在这里插入图片描述

4.4 启动项目自动完成脚跟更新

项目启动日志中打印出Flyway 的脚本执行信息如下:
在这里插入图片描述

五、错误总结

Spring Boot版本是2.5.12,MySQL用的是8.2。

  1. Unsupported Database: MySQL 8.2
    这个问题是由于开始用的Flyway 依赖是flyway-core的8.5.13版本,后面换成flyway-mysql的8.5.13版本解决问题。

  2. Validate failed: Migrations have failed validation
    (1)Either revert the changes to the migration, or run repair to update the schema history.
    这个问题是由于脚本已经被migration 过了,后面又对这个脚本做了修改所导致的。所以已经被migration 过脚本文件一定不要再去修改,实在要改的话重新写个脚本文件去修改。这里解决问题是删掉flyway_schema_history表中之前执行过的记录,这样重新再启动的时候Flyway 校验这个脚本时找不到之前执行过的记录,就会认为这是个全新的脚本不会与之前执行过的脚本有冲突,才会再次执行这个脚本。其实这样改还不是很好,因为这个脚本的的确确已经执行过一次,如果这个脚本是个添加一条记录的语句,你后面只是在这个语句中多加了个字段,然后再次去执行,那结果就是再新增一条类似的数据,而我们的本意其实只是想改动之前的数据,所以如果不小心改动了之前已经migration 过的脚本,最好连同这个脚本执行过的sql记录也一起删掉
    (2)Please remove any half-completed changes then run repair to fix the schema history.
    这个问题是由于在项目启动时Flyway 执行脚本出错,但是flyway_schema_history表中已经记录了这次脚本的migration失败的操作, 当你修改完脚本后再次启动项目时,发现flyway_schema_history表中有过这个脚本的migration操作,从而导致校验不通过。这种情况只需要把flyway_schema_history表中这个脚本之前失败的记录删除重启项目就可以,因为之前执行该脚本时,该脚本的sql报错并没有对数据库进行实际的操作,所以也就不用去数据库删除之前这个脚本操作产生的实际数据了。

  3. Flyway failed to initialize: none of the following migration scripts locations could be found
    这个问题是由于没找到sql脚本文件,可能是设置指定存放sql脚本的目录出错或者目录中压根没有脚本文件。我这个是没有脚本文件,项目启动时报的错,随便添加个空的脚本文件后就能正常启动了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值