Spring Boot数据库版本控制工具技术方案

2 篇文章 0 订阅
1 篇文章 0 订阅

1. 数据库版本困境

  在大家的日常开发过程中,肯定使用过代码版本控制工具,并且使用得十分熟练,但是对于数据库,有没有进行版本控制呢?我猜大部分企业和开发者都没有使用到数据库版本工具,如果没有使用,可能会遇到如下问题:

  1. 当前环境下的数据库处于什么状态?
  2. 多环境下数据库版本是否保持一致呢?例如刚刚修复线上的数据库变更是否应用到了测试和开发环境?
  3. 我们编写的数据库语句是否已经执行了呢?
  4. 在新的环境下,怎么快速设置一个新的数据库实例呢?
  5. 特定软件代码版本与数据库 Schema 的兼容问题怎么解决?

  其实现在的数据版本控制工具成熟的工具很多,在这里,我向大家推荐一款适合于Java开发者的工具——Flyway,在这里我就不过多介绍了,大家可以点击官网。引入了Flyway工具以后,我们可以结合spring boot来解决上述问题,优化数据库部署。

spring boot在父pom中会有引入flyway这个第三方库,大家如果对版本号没什么要求的话,即可立即引用,由此可见flyway这个工具是很成熟的,有着广阔的生态圈。

2. 关键步骤

2.1 样例数据库及版本变化

在这里插入图片描述

图 2.1.1 数据库版本变迁样例

  本次样例的环境如下:

  • spring boot: 1.5.18.RELEASE
  • jdk: 1.8
  • alibaba-druid: 1.1.10
  • flyway:5.2.4

  如果您没有相关flyway基础,可以从第三章核心概念和原理开始看。

2.2 (可选)定义基础版本

  如果当前数据库已经存在表格,依旧是项目介入flyway的时候数据库已经存在(如上图5.0版本),中途接入的话需要在项目的application.properties或者application.yml等配置文件中加入如下配置:

flyway:
  baseline-on-migrate: true  # 当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
  baseline-version: 5.1 # 开始执行基准迁移时对现有的schema的版本打标签,默认值为1.

2.3 定义5.1版本sql

  在maven中引入flyway-core后,在maven resources目录下db/migration文件下新建V5.1.0.20210302.09.16__init_ddl.sql,内容如下:

ALTER TABLE `test`.`ke_order`
ADD COLUMN `creator_name` varchar(50) NULL COMMENT '创建者姓名' AFTER `creator_id`;

2.4 定义5.2版本sql

  新建 V5.2.0.20210310.13.45__新增地址表 并插入数据.sql,内容如下:

