我的编程空间,编程开发者的网络收藏夹
学习永远不晚

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

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

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

一、简介

1.1 Flyway是什么?

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

1.2 为什么使用Flyway?

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

1.3 Flyway的工作原理

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

源码如下:

@Overridepublic  T lock(Table table, Callable callable) {if (database.isPxcStrict()) {return super.lock(table, callable);}return new MySQLNamedLockTemplate(jdbcTemplate,table.toString().hashCode()).execute(callable);}
@Overrideprotected 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 添加依赖

org.flywaydbflyway-core6.5.7

2.2 添加配置

javaspring:  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文件

在这里插入图片描述

2.4 启动项目即可

三、Flyway详解

3.1 命令行

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

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

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

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

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

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

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

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脚本命名规则

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

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

在这里插入图片描述

四 开发时注意事项

报错后需要删除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 asdeleted.

五、部署上线时注意事项

  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的解决方案,增加依赖:

org.flywaydbflyway-mysql

七、总结

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

来源地址:https://blog.csdn.net/Jiao1225/article/details/129590660

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

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

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

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

一、简介 1.1 Flyway是什么? Flyway是一款开源的数据库版本管理工具,可以实现管理并跟踪数据库变更,支持数据库版本自动升级,而且不需要复杂的配置,能够帮助团队更加方便、合理的管理数据库变更。 例:创建两个sql变更文件,项目启
2023-08-16

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录