3 Star 3 Fork 1

仰望苍穹 / flyway-example

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

flyway-example

项目介绍

flyway实战
Flyway是一款开源的数据库版本管理工具,Flyway可以独立于应用实现管理并跟踪数据库的变更。
微服务架构下,随着微服务越来越多,如果采用传统的数据库版本管理方案,工作量巨大,且容易出错。
采用Flyway后,运维人员不再需要关注代码与数据库脚本的配套关系了,并且不需要手动执行升级脚本,无疑将大大减少工作量。

flyway介绍

概述

使用Flyway,对数据库的所有更改都称为迁移(migrations)。迁移可以是版本控制的,也可以是可重复的。 版本化迁移有两种形式:常规迁移和撤消迁移。
版本化迁移具有版本、描述和校验和(checksum)。版本必须是唯一的。该描述纯粹是为了让您能够记住每个迁移所做的事情。校验和用于检测意外更改。版本化迁移是最常见的迁移类型。它们被精确地应用一次。 或者,可以通过提供具有相同版本的撤销迁移来撤消它们的效果。 可重复迁移具有描述和校验和,但没有版本。它们不是只运行一次,而是在每次校验和更改时(重新)应用。 在一次迁移运行中,在执行了所有挂起的版本化迁移之后,总是最后应用可重复迁移。可重复迁移按其描述的顺序应用。 默认情况下,版本迁移和可重复迁移都可以用SQL或Java编写,并且可以由多条语句组成。 Flyway自动发现文件系统和Java类路径上的迁移。 为了跟踪哪些迁移已经在何时由谁应用,Flyway在数据库中添加一个schema历史表(flyway_schema_history)。

版本迁移

最常见的迁移类型是版本迁移。 每个版本迁移都有一个版本、一个描述和一个校验和。 版本必须是唯一的。 该描述纯粹是为了让您能够记住每个迁移所做的事情。 校验和用于检测意外更改。每个版本的sql是确定的,并且确定后不允许修改,通过校验和(checksum)即可验证sql是否被修改。 而对于可重复执行的迁移SQL,如果检测到校验和与记录的不一致,该SQL会重新执行。 版本化迁移只应用一次;可重复迁移,如果有修改会重新执行。

版本迁移通常用于

  • 创建/修改/删除 表/索引/外键/...
  • 更新表中的数据
  • 用户数据修正

例如:

CREATE TABLE car (
    id INT NOT NULL PRIMARY KEY,
    license_plate VARCHAR NOT NULL,
    color VARCHAR NOT NULL
);

ALTER TABLE owner ADD driver_license_id VARCHAR;

INSERT INTO brand (name) VALUES ('DeLorean');

每个版本迁移必须分配一个唯一的版本号。 任何用点分隔的数字都是合法的版本号。在大多数情况下,一个简单的递增整数就足够了。 然而Flyway是非常灵活的,下面所有这些版本都是有效的迁移版本:
1
001
5.2
1.2.3.4.5.6.7.8.9
205.68
20130115113556
2013.1.15.11.35.56
2013.01.15.11.35.56
版本化的迁移SQL按其版本的顺序执行,并且只会执行一次。

撤销迁移

撤销迁移与常规版本迁移相反。撤销迁移负责用相同的版本撤销版本迁移的影响。撤消迁移是可选的,不需要运行常规版本迁移。 对于上面的例子,撤销迁移是这样的:

DELETE FROM brand WHERE name='DeLorean';

ALTER TABLE owner DROP driver_license_id;

DROP TABLE car;
重要提示

虽然撤销迁移的想法很好,但不幸的是,它在实践中有时会失败。
一旦发生了破坏性的更改(删除、删除、截断、…),就会开始遇到麻烦。 即使不这样做,最终也会创建用于恢复备份的自制替代方案,这些方案也需要经过适当的测试。
撤销迁移假定整个迁移成功了,现在应该撤销。这无助于在没有DDL事务的数据库上进行失败的版本迁移。
为什么呢?
迁移在任何一个点都可能失败。如果你的SQL文件中有10个SQL语句,第1个、第5个、第7个或第10个陈述都有可能失败。这根本没有办法提前知道。
相反,写撤销迁移是为了撤销整个版本迁移,在这种情况下不会有帮助。 我们发现另一种更好的方法是在DB和当前部署在生产环境中的代码的所有版本之间保持向后兼容性。这样,迁移失败就不是灾难。
旧版本的应用程序仍然与DB兼容,因此您可以简单地回滚应用程序代码、进行研究并采取纠正措施。

