摘要

在频繁发布版本的情况下,数据库版本难以控制一直是一个头疼的问题,本文主要介绍如何利用Flyway工具实现数据库版本控制。

概述

数据库的版本控制一般都是通过代码管理工具统一管理SQL脚本,但是仅仅是将脚本与代码一起管理,在应用升级时仍然会碰到很多问题:

  • 无法确认在某台机器上的数据库版本

  • 无法确认是否遗漏了某个数据库脚本未执行

  • 无法确认在某台机器上执行过哪些数据库脚本

  • 代码版本库无法管理数据库脚本依赖关系

    所以,我们需要借助专业的数据库版本管理工具实现数据库的版本控制。Flyway就是一个数据库版本控制工具。Flyway主要有以下功能:

  • Flyway可以自动检测指定目录下的数据升级文件并升级至指定版本

  • Flyway可以自动检测指定目录下的数据回滚文件并回滚至指定版本(专业版功能)

  • Flyway可以检测已执行过的数据升级文件是否有改动及是否有错误

  • Flyway可随时展示当前数据库版本和已执行过的数据库升级

  • Flyway可以依照数据库脚本文件命名规则依次执行数据库脚本

Flayway简介

工作原理

installed_rank version description type script checksum installed_by installed_on execution_time success
1 1 Setup SQL V1__Initial_Setup.sql 1996767037 axel 2016-02-04 22:23:00.0 546 true
2 2 First Changes SQL V2__First_Changes.sql 1279644856 axel 2016-02-06 09:18:00.0 127 true
installed_rank version description type script checksum installed_by installed_on execution_time success
1 1 Setup SQL V1__Initial_Setup.sql 1996767037 axel 2016-02-04 22:23:00.0 546 true
2 2 First Changes SQL V2__First_Changes.sql 1279644856 axel 2016-02-06 09:18:00.0 127 true
3 2.1 Refactoring JDBC V2_1__Refactoring   axel 2016-02-10 17:45:05.4 251 true

利用Flyway命令行工具实现版本控制

本章将简单介绍利用Flyway实现数据库版本控制的过程。本章用来演示的数据库为本机MySQL数据库,数据库实例名为test。

安装

Flyway的安装过程比较简单,只需从官网下载安装包并解压至服务器并解压Flyway-commandline将其添加至环境变量即可。Flyway 社区版安装包目录结构如下:

配置

执行Flyway命令通常需要准备两种文件:Flyway配置文件和数据库升级脚本。数据库升级脚本即为普通SQL脚本,本文不做赘述。如图4所示,全局的Flyway配置文件位于Flyway安装包conf目录下。本文使用的配置文件如下:

flyway.url=jdbc:mysql://localhost:3306/test #数据库jdbc连接地址
flyway.user=root   #数据库用户名
flyway.password=password   #数据库密码
flyway.schemas=test        #需要升级的数据库实例名
flyway.encoding=UTF-8  #编码格式

注意:

升级数据库

G:\flywaydb\demo>flyway info
Flyway Trial Edition 5.0.7 by Boxfuse
Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Schema version: << Empty Schema >>+-----------+---------+--------------+------+--------------+---------+----------+
| Category  | Version | Description  | Type | Installed On | State   | Undoable |
+-----------+---------+--------------+------+--------------+---------+----------+
| Versioned | 1.0.0.0 | init sample  | SQL  |              | Pending | No       |
| Versioned | 1.1.0.0 | feature 8126 | SQL  |              | Pending | Yes      |
| Versioned | 1.1.0.1 | bug 8527     | SQL  |              | Pending | No       |
+-----------+---------+--------------+------+--------------+---------+----------+
可以看到当前目录下共有3个数据库升级文件,其状态都为Pending,即表示Flyway已检测到该数据升级文件,但尚未执行。
G:\flywaydb\demo>flyway migrate
Flyway Trial Edition 5.0.7 by Boxfuse
WARNING: You are using the 30 day limited Flyway Trial Edition. After 30 days yDatabase: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Successfully validated 4 migrations (execution time 00:00.045s)
Creating Schema History table: `test`.`schema_history`
Current version of schema `test`: << Empty Schema >>
Migrating schema `test` to version 1.0.0.0 - init sample
Migrating schema `test` to version 1.1.0.0 - feature 8126
Migrating schema `test` to version 1.1.0.1 - bug 8527
Successfully applied 3 migrations to schema `test` (execution time 00:07.092s)

