flyway版本号_Flyway 实战:数据库版本管理

背景

在软件开发的过程中,开发人员都会使用版本控制系统来管理我们的代码,例如目前最流行的 Git。为什么要使用版本控制系统呢?保存代码的历史版本、改动记录,实现代码的备份;

解决协同开发过程中不同开发人员代码冲突、版本回退的问题;

实现软件代码的持续集成、持续发布部署;

等等。

那大家有考虑过?每一次软数据库的变更也是需要做版本管理的,考虑以下这些问题:多个环境下的数据库状态是否一致:比如在生产环境修复问题后,是否已经同步到开发环境,测试环境中;

如何获取某个环境中数据库的状态?某个 SQL 脚本是否已经执行过了?

一个新的环境,如何快速地设置你的数据库实例?

特定软件代码版本与数据库 Schema 的兼容问题怎么解决?

等等

这些问题可以通过 Schema migrationJava API,Maven plugin和Gradle plugin;好在它有命令行工具,迁移逻辑用 SQL 脚本写就行了,所以如果是 golang 生态一样可以用。

快速开始

本节将通过 Flyway 命令行工具来体验一下 Flyway,了解一下它的使用方法和工作原理。

前置工作

首先,下载并解压对应平台的 Flyway 社区版到本地,本人使用的环境是 macOS Big Sur + MySQL 5.7。Flyway 支持多个平台创建一个名为 test 的数据库

CREATE DATABASE IF NOT EXISTS `test`;

2. 配置 Flyway 的配置文件path_to_flyway/conf/flyway.conf

# JDBC url to use to connect to the database

flyway.url=jdbc:mysql://127.0.0.1:3306/test

# User to use to connect to the database.

flyway.user=根据实际情况填写

# Password to use to connect to the database.

flyway.password=根据实际情况填写

3. 执行命令flyway info,可以查看当前连接数据的详细状态信息:

创建 Migrations

在 Flyway 中,针对数据库所有变更都称为 MigrationsVersioned Migrations:分为正常的和回滚类型的 Migrations,回滚型的社区版并不支持;

Repeatable Migrations:区别与执行一次的 Migrations,这种类型的可重复执行。

Migrations 可以通过 SQL 脚本或者 Java 编写,本文会选择 SQL 脚本来编写,需要注意一点的是 SQL 脚本的命名规则(可通过 Flyway 配置文件配置),否则 Flyway 会提示找不到对应的 Migrations 脚本。如下图所示,Prefix 为类型;Version 为版本,可用点或下划线分割;Separator 为分隔符,用两个下划线表示;Description 为描述信息;Suffix 为后缀。在path_to_flyway/sql目录下创建一个V1__Create_person_table.sql脚本:

create table Person (

ID int not null,

NAME varchar(100) not null

);

2. 执行命令flyway migrate,执行成功会输出一下内容(还可以通过命令flyway info来查看数据库的状态):

3. 再创建一个名为V2__Add_people.sql脚本,并执行一下flyway info命令:

insert into Person (ID, NAME) values (1, 'Axel');

insert into Person (ID, NAME) values (2, 'Mr. Foo');

insert into Person (ID, NAME) values (3, 'Ms. Bar');

从上图中的命令输出可以发现,因为第二条脚本未应用到当前数据库,所以有一个处于 Pending 状态的数据。

4. 最后再执行命令flyway migrate,就可以将最新的脚本应用到数据库中了。

理解以上这些内容后,我们就已经正式入门 Flyway 了。除了migrate,info这两个命令外,还有以下几个命令,baseline命令用于已存在数据表的数据库:

项目实战

那么我们在实际的项目如何应用 Flyway 呢?本节将结合实际工作项目来说明,目前我们的服务的运行环境为腾讯云的 TKE,所以本文考虑基于 K8s 来使用 flyway,这里考虑有以下两种方案:

方案一 K8s Job

方案一的思路是在项目中创建一个目录sql保存 SQL 脚本,同时,在构建服务镜像的同时,也构建一个 Migration 镜像(即将 SQL 脚本与 flyway 镜像打包到一起)打包到一起;最后在 TKE 中创建一个 K8s Job 来执行 migrate 等命令。整个方案的可行性是 OK 的,但是会存在的一些问题:缺乏灵活性,不方便,例如每一次执行 flyway 命令都得创建一个 K8s Job;

可能导致部署,构建过程变慢,flyway 的镜像大小近 400 M;

等等

方案二 K8s Deployment

方案二的思路是将 SQL 脚本与 flyway 镜像独立打包,然后利用 K8s Deployment 起一个常驻的 flyway 服务, flyway 官方镜像只能运行一次,所以需要基于 flyway 官方的 dockerfile 进行改造,去掉原ENTRYPOINT ["flyway"]入口,改为死循环每 60 秒打印 flyway 字符串,具体如下所示:

# 省去上面一样的内容CMD ["/bin/bash", "-c", "while true; do echo flyway; sleep 60;done"]设置环境变量

在创建 flyway 服务时,可以设置以下数据库相关的环境变量,然后通过 TKE 的远程登陆服务,进入到容器中执行flyway -user=${DB_USER} -password=${DB_PASSWORD} -url=${DB_URL}${DB_NAME} info:info 命令输出

最后,如果我们要执行命名migrate话,需要将 SQL 脚本保存到 flyway 镜像的/flyway/sql目录下,那么如何来处理呢?我们可以通过共享存储卷init container 的方式,将 SQL 脚本复制到/flyway/sql中,如下图所示:共享存储卷

通过方案二这种方式,我们就可以有一个常驻的服务可以执行 flyway 命令了;如果要更新 SQL 只要更新 init container 即可。

参考

你可能感兴趣的:(flyway版本号)