这应该辅之以适当的、经过良好测试的备份和恢复策略。
它独立于数据库结构,并且一旦经过测试并证明可以工作,任何迁移脚本都不能破坏它。 为了获得最佳性能,如果您的基础设施支持这一点,我们建议使用底层存储解决方案的快照技术。 特别是对于较大的数据量,这可能比传统的备份和恢复快几个数量级。

可重复的迁移

可重复迁移具有描述和校验和,但没有版本。 它们不是只运行一次,而是在每次校验和更改时(重新)运行。 这对于管理数据库对象非常有用,这些对象的定义可以简单地在版本控制中的单个文件中维护。 它们通常用于:

  • (重新)创建视图/过程/函数/包/…
  • 批量引用数据重新插入

在一次迁移运行中,在执行了所有的版本化迁移之后,总是最后应用可重复迁移。 可重复迁移按其描述的顺序执行。 你需要确保可重复迁移的SQL可以多次执行,而不出现错误。 这通常涉及在DDL语句中使用CREATE或REPLACE子句。
下面是一个可重复迁移的例子:

CREATE OR REPLACE VIEW blue_cars AS  
   SELECT id, license_plate FROM cars WHERE color='blue';

基于SQL的迁移

基于SQL的迁移是最常用的迁移方式。这使中方式很直观、容易理解,并且很容易利用现有的SQL脚本工具进行调试。 直接使用SQL脚本实现数据库版本迁移,消除了理解任何中间转换层的需要。
基于SQL的迁移通常用于:

  • DDL更改(为表、视图、触发器、序列创建/修改/删除语句,…)
  • 修改表中的数据(表中的CRUD操作)
  • 批量数据更改

命名规则

Flyway的SQL文件命名必须遵循如下模式: flyway SQL迁移命名图 SQL文件名由以下部分组成:

  • Prefix(前缀): V 代表版本迁移(可配置),U 代表撤销迁移(可配置), R 代表可重复执行迁移(可配置)。
  • Version(版本号): 带有点或下划线的版本号,可以根据您的需要分隔任意多的部分(不适合可重复迁移)
  • Separator(分隔符): __ (两个下划线) (可配置)
  • Description(描述): 下划线或空格分隔
  • Suffix(后缀): 默认为.sql(可配置)

查找SQL文件

Flyway可以从文件系统与Java类路径下查找SQL的迁移脚本。
查找路径默认为“classpath:db/migration”,它是可以配置的(配置项为locations,可以配置多个路径)。 flyway SQL迁移命名图 在运行时通过文件系统和Java类路径扫描自动发现新的基于sql的迁移。 一旦您配置了想要使用的位置,Flyway将自动获取任何新的SQL迁移,只要它们符合配置的命名约定。
这种扫描是递归的。 指定目录下的非隐藏目录中的所有迁移也将被获取。

语法

Flyway支持所有常规SQL语法元素,包括:

  • 单行或多行语句
  • 单行注释(-)或多行注释(/**/)
  • 特定于数据库的SQL语法扩展(PL/SQL, T-SQL,…)通常用于定义存储过程、包、…

此外,对于Oracle, Flyway还支持SQL*Plus命令。

替换占位符

除了常规的SQL语法,Flyway还支持用可配置的前缀和后缀替换占位符。 默认情况下,它寻找ant风格的占位符,比如${myplaceholder}。
这对于抽象环境之间的差异非常有用。
例如:

/* 单行注释 */
CREATE TABLE test_user (
  name VARCHAR(25) NOT NULL,
  PRIMARY KEY(name)
);

/*
多行
注释
*/

-- 占位符(Placeholder)
INSERT INTO ${tableName} (name) VALUES ('Mr. T');

基于Java的迁移

基于java的迁移非常适合所有不能使用SQL轻松解决的数据库版本迁移。

比如:

  • BLOB和CLOB更改
  • 高级批量数据更改(重新计算、高级格式更改,…)

命名规则