可以看到数据库已成功升级为最高版本1.1.0.1,且可以看到升级顺序为按照版本号从低到高依次升级。

G:\flywaydb\demo>flyway info
Flyway Trial Edition 5.0.7 by Boxfuse
Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Schema version: 1.1.0.1+-----------+---------+--------------+------+---------------------+---------+----------+
| Category  | Version | Description  | Type | Installed On        | State   | Undoable |
+-----------+---------+--------------+------+---------------------+---------+----------+
| Versioned | 1.0.0.0 | init sample  | SQL  | 2018-05-11 10:50:12 | Success | No       |
| Versioned | 1.1.0.0 | feature 8126 | SQL  | 2018-05-11 10:50:13 | Success | Yes      |
| Versioned | 1.1.0.1 | bug 8527     | SQL  | 2018-05-11 10:50:13 | Success | No       |
+-----------+---------+--------------+------+---------------------+---------+----------+

可以看到数据库当前版本为1.1.0.1,共执行3次数据升级,状态均为成功。

管理已有数据库

上面的升级是基于一个没有数据的新库,在实际场景中都需要在已有数据的数据库上做版本管理。比如数据量比较大或已有应用在使用的数据库,不能清空数据库重新导入,Flyway通过baseline的概念也能很好的支持这种场景。下面我们就演示一下如何使用flyway管理已有数据库。我们仍使用与上面相同的配置文件和数据库升级文件,操作步骤如下:

G:\flywaydb\demo>flyway clean
Flyway Trial Edition 5.0.7 by Boxfuse
Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Successfully cleaned schema `test` (execution time 00:01.705s)
此时查询该数据库可以看到数据库已没有任何数据。
  • 使用mysql客户端连接工具手动执行V1_0_0_0__init_sample.sql,现在数据库的版本为已初始化状态,即1.0.0.0版本,但是该版本号尚未被flyway管理。

  • 使用flyway info查看当前数据库版本和状态:

G:\flywaydb\demo>flyway info
Flyway Trial Edition 5.0.7 by Boxfuse
Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Schema version: << Empty Schema >>+-----------+---------+--------------+------+--------------+---------+----------+
| Category  | Version | Description  | Type | Installed On | State   | Undoable |
+-----------+---------+--------------+------+--------------+---------+----------+
| Versioned | 1.0.0.0 | init sample  | SQL  |              | Pending | No       |
| Versioned | 1.1.0.0 | feature 8126 | SQL  |              | Pending | Yes      |
| Versioned | 1.1.0.1 | bug 8527     | SQL  |              | Pending | No       |
+-----------+---------+--------------+------+--------------+---------+----------+
可以看到当前数据库版本为空,并检测到3个数据升级文件状态都为pending。
  • 执行migrate命令:
G:\flywaydb\demo>flyway migrate
Flyway Trial Edition 5.0.7 by Boxfuse
Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Successfully validated 4 migrations (execution time 00:00.103s)
ERROR: Found non-empty schema(s) `test` without schema history table! Use baseline() or set baselineOnMigrate to true to initialize the schema history table.

此时可以看到Flyway报错了,报错信息中可以看到它的提示:数据库中没有找到版本历史表,请使用baseline命令或设置baselineOnMigrate参数为true初始化Flyway版本历史表。接下来我们执行一下baseline命令看一下效果。

  • 执行baseline命令,我们使用参数指定当前数据库版本,为与本文的数据库升级文件匹配,这里我们使用参数指定当前数据库版本为1.0.0.0,指定描述为init_sample。命令如下:
G:\flywaydb\demo>flyway -baselineVersion=1.0.0.0 -baselineDescription=init_sample baseline
Flyway Trial Edition 5.0.7 by BoxfuseDatabase: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Creating Schema History table: `test`.`flyway_schema_history`
Successfully baselined schema with version: 1.0.0.0

可以看到Flyway创建了版本历史表flyway_schema_history并将基线版本标记为1.0.0.0。

  • 使用info查看当前数据库状态:
G:\flywaydb\demo>flyway info
Flyway Trial Edition 5.0.7 by Boxfuse
Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Schema version: 1.0.0.0+-----------+---------+--------------+----------+---------------------+---------+----------+
| Category  | Version | Description  | Type     | Installed On        | State   | Undoable |
+-----------+---------+--------------+----------+---------------------+---------+----------+
| Versioned | 1.0.0.0 | init_sample  | BASELINE | 2018-05-11 11:40:07 | Success | No       |
| Versioned | 1.1.0.0 | feature 8126 | SQL      |                     | Pending | Yes      |
| Versioned | 1.1.0.1 | bug 8527     | SQL      |                     | Pending | No       |
+-----------+---------+--------------+----------+---------------------+---------+----------+

可以看到当前数据库版本为1.0.0.0,执行过一次baseline操作,并且结果中未展示V1_0_0_0__init_sample.sql文件,因为flyway只会展示比当前版本高的升级文件,不符合Flyway命名规范的文件和版本号低于或等于当前版本的文件都被忽略。

  • 执行migrate命令升级数据库版本,此时可以看到数据库从当前版本依次升级至最高版本1.1.0.1。
G:\flywaydb\demo>flyway migrate
Flyway Trial Edition 5.0.7 by Boxfuse
Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Successfully validated 4 migrations (execution time 00:00.125s)
Current version of schema `test`: 1.0.0.0
Migrating schema `test` to version 1.1.0.0 - feature 8126
Migrating schema `test` to version 1.1.0.1 - bug 8527
Successfully applied 2 migrations to schema `test` (execution time 00:01.209s)

通过上面的实验可以发现使Flyway管理已有数据库只需先使用baseline命令初始化数据库版本或者在Flyway配置文件中配置baselineOnMigrate=true,接下来就可以正常升级数据库了。

回滚数据库

数据库回滚也是数据库版本管理中常见的场景,Flyway使用undo命令执行回滚操作,undo命令执行过程与migrate类似。注意:社区版Flyway不支持undo操作,如果需要数据库回滚功能请下载专业版或企业版。下面演示数据库回滚操作。

G:\flywaydb\demo>flyway info
Flyway Trial Edition 5.0.7 by Boxfuse
WARNING: You are using the 30 day limited Flyway Trial Edition. After 30 days you must remove thDatabase: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Schema version: 1.1.0.1+-----------+---------+--------------+----------+---------------------+---------+----------+
| Category  | Version | Description  | Type     | Installed On        | State   | Undoable |
+-----------+---------+--------------+----------+---------------------+---------+----------+
| Versioned | 1.0.0.0 | init_sample  | BASELINE | 2018-05-11 11:40:07 | Success | No       |
| Versioned | 1.1.0.0 | feature 8126 | SQL      | 2018-05-11 13:38:27 | Success | Yes      |
| Versioned | 1.1.0.1 | bug 8527     | SQL      | 2018-05-11 13:38:27 | Success | No       |
+-----------+---------+--------------+----------+---------------------+---------+----------+

可以看到当前数据库版本为1.1.0.1,共执行过两次升级和一次baseline操作,需要注意的是版本历史表有一列数据名为Undoable,1.1.0.0这个版本被标记为yes,其他为no,该列即用来标识该版本是否可以回滚,Flyway检测到与升级文件版本号一致的回滚文件时就将该版本标记为可回滚的。

G:\dataman\外汇\技术文档\flywaydb\demo>flyway undo
Flyway Trial Edition 5.0.7 by Boxfuse
WARNING: You are using the 30 day limited Flyway Trial Edition. After 30 days you must remove this verDatabase: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Current version of schema `test`: 1.1.0.1
ERROR: Unable to undo migration to version 1.1.0.1 as no corresponding undo migration has been found.

可以看到Flyway提示错误:当前版本为1.1.0.1,没有找到当前版本对应的回滚文件。执行回滚操作需要由高版本到低版本依次回滚,不能直接回滚某一个低版本,按照提示我们将U1_1_0_0__feature_8126.sql改为U1_1_0_1__feature_8126.sql,与当前版本对应。

G:\flywaydb\demo>flyway undo
Flyway Trial Edition 5.0.7 by BoxfuseDatabase: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Current version of schema `test`: 1.1.0.1
Undoing migration of schema `test` to version 1.1.0.1 - feature 8126
Successfully undid 1 migration to schema `test` (execution time 00:01.575s)