DROP TABLE IF EXISTS `address`;
CREATE TABLE `address`  (
  `id` bigint(20) NOT NULL COMMENT '主键id',
  `address_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址名称',
  `longtitude` decimal(20, 7) NULL DEFAULT NULL COMMENT '经度',
  `latitude` decimal(20, 7) NULL DEFAULT NULL COMMENT '维度',
  `gmt_create` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  `gmt_modified` timestamp(0) NULL DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

2.5 启动项目

  启动spring boot项目,控制台没有输出异常日志,可以在数据库已经执行了上述两个sql文件,并在flyway_schema_history表中存在执行记录,如图2.5.1所示:

在这里插入图片描述

图2.5.1 启动项目数据库迁移执行成功

2.6 异常分支流程

  是不是感觉很简单,但是,这只是主流程,在日常大多数情况都不会出现异常,但是由于是方案设计,必须要考虑到各种异常情况,如果在生产环境部署中出现了异常,就应该有相对的补救措施,下面列举常见的异常分支情况:

2.6.1 sql定义错误

  假如在V5.1.0.20210302.09.16__init_ddl.sql文件中输入了错误的sql语句,比如如下语句:

sssss;

ALTER TABLE `test`.`ke_order`
ADD COLUMN `creator_name` varchar(50) NULL COMMENT '创建者姓名' AFTER `creator_id`;

  那么会在项目初次启动的过程中报错提示,如图 2.6.1.1所示:

在这里插入图片描述

图 2.6.1.1 数据文件定义错误导致项目启动报错

  同时在flyway_schema_histroy表中会记录执行的记录,如图 2.6.1.2

在这里插入图片描述

图 2.6.1.2 数据文件定义错误在数据库里面的记录

如果V5.1.0.1__init_ddl.sql文件执行错了以后,我们需要在修正sql文件的同时,把版本对应的数据库记录删除掉再启动项目

2.6.2 修改已存在(迁移)的sql

  如果有其他开发者不小心修改了已存在的数据库迁移脚本,那么flyway会检查文件的哈希值,如果变更在项目启动的过程中会报异常,如图2.6.2.1所示:

在这里插入图片描述

图2.6.2.1 修改已存在sql启动异常

2.6.3 同版本有多个sql文件

  如果一个版本存在多个sql文件,包括同版本号不同描述,那么会如图2.6.3.1所示:
在这里插入图片描述

图2.6.3.1 同版本有多个sql文件

2.6.4 发现有数据库迁移没有应用到数据库

  此异常主要出现于多人开发模式中,如果他人定义迁移版本大于你定义的数据库版本,并且已应用到数据库中,你们出现Caused by: org.flywaydb.core.api.FlywayException: Validate failed: Detected resolved migration not applied to database: 5.1.0.20210302.14.06

2.6.5 存在有错误的迁移

  如果在flyway_schema_history表中某个迁移的success=0的话,就说明这个迁移执行失败,可以通过flyway repair命令或者手动删除该条记录的方式来修正。

2.6.6 常见异常编码汇总

异常编码需求产生原因解决方法
FAULT一个未知错误联系flyway团队,或者提交GitHub issue
VALIDATE_ERROR一些迁移部分设备只有设备编号无设备名称,所有模块中的设备名称补齐(包括GIS的搜索)
FAILED_VERSION_MIGRATION存在失败的版本迁移修正数据库迁移,并执行repair命令或者手动删除数据库记录
FAILED_REPEATABLE_MIGRATION存在失败的可重复迁移修正数据库迁移,并执行repair命令或者手动删除数据库记录
CHECKSUM_MISMACTCH即将应用的迁移和已经被应用的迁移校验和不一样修正回即将应用的迁移,或者取舍留哪个文件

   更多异常请阅读参考资料2。

3. 核心概念和原理

3.1 迁移(Migrations)

  在flyway中,迁移指的是任何对数据库变更就是迁移,迁移通常可以区分为版本迁移可重复迁移:

  • 版本迁移:拥有一个版本号,描述和校验和。版本号必须唯一,描述可以让你清晰地明白这个迁移是干什么的,校验和主要用来检验文件/脚本是否变更。版本迁移是最常用的迁移,他们**有序执行并且只会执行一次。**版本迁移可以细分为两种形式:
    • 常规迁移(regular): 通常用来创建表、数据更新、建立外检等;
    • 撤销迁移(undo):与常规迁移相反,对同版本号的常规迁移进行回退;
  • 可重复迁移:有一个描述和校验和,没有版本号。与版本迁移只会运行一次不同,可重复迁移只要校验和变了就会被再次执行,常见用途:
    • (重新)创建视图、存储过程等;
    • 大量数据重新插入;

  版本迁移和可重复迁移大部分中通过SQL语句来定义,但是还有其他形式可以定义,可支持的定义形式如下:

  1. SQL语句;
  2. JAVA语句,把相关变更通过java语句的方式写入.java文件;
  3. 其他脚本,例如.psl,.bat,.cmd,.sh,.bash,.py等形式;

JAVA语句方式很方便,可以手动写代码,尤其是在分布式环境下需要调用外部接口,或者一些复杂的插入更新逻辑的初始化操作中及其有用。

  在版本迁移中,版本号的定义和使用如图3.1.1所示:

在这里插入图片描述

图3.1.1 同版本有多个sql文件

3.2 flyway关键指令

3.2.1 Migrate

  把数据库迁移到最新的版本,如果sechema history table不存在的话就会创建,也就是之前提到过的flyway_schema_histroy表,如图3.2.1.1所示:

在这里插入图片描述

图3.2.1.1 migrate指令

3.2.2 Clean

  在配置的数据库schema中清除所有对象,包括表、视图、存储过程、触发器,这个操作慎重操作哈。如图3.2.2.1所示:

在这里插入图片描述

图3.2.2.1 clean指令

3.2.3 Info

  打印出所有迁移的细节和状态,如图3.2.3.1所示:

在这里插入图片描述

图3.2.3.1 info指令

3.2.4 Validate

  验证已应用的迁移和本地迁移是否有变更,以防止对已应用的迁移进行变更,如图3.2.4.1所示:

在这里插入图片描述

图3.2.4.1 validate指令

3.2.5 Undo

  执行迁移撤销动作,对应之前讲述的撤销迁移,如图3.2.5.1所示:

在这里插入图片描述

图3.2.5.1 undo指令

3.2.6 Baseline

  对应现有的数据库进行基线操作,指定基线版本,如图3.2.6.1所示:

在这里插入图片描述

图3.2.6.1 baseline指令

3.2.7 Repair

  修复flyway_schema_history表中的错误,也就是之前提到过status=0的字段,还有重新对齐现有迁移的校验和、描述等,如图3.2.7.1所示:

在这里插入图片描述

图3.2.7.1 repair指令

3.3 迁移失败回滚

  Flyway在一个单独的事务中运行每个迁移。如果失败,此事务将回滚。但是对于DDL的事务支持的话,不是所有数据库都OK的,所以如果把DDL和DML写在一个迁移文件里面,如果执行失败了,会导致整体不会回滚,所以通常建议DDL和DML分开写在迁移文件里面。

听说Mysql 8.0开始也支持DDL事务了,有兴趣的大家可以去看看

4. 实施方案

  先说说业内比较通用的项目交付流程,如图4.1所示,从本地->开发->测试->生产,各个环境的版本会不一致。

在这里插入图片描述

图4.1 项目交付流程

  在我们公司,会严格按照这个流程走,如果线上出现什么问题,会先在开发环境里面开发人员自己先测试,然后交给测试人员,测试完毕以后再上生产,而不能在生产上面直接改。

4.1 开发阶段

  对开发者来说,使用flyway数据库版本工具,主要是关注点如果协同定义数据库,很有可能会出现冲突,所以规范相关操作是重中之重,整体流程如图4.1.1下:

在这里插入图片描述

图 4.1.1 开发者数据库变更流程

  其中如果你们本地开发使用的是本地数据库服务,那合入到开发环境的时候就不会有任何问题;如果你们像我这边一样本地和开发环境使用的都是中心数据库,并且支持开发者本地调试,那么在实际过程中可能会遇到如图4.1.2所示的问题:

在这里插入图片描述

图 4.1.2 开发者数据库变更流程

  为了克服上述问题需要进行如下配置:

flyway:
	out-of-order: true #是否开启乱序执行,不开启的话flyway只允许执行版本号递增的迁移
  ignoreMissingMigrations: true #是否忽略丢失的迁移,在本地调试下,会丢失其他开发者定义的数据库迁移

更多spring boot相关配置请阅读参考资料1或者其他官方的配置详情,在这里我就不详细展开水数字了23333

4.2 测试/生产部署

  对于运维部署人员,整体流程则比较简单,如图4.2.1所示:

在这里插入图片描述

图 4.2.1 运维人员部署流程

4.3 其他交付流程

  考虑到有些公司如果线上出现问题以后会直接在线上的版本上修正,而我们开发环境和测试环境在开发其它版本,这时候需要把应用的迁移应用到开发和测试环境中,可以参照参考资料3的方案,可以分为两步走:

  1. 首先我们在特定环境下定义一个更高版本的sql文件;
  2. 然后我们需要重写应用的sql语句,使之能保证可重复运行和幂等性,举个栗子就是插入数据前先检查数据是否存在,如果存在则不做任何事情。

不同数据库的可重复运行和幂等性的sql语句定义方式不同,例如mysql要使用存储过程来检查列是否存在。

  在这里我就不过多扩展了,不然越讲越多了,收不住了>_<,有兴趣的可以在下面留言,大家一起讨论一下。

5. 不同场景下的数据库版本控制

  • 如何处理database-specific sql(依赖数据库的sql语句),可以使用flyway.locations配置项;
  • 零停机下的数据库迁移、大数据迁移,请阅读参考资料3
  • 多schema下的flyway,请阅读参考资料4/5
  • 需要使用上线后使用代码进行数据初始化的场景,这时候我们只需通过定义java代码的迁移变更即可

6. 参考资料

[1] Flyway数据库版本控制器理解与使用
[2] flyway error codes
[3] Database migration with Flyway in large project
[4] Does Flyway support multiple schemas
[5] multiple-datasources-migrations-using-flyway-in-a-spring-boot-application

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: Spring Boot 2.3.0 对应的 Redisson 版本是 3.12.5。你可以在 Spring Boot 官方文档中查看更多关于 Spring Boot 2.3.0 的信息。同时,Redisson 的官方文档中也提供了 Redisson 版本与 Spring Boot 版本之间的对应关系。建议在集成 Redisson 时,选择与你使用的 Spring Boot 版本兼容的 Redisson 版本。 ### 回答2: Spring Boot 2.3.0版本对应的Redisson版本是3.12.3。 Redisson是一个基于Redis的Java驻内存数据网格(In-Memory Data Grid)和分布式计算框架,简化了对分布式数据结构和服务的访问和操作。它提供了多种并发的集合数据结构,如Map、Set、Queue等,并且支持分布式锁和分布式AtomicLong等功能。 在Spring Boot项目中使用Redisson作为Redis的客户端,可以方便地访问和操作Redis服务。Spring Boot 2.3.0版本集成了Redisson 3.12.3作为默认的Redis客户端版本。我们可以直接在pom.xml文件中引入Redisson的依赖,并进行相应的配置,即可使用Redisson连接和操作Redis。 在使用Spring Boot版本为2.3.0的项目中,如果想使用Redisson,可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.12.3</version> </dependency> ``` 然后,在application.properties(或application.yml)文件中配置Redisson的连接信息,如Redis的地址、端口、密码等。配置完毕后,就可以在Spring Boot项目中使用Redisson进行对Redis的访问和操作了。 需要注意的是,Redisson的版本与Spring Boot的版本可能不完全一致,因此在实际使用中,可以根据项目需求选择适合的Redisson版本。 ### 回答3: Spring Boot 2.3.0 对应的 Redisson 版本是 3.12.2。在 Spring Boot 2.3.0 中,Redisson 客户端库通过 Maven 的依赖管理工具进行版本的控制。在 pom.xml 文件中引入 Redisson 的依赖项,并指定版本为 3.12.2,即可使用 Redisson 客户端库的功能。 Redisson 是一个基于 Redis 的分布式 Java 对象和服务框架,它提供了丰富的功能和易于使用的 API,可以方便地与 Redis 数据库进行交互。Redisson 使用了高级的数据结构和算法来优化 Redis 的性能,并提供了分布式的锁、并发处理、分布式对象等功能,使得开发者可以更加方便地使用 Redis 构建分布式应用。 Spring Boot 是一个用于开发独立的、基于生产级别的 Spring 应用程序的框架。它提供了各种扩展和集成,使得开发者能够快速构建可扩展、高性能的应用程序。Spring Boot 2.3.0 版本是其中一个版本,它引入了许多新的功能和改进,并且对 Redisson 客户端库的支持也进行了更新,以保持与 Redisson 的版本兼容。 总结来说,Spring Boot 2.3.0 版本对应的 Redisson 版本是 3.12.2。开发者可以通过在项目的 pom.xml 文件中添加 Redisson 的依赖项,并指定版本为 3.12.2,来使用 Redisson 客户端库的功能。这样可以方便地与 Redis 数据库进行交互,并实现各种分布式应用的需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CuteXiaoKe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值