|- 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>
    
  2. yml 文件中的配置如下

    配置中心的配置信息:

    flywaydb:
      url: ${spring.datasource.url}
      username: username
      password: password
    

    注意

    要求数据库账号 除了拥有正删改查操作外还需拥有能够操作数据表的权限,因为第一次引进 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
关于脚本的变更的问题

修改 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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,可以得知flyway是一个数据库版本管理工具,可以帮助开发人员更好地管理数据库的版本。而flyway-mysql则是flyway针对MySQL数据库的一个插件,可以帮助开发人员更好地管理MySQL数据库的版本。 要使用flyway-mysql,需要按照以下步骤进行操作: 1. 在pom文件中添加flyway和MySQL的驱动依赖,如下所示: ```xml <dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId> <version>5.2.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.21</version> </dependency> ``` 需要注意的是,flyway的版本和spring boot的版本需要兼容,否则会出现异常。 2. 在application.properties文件中配置MySQL数据库的连接信息,如下所示: ```properties spring.datasource.url=jdbc:mysql://127.0.0.1/resty-demo?useUnicode=true&characterEncoding=UTF-8 spring.datasource.username=dev spring.datasource.password=dev1010 ``` 3. 在resources目录下创建db/migration目录,并在该目录下创建SQL脚本文件,如下所示: ```sql V1__create_user_table.sql CREATE TABLE user ( id INT PRIMARY KEY, name VARCHAR(50), age INT ); ``` 其中,V1__create_user_table.sql是一个版本号为1的SQL脚本文件,用于创建user表。 4. 在启动类上添加@EnableFlyway注解,如下所示: ```java @SpringBootApplication @EnableFlyway public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 5. 启动应用程序,flyway会自动检测db/migration目录下的SQL脚本文件,并执行其中的SQL语句,创建数据库表。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值