当前位置:   article > 正文

|- flyway -| 带你快速了解与使用 flyway_flyway执行顺序

flyway执行顺序

什么是 flyway

Flyway is an open-source database migration tool. It strongly favors simplicity and convention over configuration.

flyway 是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式(约定大于配置)。flyway 可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级,并且有一套默认的规约,不需要复杂的配置,Migrations 可以写成 SQL 脚本,也可以写在 Java 代码中,不仅支持 Command Line 和 Java API,还支持 Build 构建工具和 Spring Boot 等,同时在分布式环境下能够安全可靠地升级数据库,同时也支持失败恢复等。

为什么要使用 flyway

对于软件部分,我们已经有成熟的解决方案:Git/SVN 等版本控制系统;GoCD/Jenkins/CircleCI 等持续集成工具;蓝绿部署等成熟的自动化部署方案。但是对于数据库部分呢?很多项目仍然依赖于手动运行 SQL 脚本,甚至还在项目中处处可见用于补丁升级的 SQL 脚本。那么问题就来了:如何确认各个环境上的数据库状态?某个 SQL 脚本是否运行过了? flyway 数据库迁移工具就是帮助我们解决这个问题的。

img

当前我们的数据库管理现状

我们遇到的问题:
不同的开发人员在开发产品特性时,都有可能更新数据库(添加新表,新的约束等)。所有的数据脚本都需要写成可重复执行的形式,统一放于 svn 中管理,由于没有状态的记录,每次都会执行全部的脚本,一不小心就容易出现问题,如果是新增数据脚本用于初始化基本数据,那我们基本是让运维手工执行 sql 脚本,以什么顺序来执行这些脚本,都需要填写和运维沟通清楚,这些问题同样存在于生产环境。

flyway 优势

对比其他工具的最大优势:就是 简单且易于管理,而且直接书写 SQL 并不需要额外的学习( 这里我们选择 flyway 有两个原因,一是它是 Java 生态圈的,其次就是 Spring Boot 提供了内建支持,可以很快应用到产品中 )

flyway 是如何工作的?