为了能够通让Flyway识别到,基于java的迁移必须实现JavaMigration接口。
然而,通常情况只需要从BaseJavaMigration继承就可以了,因为它采用Flyway的默认命名约定,允许Flyway自动从类名中提取版本和描述。
要做到这一点,类名必须遵循以下命名模式: flyway SQL迁移命名图 文件名由以下部分组成:

  • Prefix(前缀):V表示版本迁移,U表示撤消迁移,R表示可重复迁移
  • Version(版本):下划线(在运行时自动替换为点)可以分隔任意多的部分(不用于可重复迁移)
  • Separator(分隔符):默认__(为两个下划线)

当然,你也可以按照自己的规则来命名Java类,这样的话,版本、描述、迁移类别则通过你的类实现的JavaMigration的方法来提供。

查找Java的版本迁移

Flyway在locations属性引用的包中的Java类路径中发现基于Java的迁移。 flyway SQL迁移命名图

在运行时通过类路径扫描自动发现新的java迁移。 扫描是递归的。
指定包的子包中的Java迁移也会被获取。

校验和和验证

与SQL迁移不同,Java迁移在默认情况下没有校验和,因此不参与Flyway验证的更改检测。
可以通过实现getChecksum()方法来弥补这一点,然后可以使用该方法提供您自己的校验和,然后将对更改进行存储和验证。

Java类示例

package db.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;  
import org.flywaydb.core.api.migration.Context;  
import java.sql.PreparedStatement;  

/**  
 * Example of a Java-based migration.  
 */  
public class V1_2__Another_user extends BaseJavaMigration { 

    public void migrate(Context context) throws Exception {  
    	PreparedStatement statement =  
    		context.getConnection().prepareStatement("INSERT INTO test_user (name) VALUES ('Obelix')");  
    
	    try {  
	    	statement.execute();  
	    } finally {  
	    	statement.close();  
	    }  
    }  
}  

Spring

如果您的应用程序已经使用了Spring,并且您不想直接使用JDBC,那么您可以轻松地使用Spring JDBC的JdbcTemplate:

package db.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import java.sql.PreparedStatement;

/**
 * Example of a Java-based migration using Spring JDBC.
 */
public class V1_2__Another_user extends BaseJavaMigration {
    public void migrate(Context context) {
	    	new JdbcTemplate(new SingleConnectionDataSource(context.getConnection(), true))
	    		.execute("INSERT INTO test_user (name) VALUES ('Obelix')");
	    }
}

事务

默认情况下,Flyway总是为每个版本创建一个事务。 你也可以通过修改默认配置 group=true 来设置,所有的迁移在一个事务中执行。

如果Flyway检测到由于数据库的技术限制,某个特定语句无法在事务中运行,那么它就不会在事务中运行该迁移。 相反,它将被标记为非事务性的。

默认情况下,事务和非事务语句不能在迁移运行中混合。 但是,您可以通过将mix属性设置为true来实现这一点。

重要提示
如果数据库支持DDL语句事务,失败的迁移将总是回滚(除非它们被标记为非事务性的)。

如果另一方面数据库地支持事务中存在DDL语句(例如mysql中,当事务中遇到DDL语句,会将之前的执行进行隐式提交),因此如果后面出错了,将迁移标记为失败,表明可能需要一些手工清理。 所以尽量做到DDL与DML语句写入到不同的SQL文件中,尽量保证DDL语句的正确性,因为一旦出错需要手动清理。

Schema历史表 为了跟踪各个版本的迁移在何时由谁执行,Flyway向您的数据库Schema中添加了一个特殊的Schema历史表。 您可以将此表视为对针对Schema执行的所有更改的完整审计跟踪。 它还记录了迁移校验和以及迁移是否成功。

迁移状态

  • 成功 迁移成功时,在Flyway的模式历史表中标记为成功。

  • 失败回滚 当迁移失败且数据库支持DDL事务时,将回滚迁移,模式历史表中不会记录任何内容。

  • 回滚失败 当迁移失败且数据库不支持DDL事务时,迁移将在模式历史表中标记为failed,这表明可能需要手动数据库清理。

相关连接

Flyway官网
Flyway官网文档
Flyway配置说明
Flyway的工作原理

空文件

简介

取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/lzcangqiong/flyway-example.git
git@gitee.com:lzcangqiong/flyway-example.git
lzcangqiong
flyway-example
flyway-example
master

搜索帮助