可以看到这次数据库回滚成功了,执行回滚的版本是1.1.0.1。

G:\flywaydb\demo>flyway info
Flyway Trial Edition 5.0.7 by Boxfuse
Database: jdbc:mysql://localhost:3306/test (MySQL 5.5)
Schema version: 1.1.0.0+-----------+---------+--------------+----------+---------------------+---------+----------+
| Category  | Version | Description  | Type     | Installed On        | State   | Undoable |
+-----------+---------+--------------+----------+---------------------+---------+----------+
| Versioned | 1.0.0.0 | init_sample  | BASELINE | 2018-05-11 11:40:07 | Success | No       |
| Versioned | 1.1.0.0 | feature 8126 | SQL      | 2018-05-11 13:38:27 | Success | No       |
| Versioned | 1.1.0.1 | bug 8527     | SQL      | 2018-05-11 13:38:27 | Undone  |          |
| Undo      | 1.1.0.1 | feature 8126 | UNDO_SQL | 2018-05-11 14:26:11 | Success |          |
| Versioned | 1.1.0.1 | bug 8527     | SQL      |                     | Pending | Yes      |
+-----------+---------+--------------+----------+---------------------+---------+----------+

可以看到当前数据库版本为1.1.0.0,最后新增了一条数据库回滚的记录。通过本实验可以发现Flyway使用回滚脚本完成数据库回滚,回滚脚本的版本必须要与升级版本一致,且版本号从高到低依次回滚。

总结

Flyway是一个优秀的数据库版本管理工具,简单灵活易操作,每当需要升级数据库时,无论是修改表结构结构(DDL)还是数据(DML),只需创建一个比当前版本号更高的新升级文件。下一次Flyway启动时,它将找到新版本的升级文件并相应地升级数据库。很好的解决了,应用数据库升级的痛点。可以广泛使用在应用升级过程中。

Flyway常用配置

配置 说明
spring.flyway.baseline-description 对执行迁移时基准版本的描述
spring.flyway.baseline-on-migrate 当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false
spring.flyway.baseline-version 开始执行基准迁移时对现有的schema的版本打标签,默认值为1
spring.flyway.check-location 检查迁移脚本的位置是否存在,默认false
spring.flyway.clean-on-validation-error 当发现校验错误时是否自动调用clean,默认false
spring.flyway.enabled 是否开启flywary,默认true
spring.flyway.encoding 设置迁移时的编码,默认UTF-8
spring.flyway.ignore-failed-future-migration 当读取元数据表时是否忽略错误的迁移,默认false
spring.flyway.init-sqls 当初始化好连接时要执行的SQL
spring.flyway.locations 迁移脚本的位置,默认db/migration
spring.flyway.out-of-order 是否允许无序的迁移,默认false
spring.flyway.password 目标数据库的密码
spring.flyway.placeholder-prefix 设置每个placeholder的前缀,默认${
spring.flyway.placeholder-replacement placeholders是否要被替换,默认true
spring.flyway.placeholder-suffix 设置每个placeholder的后缀,默认}
spring.flyway.placeholders.[placeholder name] 设置placeholder的value
spring.flyway.schemas 设定需要flywary迁移的schema,大小写敏感,默认为连接默认的schema
spring.flyway.sql-migration-prefix 迁移文件的前缀,默认为V
spring.flyway.sql-migration-separator 迁移脚本的文件名分隔符,默认__
spring.flyway.sql-migration-suffix 迁移脚本的后缀,默认为.sql
spring.flyway.tableflyway 使用的元数据表名,默认为schema_version
spring.flyway.target 迁移时使用的目标版本,默认为latest version
spring.flyway.url 迁移时使用的JDBC URL,如果没有指定的话,将使用配置的主数据源
spring.flyway.user 迁移数据库的用户名
spring.flyway.validate-on-migrate 迁移时是否校验,默认为true

