Flyway详解(使用说明及避坑指南、一文搞懂flyway)

这篇具有很好参考价值的文章主要介绍了Flyway详解(使用说明及避坑指南、一文搞懂flyway)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、简介

1.1 Flyway是什么?

Flyway是一款开源的数据库版本管理工具,可以实现管理并跟踪数据库变更,支持数据库版本自动升级,而且不需要复杂的配置,能够帮助团队更加方便、合理的管理数据库变更。
例:创建两个sql变更文件,项目启动后会将两个文件中的sql语句全部执行。

1.2 为什么使用Flyway?

简单举个例子:开发时,如果A开发和B开发都对同一数据库进行了修改,那么如何进行数据同步呢?假如多个开发人员都修改了sql脚本,怎么同步到测试环境和生产环境?
类似于以上的情况在日常开发中不胜枚举,在最开始的单体架构中,我们公司采用了通过校验数据库版本号来实现sql的变更,这虽然能够解决大部分问题,但每次都需要维护变更sql的代码和数据库版本号,且对于后续服务上云也是十分不便的。因此我们需要对数据库校验的方案进行调整,就去调研了目前市面上比较流行的Flyway和Liquibase,综合对比下来,最终选择了Flyway作为后续的数据库版本管理工具,具体差异如下:
Flyway详解(使用说明及避坑指南、一文搞懂flyway)

1.3 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_schema_history的历史记录表,这张表会用来跟
踪或记录数据库的状态,然后每次启动时都会自动扫描在resources/db/migration下的文件并且通过查
询flyway_schema_history来判断是否为新增文件,从而判断是否进行迁移。
默认的查找 migration 的路径为 classpath:db/migration ,对应 SQL 文件可放置在
src/main/resources/db/migration 下,Java 类可放置在 src/main/java/db/migration 下

1.3.1 Flyway的校验版本号算法

flyway在升级数据库时会先计算之前已经升级过的脚本的checksum值和数据库的checkSum值进行比对,如果老脚本发生了变化后checkSum校验就会失败,从而抛出异常,checkSum计算算法为(CRC32 (循环冗余校验码)算法)。
新增的脚本则会和数据库中的版本号进行比较,如果小于数据库存储的最后一个版本号,也不会继续执行。

1.3.2 Flyway的锁机制

Flyway使用数据库锁机制(locking technology of your database)来协调多个节点,从而保证多套应用程序可同时执migration,而且集群控制也可做配置。基于数据库锁机制实现分布式锁有两种,基于数据库表和基于数据库排他锁,Flyway采用的是基于数据库排他锁。

排他锁(Exclusive Locks,简称X锁),又称为写锁、独占锁,在数据库管理上,是锁的基本类型之一。若
事务T对数据对象A加上X锁,则只允许T读取和修改A,其他任何事务都不能再对A加任何类型的锁,直到T释放
A上的锁。这就保证了其他事务在T释放A上的锁之前不能再读取和修改A

源码如下:

@Override
public <T> T lock(Table table, Callable<T> callable) {
		if (database.isPxcStrict()) {
		return super.lock(table, callable);
}
	return new MySQLNamedLockTemplate(jdbcTemplate,table.toString().hashCode()).execute(callable);
}
@Override
protected void doLock() throws SQLException {
		jdbcTemplate.execute("SELECT * FROM " + this + " FOR UPDATE");
}
private boolean tryLock() throws SQLException {
		return jdbcTemplate.queryForInt("SELECT GET_LOCK(?,10)", lockName) == 1;
}

1.3.3 Flyway连接数据库

flyway使用JDBC连接数据库

private boolean hasUserVariableResetCapability() {
	try {
		jdbcTemplate.queryForStringList(userVariablesQuery);
		return true;
	} catch (SQLException e) {
		LOG.debug("Disabled user variable reset as " + (database.isMariaDB() ? USER_VARIABLES_TABLE_MARIADB :USER_VARIABLES_TABLE_MYSQL)+ "cannot be queried (SQL State: " + e.getSQLState() + ",Error Code: " + e.getErrorCode() + ")");
	return false;
}
}

1.3.4 Flyway的启动速度

耗时主要来源两个方面
(1).Flyway依次读取脚本中内容时的IO开销
(2).Flyway计算脚本checksum值的算法开销
对于IO开销而言,每个脚本如果不是涉及大量的数据变更,只是表结构的变更,脚本的大小都非常小,可以不考虑。

二、Flyway的使用

接下来就进入正题了,flyway该如何使用呢?
以下是Java的使用方式。

2.1 添加依赖

<dependency>
	<groupId>org.flywaydb</groupId>
	<artifactId>flyway-core</artifactId>
	<version>6.5.7</version>
</dependency>

2.2 添加配置

