一、为什么要用Flyway

目前开发中存在以下问题:

  • 开发、测试、生产存在多套数据库环境,对于同一数据库的修改,需要手动执行多次;
  • 数据库变更无记录,投产上线前梳理SQL脚本容易遗漏。
    为解决上述问题,尝试使用Flyway.

二、Flyway简介

flyway支持mysql版本_Flyway

  • Flyway是一款开源的数据库版本管理工具,支持在所有环境中进行稳健的架构演变。
  • Flyway具有幂等性,SQL脚本对数据库对影响只是一次性的,不会重复操作。
  • Flyway独立于应用实现,对数据库版本进行管理,支持数据库版本的自动升级。

三、Flyway运行机制

引用Flyway官网的图进行说明:

flyway支持mysql版本_SQL_02


Flyway通过记录数据库版本升级来进行管理。数据库中的每一个修改后状态对应数据库的一个版本。理论上Flyway引入后,不允许直接操作数据库,均需通过Flyway配置扫描路径下的SQL文件来操作。

flyway支持mysql版本_SQL_03


Flyway运行成功后,会在数据库中自动创建 flyway_schema_history(表名可通过配置修改)表,该表用于记录数据库的变更记录。

  • 表中每一条记录对应扫描路径(一般配置在 /src/resources/db/migration)下的每一个SQL文件执行;
  • 表字段 version 对应 SQL 脚本版本;
  • 表字段 script 对应 SQL 脚本名;
  • 表字段 success 对应 SQL 脚本执行结果,0: 失败;1: 成功。

四、Flyway 配置使用(包括多数据源配置)

Flyway的配置特别简单,在数据库连接配好的前提下,仅需要引入依赖、增加application配置即可。

1、pom中增加依赖

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

2、进行application相关flyway配置
本项目配置使用application.yaml,在yaml中增加flyway配置

flyway:
 baseline-on-migrate: true
 enabled: true
 locations: classpath:db/migration
 table: flyway_schema_history

本项目配置的比较简单,配置的参数主要含义为:
baseline-on-migrate:当schema为空时,是否自动执行基线。配置为true时,第一次启动flyway时,会自动创建flyway记录版本的表flyway_schema_history,以及基线记录(V1基线记录)
enabled:是否开启flyway
locations:扫描的sql脚本位置

  • 支持项目路径(classpath)、文件路径(filesystem)等格式。如果不显示声明,默认为classpath:db/migration
  • 路径支持模糊匹配,通配符支持:
    – ** :0个或多个路径。例如 db/**/test(确定以 /test 结尾),db/path1/test、db/path1/path2/test 均可以匹配,但是 db/path1/test1 就不行了
    – * :0个或多个字符。例如 db/version1.* ,db/version1.0、db/version1.123456 均可以匹配,但是 db/version2.0 不能匹配
    – ?:1个字符。例如 db/version1.?,db/version1.0、db/version1.2 均可匹配,但是 db/version1.11 就不可以

table:自动生成的记录版本表名
更多flyway参数说明可参考官网:flyway官网文档地址

3、多数据源配置
随着项目的扩大,引入了多数据源连接(目前使用druid配置的多数据源连接),同时需引入多数据源的版本配置。
Flyway自身是无法区分数据源连接的,为支持多数据源版本管理,需将多数据源对应的SQL文件分别存放,并增加flyway配置。
本项目中,主数据源相关迁移脚本放在/resources/db/migration 目录下,另一数据源迁移脚本放在 /resources/db/baseMigration 目录下。
主数据源flyway配置无需修改,再增加一套flyway配置即可。
主数据源flyway配置在application.yaml中,另一数据源无法同时配置在applicaiton中,增加 FlywayConfig.java 配置文件,主要代码如下:

@Configuration
@EnableTransactionManagement
@Import({DynamicDataSourceRegister.class})
public class FlywayConfig {
	private static final String BASE_SQL_LOCATION = "/db/baseMigration";
	private static final String ENCODING = "UTF-8";

	// application配置文件中base数据源配置
	@Value("${frame.druid.ds.base.url}")
	private string baseUrl;
	@Value("${frame.druid.ds.base.username}")
	private string baseUserName;
	@Value("${frame.druid.ds.base.password}")
	private string basePassword;
	@Value("${frame.druid.ds.base.driverClassName}")
	private string baseDriverClassName;
	
	@Bean
	public void migrate() {
		Flyway flyway = Flyway.configure()
					.dataSource(getBaseDataSource())
					.locations(BASE_SQL_LOCATION)
					.encoding(ENCODING)
					.baselineOnMigrate(true)
					.table("base_flyway")
					.load();
		flyway.migrate();
	}

	private BasicDataSource getBaseDataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setUrl(baseUrl);
		dataSource.setUserName(baseUserName);
		dataSource.setPassword(basePassword);
		dataSource.setDriverClassName(baseDriverClassName);
		return dataSource;
	}
}

配置完成后,启动项目,两个路径下的迁移脚本均完成执行。

五、Flyway 使用规范

SQL脚本命名规范

扫描路径下SQL文件命名为 V2_1__init_request.sql 格式,具体说明如下:

flyway支持mysql版本_flyway支持mysql版本_04

  • V 为固定前缀分隔符,代表数据库版本化;
  • 2_1 为 SQL 脚本版本,’_’ 翻译为小数点,2_1 即为 2.1 版本;
  • __为两个下划线,代表中间分隔符;
  • init_request 为 SQL 脚本名,概述本脚本要进行的操作;
  • .sql 为固定后缀。

开发规范

通过在项目中配置,Flyway 会在 application 启动时自动按顺序执行扫描路径下的 SQL 文件。开发中建议遵循以下规范:

  • 禁止修改已执行的 SQL 文件(已执行的定义:SQL文件已合并到公共分支,且 flyway_schema_history 表里已有该条记录),如需修改已执行 SQL 涉及的表,需新增 SQL 文件写入修改语句;
  • DDL 与 DML 语句不能写在同一 SQL 文件;
  • 在增加 SQL 脚本后,需先在本地进行启动 applicaiton。若数据迁移脚本执行失败,则 application 无法启动,请根据第六点进行修复;
  • 禁止提交执行失败的 SQL 文件。本地新增 SQL 文件后,application 启动成功后,再提交代码到远程。

六、脚本执行失败排查及修复

1、由于Flyway导致application执行失败时,在console 中查看错误日志及原因

flyway支持mysql版本_数据库_05


例如图中失败原因为 存储过程delete_matches 已经存在,则需要删除已存在的存储过程,再次执行。

2、根据console中的错误提示,修复SQL脚本。

3、然后数据库中打开 flyway_schema_history 表,删除 success 字段为 0 (0状态为失败,1状态为成功) 的记录(表中最后一条记录)。

再次启动 application即可。

最后,让我们开心、愉快的来使用 Flyway 吧~