数据库版本管理工具-Flyway

  Flyway 是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式。Flyway 可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级,并且有一套默认的规约,不需要复杂的配置,Migrations 可以写成 SQL 脚本,也可以写在 Java 代码中,不仅支持 Command Line 和 Java API,还支持 Build 构建工具和 Spring Boot 等,同时在分布式环境下能够安全可靠地升级数据库,同时也支持失败恢复等。

简单介绍

主要特性

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

运行原理

当 Flyway 连接数据库中的 schema 后,会先检查是否已存在 flyway_schema_history 表,如果没有则创建。该表用于跟踪数据库的状态,如数据迁移的版本,迁移成功状态等信息。

当 flyway_schema_history 存在后,Flyway 会扫描文件系统或应用中的 classpath 目录的数据迁移文件,然后根据它们的版本号进行按序迁移,如下图:

flyway_schema_history 表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for flyway_schema_history
-- ----------------------------
DROP TABLE IF EXISTS `flyway_schema_history`;
CREATE TABLE `flyway_schema_history` (
`installed_rank` int(0) NOT NULL,
`version` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`description` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`type` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`script` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`checksum` int(0) NULL DEFAULT NULL,
`installed_by` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`installed_on` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
`execution_time` int(0) NOT NULL,
`success` tinyint(1) NOT NULL,
PRIMARY KEY (`installed_rank`) USING BTREE,
INDEX `flyway_schema_history_s_idx`(`success`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

由于 flyway_schema_history 表中记录了迁移的版本号,如果文件的版本号小于或等于标记为当前版本的版本号,则忽略它们不执行。

整合springboot

添加依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

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

application.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 1234
flyway:
enabled: true
# 禁止清理数据库表
clean-disabled: true
# 如果数据库不是空表,需要设置成 true,否则启动报错
baseline-on-migrate: true
# 与 baseline-on-migrate: true 搭配使用
baseline-version: 0
locations:
- classpath: db/migration/mysql

将需数据迁移的 sql 文件放置到 db/migration/mysql 目录中,启动 Spring Boot 项目即可运行 Flyway 进行数据迁移。(此处本人测试出错,如果不行,也可不指定使用默认的文件夹目录)

创建sql文件

在项目的 src/main/resources 下创建 db/migration 目录,该目录下放置需要数据迁移的sql文件。
数据迁移文件名称格式为:V[version]__[name].sql,V大写。
注意:名称中[version]和[name]之间是两个下划线!例如V1.0.0__wjup_test.sql

运行

flyway会在项目启动时自动加载sql文件并执行。

注意事项:

如果 flyway 不是项目初期引入,而是在数据库已有表的情况下引入时必须设置 baseline-on-migrate: true,设置该配置启动项目后,flyway 就会在数据库中创建 flyway_schema_history 表,并且会往该表中插入一条 version = 1 的建表记录,如果迁移数据有 V1__ 开头的文件,扫描文件会忽略该文件不执行迁移,进而可能引发其他迁移数据出错的问题。

参考资料

Flyway 官网
Spring Boot 文档


-------------本文结束感谢您的阅读-------------
感觉文章不错,就赏个吧!
0%