java
spring:
  flyway:
    #是否启用
    enabled: true
	# 可以支持多个location,','隔开
	locations: classpath:db/migration
	#是否创建元数据表
	validate-on-migrate: true
	# flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是
	false 理论上作为默认配置是不科学的。
	clean-disabled: true
	# 如果数据库不是空表,需要设置成 true,否则启动报错
	baseline-on-migrate: true
	# 版本控制日志表,默认flyway_schema_history,不同系统建议修改数据
    # table: flyway_schema_history

2.3 创建sql文件

Flyway详解(使用说明及避坑指南、一文搞懂flyway)

2.4 启动项目即可

三、Flyway详解

3.1 命令行

1.常用命令Migrate, Clean, Info, Validate, Baseline, Repair。

2.Migrate是指把数据库默认数据库迁移到最新版本。

3.Clean这个命令会清除指定库下所有的对象,包括table、view、triggers…,让数据库变成空的状态。

4.info用于打印所有Migrations的详细和状态信息。

5.Validate是指验证已经应用的Migrations是否有变更,Flyway是默认是开启验证的。

6.Baseline针对已经存在表结构的数据库的一种解决方案,即实现在非空数据库中新建Metadata表,并把Migrations应用到该数据库。

7.Repair操作能够修复Metadata表,该操作在Metadata表出现错误时是非常有用的。

8.Repair会修复Metadata表的错误,通常有两种用途:
①移除失败的Migration记录,该问题只是针对不支持DDL事务的数据库。
②重新调整已经应用的Migratons的Checksums值,比如:某个Migratinon已经被应用,但本地进行了修改,又期望重新应用并调整Checksum值,不过尽量不要这样操作,否则可能造成其它环境失败。

3.2 配置行

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.

3.3 执行方式

Flyway 的 migration 会在 Spring Boot 应用启动时自动执行,如果不想通过启动应用的方式执行,官方
提供了命令行、API、以及 Maven 和 Gradle 插件的方式,但总的来说都会麻烦一些,因为需要将已经
在 Spring Boot 中配置的参数,再到其他执行方式所各自要求的位置重新配置一遍,实用性一般。

3.4 sql脚本命名规则

1.仅需要执行一次的,以大写“V”开头,V+版本后(版本号间的数字以“.” 或者“ _ ”分隔开,“ _ ”会自动编译
成 “ . ” )+" __"+文件描述+后缀名
2.需要执行多次的,以大写“R”开头,命名如R__clean.sql ,R的脚本只要改变了就会执行,R不带版本号
3.V开头的比R开头的优先级要高。

前缀:用于版本控制(可配置)、撤消(可配置)和可重复迁移(可配置)VUR)
版本:带有点或下划线的版本可根据需要分隔任意数量的部分(不适用于可重复的迁移)
分隔符:(两个下划线)(可配置)__)
说明:下划线或空格分隔单词
后缀:(可配置.sql)
(可选)版本控制 SQL 迁移还可以省略分隔符和说明

Flyway详解(使用说明及避坑指南、一文搞懂flyway)

四 开发时注意事项

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文件后启动会报错,报错如下:

If you removed this migration intentionally, run repair to mark the migration as
deleted.

五、部署上线时注意事项

  1. 如果不手动创建元数据表,则需要进行以下配置,用于自动创建
    validate-on-migrate: true
    If you removed this migration intentionally, run repair to mark the migration as
    deleted.
  2. 如果数据库不是空表,则需进行以下配置,否则启动报错
    baseline-on-migrate: true
  3. clean命令会删除数据库中所有表,包括数据,结构等,这是不合理的,所以需要进行以下配置
    clean-disabled: true (该配置由于默认值不合理,所以在V9版本中修改默认值由false为true)
  4. 使用flyway要注意版本兼容问题,springboot与flyway,flyway与数据库版本,否则启动报错
  5. 如果启动的时候像忽略某些迁移文件,可进行以下参数配置
    baseline-version=20210809,以忽略 20210809 版本以及之前的所有 migration
  6. 多人开发中,如果一个人提交V2一个人提交V1,而V2先入库执行了,那么V1入库就不会执行,如
    果需要执行则需进行如下配置,但是不建议这么做
    out-of-order=true

六、 支持的数据库版本

目前支持mysql5.7的社区版为7.15.0,支持mysql8.0的版本是8.2.0,8.2.1移除了mysql支持,如文档原
文:

Extract MySQL code to plugin. This will need to be added as a new dependency.

flyway的8.2.1版本移除mysql的解决方案,增加依赖:

<dependency>
	<groupId>org.flywaydb</groupId>
	<artifactId>flyway-mysql</artifactId>
</dependency>

七、总结

Flyway的引用确实方便了后续我们团队的数据库版本管理,但各个团队使用场景皆有不同,所以本文只供想要学习Flyway的朋友借鉴,另:flyway的社区版同专业版相比也是有一些区别的,类似下面的两个方面,所以在选择Flyway时需考虑引入对整体架构的提升,本文分享到这里结束,感谢大家耐心观看。
①社区版目前不支持版本回退
②社区版本没有任务队列和异步任务的支持,所以在大量变更时略有风险,尽量拆分文章来源地址https://www.toymoban.com/news/detail-420918.html

