Flyway基于HighGoDB实现数据库版本管理

本文介绍了Flyway这款工具,它如何通过使用纯SQL脚本和Java代码实现数据库版本管理,包括版本集成、主要特性、工作原理、配置详解以及在SpringBoot项目中的实战应用。重点讲解了如何解决企业版数据库中关于角色权限的问题。
摘要由CSDN通过智能技术生成

Flyway基于HighGoDB实现数据库版本管理

1. 我们为什么需要数据库的版本集成?

假设我们有一个名为demo的项目,项目的主要交付物就是提供一块叫做demo soft的代码并连接到名为demo db的数据库。

如果用一个图来表示上述所意的,应该如下:
在这里插入图片描述
现在我们有了代码和数据库,这也是大多数初创项目所需的所有内容了。

但是随着项目的进展,这种简单的开发模式马上会演变成如下的这种样子:
在这里插入图片描述

现在我们不止一个环境,而是有了开发、测试、灰度、生产等,由于环境数量的增加,给我们带来了更多的挑战。

git、svn等版本管理工具功能强大,可以很好的帮助我们管理代码。

但是,我们的在数据库的版本管理方面做的不那么的好。很多项目还是依靠dba或是scm手动的执行sql脚本,而有的时候,为了临时的解决某些问题,会在这个或是那个环境手动的执行某些脚本,如此这样就会产生很多的问题。比如我如何知道某台机器上面的数据库处于什么状态。sql脚本文件是执行了,还是没有执行?在生产环境执行的脚本文件随后在其他的环境有执行吗?如何启动一台全新的数据库实例,而与其他的数据库实例保持一致?

数据库的持续集成是解决这一混乱问题的好方法,它具有如下优点

  1. 重头重新的创建数据库
  2. 清楚的知道你的数据库现在处于什么样的状态
  3. 以确定的方式从当前版本的数据库集成到新的版本

2.Flyway的主要特征

普通 SQL:纯 SQL 脚本(包括占位符替换)没有专有的XML格式,没有锁定
无限制:使用 Java 代码来进行一些高级数据操作
零依赖:只需运行在 Java6(及以上)和数据库所需的 JDBC 驱动
约定优于配置:迁移时,自动查找系统文件和类路径中的 SQL 文件或 Java 类
高可靠性:在集群环境下进行数据库升级是安全可靠的
云支持:完全支持 Microsoft SQL Azure, Google Cloud SQL & App Engine、Heroku Postgres 和 Amazon RDS
自动迁移:使用 Flyway 提供的 API,让应用启动和迁移同时工作
快速失败:损坏的数据库或失败的迁移可以防止应用程序启动
数据库清理:在一个数据库中删除所有的表、视图、触发器,而不是删除数据库本身

3.Flyway的工作原理

假设一个最简单的场景,我们要在一个空的数据库上面应用flyway。
在这里插入图片描述

flyway首先在数据库上面找一个默认的表名为flyway_schema_history的历史记录表,由于此时,数据库为空,所以flyway会创建一个表名为flyway_schema_history的空表。
在这里插入图片描述

然后flyway会使用此表来跟踪和记录数据库的日志状态。

创建了flyway_schema_history之后,flyway马上会扫描文件系统或是web应用下的classpath路径下的sql文件(如下的介绍默认使用sql文件做为migrations文件)或是java文件为migration做准备。

找到migrations文件之后,会按照version number升序排列,然后依次的执行migrations文件。
在这里插入图片描述

每执行一次migrations文件,flyway_schema_history表的内容相应的就发生变化。
在这里插入图片描述

如果数据库已经有了flyway_schema_history表,且其中记录了相应的版本信息,我们现在看一下flyway_schema_history是如何做版本升级的。flyway马上会扫描文件系统或是web应用下的classpath路径下的migrations文件为migration做准备。如果扫描到的migrations文件的版本号小于或是等于当前flyway_schema_history记录的标本号,这些migrations文件会被忽略。而剩下的migrations文件就是准备执行的migrations文件。
在这里插入图片描述

这些剩余的migrations文件会按照version number升序排列并执行,flyway_schema_history也会相应的记录版本更新的情况。
在这里插入图片描述

所以如果你想升级数据库的版本信息,不管是DDL或是DML语句,只要生成一个migrations文件,并将其version number大于当前的flyway_schema_history记录的当前版本信息即可,当下次flyway执行的时候,就会找到新增的这些migrations文件,并执行和记录新的版本信息。通过这种方式,可以很方便的将相关的升级脚本与代码一同的发布。

4.Flyway配置属性详解