第一个最简单的场景:如何使用 flyway 从无到有的创建数据库。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jteVqhSg-1572589543612)(https:// flyway db.org/assets/balsamiq/EmptyDb.png)]

flyway 用 flyway_schema_history 数据表存放执行 SQL 脚本的历史记录,跟踪数据库结构的变更;我们则需要在项目中定义 Migration ,通常用 SQL 或 Java 定义。如下图所示,flyway 在运行时会顺序执行上图中的 Migration1 和 Migration2 来实现对数据库的更新;同时 flyway_schema_history 表也会记录下这两次修改。
在这里插入图片描述
注意:
flyway 因为版本不同,旧版本的 flyway 的执行记录表不是 flyway_schema_history 而是 schema_version ,而且表结构也发生了变更,在选择 flyway 版本的时候还需注意!

接下来就是第二个场景:基于已有数据库进行更新。flyway 仍然会遍历项目中定义的各个 Migration,并参照 flyway_schema_history 数据表,忽略版本号低于或等于当前版本的 Migration,剩下的就是 Pending Migration,然后按照版本号顺序执行 Pending Migration,如下图所示:

因此,每当我们要对数据库的 DDL 或者 DML 进行演进,就只需要定义一个更高版本的 Migration
在这里插入图片描述

flyway 命令介绍

Repair
Repair 操作能够修复 flyway_schema_history 表,该操作在 flyway_schema_history 表出现错误时是非常有用的。
在这里插入图片描述

Repair 会修复 flyway_schema_history 表的错误,通常有两种用途:

  • 移除失败的 Migration 记录,该问题只是针对不支持 DDL 事务的数据库。
  • 重新调整已经应用的 Migratons 的 checksum 值,比如:某个 Migration 已经被应用,但本地进行了修改,又期望重新应用并调整 checksum 值,不过尽量不要这样操作,否则可能造成其它环境失败。

Migrate
Migrate 是指把数据库 schema 迁移到最新版本,是 flyway 工作流的核心功能, flyway 在 Migrate 时会检查 flyway_schema_history 表,如果不存在会创建 flyway_schema_history 表, flyway_schema_history 表主要用于记录版本变更历史以及 checksum 之类的。
在这里插入图片描述

migrate 时会扫描指定文件系统或 classpath 下的 migrations (可以理解为数据库的版本脚本),并且会逐一比对数据表中的已存在的版本记录,如果有未应用的 migrations,flyway 会获取这些 migrations 并按次序应用到数据库中,否则不需要做任何事情。另外,通常在应用程序启动时应默认执行 migrate 操作,从而避免程序和数据库的不一致性。

Validate
validate 是指验证已经应用的 migrations 是否有变更,flyway 是默认是开启验证的。
在这里插入图片描述

validate 原理是对比 flyway_schema_history 表与本地 migrations 的 checksum 值,如果值相同则验证通过,否则验证失败,从而可以防止对已经应用到数据库的本地 migrations 的无意修改。

Clean
clean 相对比较容易理解,即清除掉对应数据库 schema 中的所有对象,包括表结构,视图,存储过程,函数以及所有的数据等都会被清除。
在这里插入图片描述

所以,执行 clean 命令的时候,还请三思!

flyway 的使用命令介绍就到这里了。当然,flyway 的命名不只有这些,如果你感兴趣的话,可以自行到官网查看

在项目中如何引入并使用 flyway

flyway 引入

其他几种引入方式,详见 |- flyway -| 项目中接入 flyway 的几种方式 ,以下以 自定义 starter 为例

  1. pom 文件引入 flyway 相应依赖

    starter 和接入项目在文末也会给出相应的项目连接地址

    <dependency>
    	 <groupId>org.flywaydb</groupId>
     	<artifactId>flyway-core</artifactId>
     	<version>6.0.7</version>
    </dependency>
    <!-- 引入自定义的 flyway starter -->
    <dependency>
    	<groupId>com.linkr.flyway</groupId>
    	<artifactId>linkr-starter-flyway</artifactId>
     <version>1.0.0-SNAPSHOT</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  2. yml 文件中的配置如下

    配置中心的配置信息:

    flywaydb:
      url: ${spring.datasource.url}
      username: username
      password: password
    
    • 1
    • 2
    • 3
    • 4

    注意

    要求数据库账号 除了拥有正删改查操作外还需拥有能够操作数据表的权限,因为第一次引进 flyway的时候,会在数据库中创建一张名为 flyway_schema_history 的数据表,该表主要用于记录 SQL 脚本的执行记录和版本信息

    url: 直接引用 当前项目中的数据库连接即可
    username: 配置成加密后的字符串
    password: 配置成加密后的字符串

  3. 添加数据库脚本

    脚本存放位置(默认):src/resources/db/migration(目录是可以自定义,参数配置见 使用须知 )
    在这里插入图片描述

SQL 数据脚本命名须知

不可重复执行脚本
V${version}_${time}__${name}.sql,其中前缀V、后缀.sql、分隔符__ ;
可重复执行脚本
R__V${version}_${time}__${name}.sql,其中前缀V、后缀.sql、分隔符__;

注意
脚本执行顺序

「 可重复执行脚本(R)」 的执行顺序在 「 不可重复执行脚本(V)」 之后(此处有坑)

执行顺序的重要性(依靠版本号来约束):如果是进行数据脚本迁移且现有的数据库被清空的情况下(即空数据库情况下),那么建表语句需先执行(最小版本号)才行。如果建表语句写成可重复脚本的话,那么程序将会报错,因为「 可重复执行脚本(R)」 的执行顺序在 「 不可重复执行脚本(V)」 之后,所以此时数据表还没建立,对于数据表中的数据操作都将报错

至此 flyway 引入完成,启动项目,坐等执行成功即可~

使用须知

关于 yml 配置支持
spring:
  application:
    name: flyway-db
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/iot_db_user?useUnicode=true&useSSL=false&characterEncoding=utf-8
    username: balabala
    password: balabala
# 模拟配置中心的配置
flywaydb:
  url: ${spring.datasource.url}
  username: username
  password: password
#  以下配置可以配置在 当前项目中
#  配置是否启动项目的时候,执行 repair 和 migrate 方法,用于自测;一般不需要配置
#  startEnable: false
#  如果有自定义需求,可以通过 locations 配置 SQL 脚本的存放目录,支持多个目录,用 “,” 隔开
#  locations: db/migration/V1_0_0,db/migration/V2_0_0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
关于脚本的变更的问题

修改 SQL 脚本
如果直接更改其中一个执行过的 SQL 脚本,然后去执行 migrate 命令,会报错

由于初始化脚本的改动,导致 flyway 校验失败,flyway 检测到当前的脚本与上一次执行的内容不同,提示报错并终止程序,以免造成更严重的数据结构破坏
在这里插入图片描述
由报错可以看出,报错是因为 checksum 值和之前的不一样了,flyway 就是通过这个值来判断这个文件是否已经执行过的。

解决方法
使用 flyway repair 命令
这个命令会修改错误的 SQL 文件校验码的值,再执行 migrate 就没问题了,但是,修改的内容还是不会被执行!
因为 flyway_schema_history 数据表的 success 值为 1 ,便不会在重新执行脚本

删除 SQL 脚本

在开发阶段,已经写了 V1_0_0_20191024102411__add_userInfo.sql ,也已经 migrate,但是之后发现这个脚本没用,删掉了,后续再执行migrate时,发现会报错,
在这里插入图片描述

解决办法
注意:一般遇到这种情况,是由于自己的使用不当造成的,开发过程应该按照流程来,flyway 是不支持降级的,所以,即便你发现这个 SQL 没用,你不应该删除,你应该补充一个 SQL ,将你之前那个 SQL 中的语句逻辑上回退掉(如:你之前是创建了表,那么这个 SQL 就是删掉这个表)

不合规的解决办法
在数据库中,找到你指定的 flyway 的 flyway_schema_history 表,将你要删掉 SQL 文件的那条记录删除掉,重新执行 migrate 就可以了。 不支持这样做

注意

由于在 starter 项目中设置了在启动项目的时候会默认执行 repair 和 migrate 命令,以保证程序的正常运行,所以,请不要再次更改已经执行过的 SQL 脚本,虽然更改了运行也没有问题,但是你的修改信息也是不会生效的,反而会导致 SQL 脚本影响到其他环境的数据


写的不好的地方还请大伙们多多包涵哈~
要是能帮忙指出更是十分感谢了!
要是文章写得不清不楚的,搞得你都迷糊了,欢迎小伙伴们来交流哈~
在这里插入图片描述
项目地址:
starter 项目地址:https://github.com/QACBoy/linkr-starter-flyway
flywaydb 项目地址:https://github.com/QACBoy/flywaydb

参考链接

https://flywaydb.org/documentation/

https://www.jianshu.com/p/783b87871551

https://blog.csdn.net/xiang__liu/article/details/82780201

https://yq.aliyun.com/articles/269164?spm=a2c4e.11155472.0.0.4ecc3ee3quZEGC

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/595663
推荐阅读
相关标签
  

闽ICP备14008679号