到了这里,关于Flyway详解(使用说明及避坑指南、一文搞懂flyway)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【工控老马】三菱Q系列PLC调试及三菱触摸屏报警使用说明详解

    一 程序段注解 第1步 编辑菜单→文档创建→声明编辑 第2步 在左侧空白处双击→弹出行间声明输入弹窗→输入申明内容 第3步 显示如图,转换+全部编译 二 插入比较指令 第1步 编辑菜单→梯形图编辑模式→写入模式 第2步 在需要插入指令的地方双击→输入指令内容 第3步 显示

    2024年02月05日
    浏览(65)
  • 超维空间S2无人机使用说明书——55、代码详解:基础PID算法控制无人机的跟随代码详解

    PID,即比例 Proportion、积分 Integral 和微分 Derivative 三个单词的缩写;比例积分微分控制,简称PID控制。 简单讲,根据给定值和实际输出值构成控制偏差,将偏差按比例、积分和微分通过线性组合构成控制量,对被控对象进行控制。 常规 PID 控制器作为一种线性控制器。 步骤

    2024年01月21日
    浏览(64)
  • 【STM32笔记】低功耗模式配置及避坑汇总

    【STM32】低功耗模式配置及配置汇总 自己做的低功耗库函数: 【STM32】基于HAL库建立自己的低功耗模式配置库(STM32L4系列低功耗所有配置汇总) gitee库 文章总结:(后续更新以相关文章为准) 【STM32笔记】低功耗模式、WFI命令等进入不了休眠的可能原因(系统定时器SysTick一

    2024年02月06日
    浏览(108)
  • 一文搞定Windows11+WSL+Pycharm开发环境及避坑

    众所周知,虽然Windows和Linux都可以运行Python,但是对很多Python扩展包的支持是不一样的。 比如 深度学习相关的pytorch 比如 自动化运维相关的ansible 小编本人也尝试将Ubuntu作为自己的主系统,并且为了逼自己适应,硬是将自己三台电脑(家里台式、笔记本、公司台式)全部装上

    2024年02月11日
    浏览(68)
  • 1.Java接入银联支付(chinapay)教程及避坑点

    一、背景及效果展示 现如今,诸多的供应链系统需要使用电子钱包功能,所以接入银联B2B无卡支付,是很多系统应用需要做的事情。银联支付的类型分很多种:网关支付(带token请求实现,下次有空再分享)、B2B无卡支付(带证书秘钥请求实现)分商户和机构入网,具体和更

    2024年02月12日
    浏览(43)
  • 【VxWorks】VxWorks系统详细介绍说明,环境搭建说明,使用场景,使用实例

    目录 1.VxWorks 概述 2.详细介绍 2.环境搭建说明 3.使用场景 4.使用实例         VxWorks 是一款实时操作系统(RTOS),广

    2024年02月15日
    浏览(43)
  • MSELoss详解+避坑指南

    loss(xi,yi)=(xi−yi)2 loss(xi,yi)=(xi−yi)2 这里 loss, x, y 的维度是一样的,可以是向量或者矩阵,i 是下标。 很多的 loss 函数都有 size_average 和 reduce 两个布尔类型的参数。因为一般损失函数都是直接计算 batch 的数据,因此返回的 loss 结果都是维度为 (batch_size, ) 的向量。 (1)如果 red

    2024年02月05日
    浏览(48)
  • iotop命令使用说明及iotop输出排序操作说明

    iotop是一个用来显示实时的磁盘活动 的工具,可查看哪些程序、进程或线程占用io过多。 iotop监控 Linux 内核输出的 I/O 使用信息,并且显示一个系统中进程或线程的当前 I/O 使用情况。它显示每个进程/线程读写 I/O 带宽。它同样显示当等待换入和等待 I/O 的线程/进程花费的时

    2024年04月12日
    浏览(50)
  • valgrind基本功能介绍、基础使用方法说明 valgrind基本功能介绍、基础使用方法说明

    valgrind基本功能介绍、基础使用方法说明_valgrind使用方法_HNU Latecomer的博客-CSDN博客 拷贝效果不好,请看原文。 1、Valgrind概述 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合。 Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(f

    2024年02月07日
    浏览(61)
  • chatGPT使用说明,相关技巧,使用记录等等

    它的工作原理是基于自然语言处理技术和深度学习算法。当用户输入问题时,我会将问题分解成并进行语义分析,以 理解用户的意图 。接着,我会调用内部的知识库和外部资源,比如搜索引擎、数据库等,寻找与问题相关的答案,并通过 回答、提供链接、建议 等方式

    2024年02月03日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包