Url:连接数据库的jdbc的url
Driver:连接数据库的jdbc驱动的class全名,默认为空,flyway会根据url⾃动查找匹配的驱动
User:连接数据库的⽤户名
Password:连接数据库的⽤户名对应的密码
connectRetries:连接数据库的最⼤的重试次数,每次尝试失败后,flyway会等待⼀秒然后继续重试到最⼤次数为⽌(不设置,就不重试,快速的失败)
initSql:连接上数据库之后的初始化sql
defaultSchema:默认的schema,⼤⼩写敏感,是flyway在执⾏过程中默认的schema,flyway_schema_history包含在这个schema⾥⾯,flyway的6.1版本之后,如果没有指定schema,那么默认使⽤schemas属性配置的第⼀个schema
Schemas:使⽤逗号分隔,⼤⼩写敏感,除⾮配置的第⼀个schema已经存在,不然会创建所有的schema,所有的schema会按照顺序做clean操作
Table:默认名flyway_schema_history,如果在schemas配置了多个schema,那么flyway_schema_history表在第⼀个schema⾥⾯
Tablespace:创建flyway_schema_history的表空间,此设置仅与⽀持表空间概念的数据库相关。对其它数据库不起作⽤
Locations:locations使⽤逗号分隔,会对其指定的location进⾏递归查找,location的类型依配置的location的前缀⽽定,没有前缀的location或是以classpath:标记的location会在classpath上扫描sql或是java⽂件,以filesysytem标记的location会在⽂件系统上递归的查找⾮隐藏的migration⽂件,⽽且可以使⽤通配符
Color:仅仅应⽤于命令⾏使⽤,是否可以对于输出添加颜⾊,默认是auto,可以有always和never其它的两个选项
jarDirs:逗号分隔,驱动⽂件和基于Java的migration⽂件所在⽬录
sqlMigrationPrefix:migration⽂件的前缀,默认为V
undoSqlMigrationPrefix:undo⽂件前缀,默认是U
repeatableSqlMigrationPrefix:repeat⽂件前缀,默认是P
sqlMigrationSeparator:migration⽂件分隔符,默认是__
sqlMigrationSuffixes:migration⽂件后缀,默认是.sql
validateMigrationNaming:是否验证migration⽂件,默认是false,如果migration⽂件名格式不满⾜要求,skip,如果为true,快速失败
Stream:是否对migration⽂件流化处理,⽽不是全部的加载到内存之后再处理(如果migratio⽂件很⼤,如1GB,⼀般也不会遇到这样的情况)
Batch:是否对migration⽂件进⾏批处理,可以节约带宽,对于处理⼤的migration⽂件⽽⾔
Encoding:migration⽂件编码
placeholderReplacement:是否进⾏占位符替换,默认为true
placeholderPrefix:占位符前缀,默认为${
placeholderSuffix:占位符后缀,默认为}
Resolvers:migration⽂件解析器,逗号分隔的全class⽂件名,相当于可以扩展内置的resolvers解析器
skipDefaultResolvers:是否skip内置的解析器只使⽤定制化的解析器,默认是false
callbacks:逗号分隔的class⽂件名,在flyway⽣命周期内被回调引⽤
skipDefaultCallbacks:是否skip内置的callbacks,默认false
target:migration时数据库的版本,最好使⽤默认值
outOfOrder:是否可以⽆序执⾏,维持默认即可
ignoreMissingMigrations:忽略丢失的migration⽂件,默认是false,针对⽼的系统可以进⾏ 

5.Flyway命令

Migrate:迁移操作,对于每次数据库进行版本迁移的操作。将sql脚本中的内容进行执行记录	
Baseline:初始化 schema_version 表,并插入一条原始 version = 1 。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以在已有表结构的数据库中实现添加Metadata表。
Clean:清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用,但在生产环境务必禁用。
Info:用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本。
Repair:repair操作能够修复metaData表,该操作在metadata出现错误时很有用。
Undo:撤销操作,社区版不支持。
Validate:验证已经apply的Migrations是否有变更,默认开启的,原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。

6.Migration

Flyway将每一个数据库脚本称之为migrations,flyway支持三种类型的migration:

  1. Versioned migrations:最常用的migration,可以简单的理解为数据库升级脚本
  2. Undo migrations:数据库版本回退脚本,需要Pro版本,忽略,而且使用过程存在较大风险,undo操作目前只能通过plugin或者command-line来执行
  3. Repeatable migrations:可重复执行的migration,例如create or replace脚本,当脚本checksums改变时会重新执行

每个migration支持两种编写方式:

  1. Java:通过实现 org.flywaydb.core.api.migration.jdbc.JdbcMigratio 接口来创建一个Java migration,也就是通过JDBC来执行SQL,对于类是CLOB或者BOLB这种不方便在SQL中实现的脚本比较有用,例如:
package db.migration;
import org.flywaydb.core.api.migration.jdbc.JdbcMigration;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class V1_2__Another_user implements JdbcMigration {
    public void migrate(Connection connection) throws Exception {
        PreparedStatement statement = connection.prepareStatement("INSERT INTO test_user (name) VALUES ('Obelix')");
        try {
            statement.execute();
        } finally {
            statement.close();
        }
    }
}
  1. SQL:简单的SQL脚本文件,例如:
CREATE TABLE test_user (
  name VARCHAR(25) NOT NULL,
  PRIMARY KEY(name)
);
INSERT INTO ${tableName} (name) VALUES ('Mr. T');

所有的migration都需要遵守命名规范:
在这里插入图片描述

确保版本号唯一,flyway按照版本号顺序执行。repeatable没有版本号,因为repeatable migrations会在内容改变时重复执行。

7.基于spring boot的flyway实战

  1. 在pom文件中引入依赖
<dependency>
     <groupId>org.flywaydb</groupId>
     <artifactId>flyway-core</artifactId>
     <version>6.0.8</version>
</dependency>
  1. application.yml配置
    在这里插入图片描述

  2. 在resources的db/migration目录下面添加sql脚本
    在这里插入图片描述

  3. 启动项目,查看控制台输出
    在这里插入图片描述

8.Flyway jar包引用注意事项

报错:{conn-10005, pstmt-20009} execute error. SET ROLE ‘sysdba’

企业版数据库不会报错,安全版数据库报 set role 无权限错误。

解决方案(两种方案任选其一):

  1. 关闭安全版数据库三权
  2. 更改flyway源码
    下载flayway源码,修改类文件org.flywaydb.core.internal.database.postgresql.PostgreSQLConnection.java
protected void doRestoreOriginalState() throws SQLException {
  #添加下面一行代码
  this.jdbcTemplate.execute("SET application_name to securedump");
  this.jdbcTemplate.execute("SET ROLE '" + this.originalRole + "'");
}

重新打包,替换项目中引用的flayway原有jar包。

  • 17
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值