数据库版本控制Flyway相关推荐

  1. flyway版本号_Spring Boot 集成 Flyway 实现数据库版本控制

    在项目迭代开发中,难免会有更新数据库 Schema 的情况,比如添加新表.在表中增加字段或者删除字段等,那么当我对数据库进行一系列操作后,如何快速地在其他同事的电脑上同步?如何在测试/生产服务器上快速 ...

  2. Spring Boot 集成 Flyway 实现数据库版本控制

    在项目迭代开发中,难免会有更新数据库 Schema 的情况,比如添加新表.在表中增加字段或者删除字段等,那么当我对数据库进行一系列操作后,如何快速地在其他同事的电脑上同步?如何在测试/生产服务器上快速 ...

  3. dbv数据库乱码_使用DBV进行数据库版本控制

    dbv数据库乱码 It's good practice to always use a version control system in any of your projects. Be it a ...

  4. 数据库版本控制工具介绍

    Source Safe for SQL Server 网址:http://www.grqsh.com/products.htm?tab=sourcesafe-for-sql-server Source ...

  5. Flyway 数据库版本控制

    背景 在我们日常产品发布的过程中,代码的版本控制可以使用git.svn工具实现.对于数据库每当发布时会出现手动执行sql脚本进行升级数据库,中间经常出现一些漏写.错写情况,对数据库的版本与代码的版本不 ...

  6. flyway数据库版本控制

    一.Flyway简介 Flyway是一款数据库迁移(migration)工具.简单点说,就是在你部署应用的时候,帮你执行数据库脚本的工具.Flyway支持SQL和Java两种类型的脚本,你可以将脚本打 ...

  7. mysql数据库version版本控制_MySQL数据库版本控制

    你用什么方法来控制你的数据库?我已经将所有数据库表作为单独的.sql脚本提交到我们的respository(mercurial).这样,如果团队中的任何成员对employee表进行了更改,比如说,当我 ...

  8. 数据库迁移Flyway

    为什么需要Flyway 日常开发常常会遇到一些这样的场景 小红开发一个模块在本地数据库增加了两个字段,并且改动了dao层的代码提交到git.这时候小黄拉取了代码Run很可能报错. 如果在上线正式环境的 ...

  9. flyway版本号_各个互联网公司都在用的开源数据库控制器Flyway

    开源的数据库控制器 在开发中,我们经常会遇到上线数据库表的情况,代码上我们有git,svn这样优秀的版本控制软件,但是数据库的迭代我们不能使用手工的方式迭代吧?或者说每次上线前手工去数据库执行.这样带 ...

最新文章

  1. 在SpringBoot项目中使用redis简单用法(一)
  2. jquery点击后执行PHP加载div,PHP-将JQuery自动完成附加到由Ajax调用加载的文本字段...
  3. [Spring Cloud Task]6 Spring Batch批处理应用设计原则
  4. MP3Player(附源码)
  5. python画剖面图_如何创建Matplotlib图形与图像和剖面图相匹配?
  6. 使用fluentd管理docker日志
  7. html5简单游戏案例,HTML5存储(带一个粗糙的打怪小游戏案例)
  8. zabbix3.0安装过程记录
  9. ASP.NET-Session cooike
  10. java输出二进制数_Java打印整数的二进制表示(代码与解析)
  11. vue页面引用echart的词云图
  12. docx文档文字怎么加边框_word给正文加边框 word怎样给一段文字加上边框
  13. 【字符串匹配】BF算法
  14. Cluster status reports MDSs behind on trimming
  15. PHPUnit的使用
  16. 批量去除图片的黑色背景,并且统一修改图片尺寸
  17. 模糊PID控制器MATLAB仿真探讨,模糊PID控制器MATLAB仿真探讨
  18. MySQL-获取每个部门在职员工的最高薪水
  19. mysql中声明数组_SQL数据库中怎么定义数组
  20. linux升级n卡驱动,Centos 7 更新 NVIDIA 驱动

热门文章

  1. 基于微信的旅游小程序、景区景点购票小程序、毕业设计、开题报告、毕业论文参考(2)Java管理后台、springboot框架
  2. 三路归并排序(附C++和Java代码)
  3. PHP GD画图步骤
  4. 我以为我很菜,虽然我确实很菜,但现在我菜的理直气壮~
  5. [转帖] c实现拼音首字母筛选
  6. 公众号第三方平台 接入与全网发布
  7. 一个简单的网页计数器
  8. vue 使用xuex来改变后台接口中英文的字段
  9. Windows 无法启用网络发现功能
  10. Ubuntu服务器使用active-backup模式进行网口绑定