From version control to continuous delivery, Flyway helps individuals, teams, and enterprises build on application delivery processes to automate database development.
在项目开发中,一直在探索如何进行数据库的版本管理。关注的公众号推送了数据库版本管理工具Flyway,Flyway支持的数据库为 Oracle, SQL Server (including Amazon RDS and Azure SQL Database), Azure Synapse (Formerly Data Warehouse), DB2, MySQL (including Amazon RDS, Azure Database & Google Cloud SQL), Aurora MySQL, MariaDB, Percona XtraDB Cluster, TestContainers, PostgreSQL (including Amazon RDS, Azure Database, Google Cloud SQL, TimescaleDB, YugabyteDB & Heroku), Aurora PostgreSQL, Redshift, CockroachDB, SAP HANA, Sybase ASE, Informix, H2, HSQLDB, Derby, Snowflake, SQLite and Firebird.
最近实际操作了一下,结合官方文档,记录一下如何应用于Spring Boot项目中。
Flyway默认需要在数据库中新建一个metadata数据表,默认表名为flyway_schema_history,在该表中保存着每次 migration
(迁移)的记录, 记录包含 migration
脚本的版本号和 SQL 脚本的 checksum
值。下图表示了多个数据库版本。
对应记录表:
表中记录5个版本,对应配置文件下(第三节 的locations值),五个文件,如图所示。
Flyway 扫描文件系统或应用程序的类路径读取 DDL 和 DML 以进行迁移。根据metadata
表进行检查迁移。如果脚本声明的版本号小于或等于标记为当前版本的版本号之一,将忽略它们。其余迁移是待处理迁移:可用,但未应用。最后按版本号对它们进行排序并按顺序执行 并将执行结果写入 metadata 表。
Flyway 将 SQL 文件分为 Versioned 、Repeatable 和 Undo 三种:
checksum
有变动, Flyway 就会重新应用该脚本. 它并不用于版本更新, 这类的 migration
总是在 Versioned 执行之后才被执行。这三种的命名规则如下图:
V
表示 Versioned, R
表示 Repeatable, U
表示 Undo.
或下划线 _
__
_
或空格 分隔.sql
8.5.13
org.flywaydb
flyway-core
${flyway.version}
org.flywaydb
flyway-mysql
${flyway.version}
注意:因为我使用的数据库为MySql版本现在Flyway不直接支持,需要添加对于mysql的支持引入。
application.yml配置属性
spring:
datasource:
#???????
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DATABASE_SYSTEM_URL}
username: ${DATABASE_SYSTEM_USERNAME}
password: ${DATABASE_SYSTEM_PASSWORD}
#数据库版本管理工具flyway配置
flyway:
schemas: leading_info_collection # 数据库名称
enabled: true #是否开启flyway
encoding: utf-8 #编码方式
clean-on-validation-error: false #当发现校验错误时是否自动调用clean,默认false.
baseline-on-migrate: true # 如果数据库不是空表,需要设置成 true,否则启动报错
baseline-version: 0 # 与 baseline-on-migrate: true 搭配使用
clean-disabled: true # 禁止清理数据库表
locations: classpath:db/migration #设定 SQL 脚本的目录,多个路径使用逗号分隔, 比如取值为
#classpath:db/migration,filesystem:/sql-migrations
out-of-order: true #是否按照版本顺序执行sql文件
validate-on-migrate: false #启动时是否校验最新的版本迁移文件
此处列出了比较重要的一些配置,具体配置可以查看官方文档。这里讲解一下重要的配置。
flyway.baseline-description对执行迁移时基准版本的描述.
flyway.baseline-on-migrate当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false.
flyway.baseline-version开始执行基准迁移时对现有的schema的版本打标签,默认值为1.
flyway.check-location检查迁移脚本的位置是否存在,默认false.
flyway.clean-on-validation-error当发现校验错误时是否自动调用clean,默认false.
flyway.enabled是否开启flywary,默认true.
flyway.encoding设置迁移时的编码,默认UTF-8.
flyway.ignore-failed-future-migration当读取元数据表时是否忽略错误的迁移,默认false.
flyway.init-sqls当初始化好连接时要执行的SQL.
flyway.locations迁移脚本的位置,默认db/migration.
flyway.out-of-order是否允许无序的迁移,默认false.
flyway.password目标数据库的密码.
flyway.placeholder-prefix设置每个placeholder的前缀,默认${.
flyway.placeholder-replacementplaceholders是否要被替换,默认true.
flyway.placeholder-suffix设置每个placeholder的后缀,默认}.
flyway.placeholders.[placeholder name]设置placeholder的value
flyway.schemas设定需要flywary迁移的schema,大小写敏感,默认为连接默认的schema.
flyway.sql-migration-prefix迁移文件的前缀,默认为V.
flyway.sql-migration-separator迁移脚本的文件名分隔符,默认__
flyway.sql-migration-suffix迁移脚本的后缀,默认为.sql
flyway.tableflyway使用的元数据表名,默认为schema_version
flyway.target迁移时使用的目标版本,默认为latest version
flyway.url迁移时使用的JDBC URL,如果没有指定的话,将使用配置的主数据源
flyway.user迁移数据库的用户名
flyway.validate-on-migrate迁移时是否校验,默认为true
如下图所示,数据库中没有任何表,现在有V0版本,V0版本为初始化数据表
DROP TABLE IF EXISTS `problem_info`;
CREATE TABLE `problem_info` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`subject` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '描述主题',
`subjection_model` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '所属模块',
`detail` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '具体描述',
`ImageNames` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '图片地址',
`verificationCode` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '修改删除使用的验证码',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=144 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='问题信息表';
此时数据库新建了 flyway_schema_history表,并新建了一条数据,执行了initdb.sql文件,新建了problem_info表格。
现在按照命名规则,新增 V1版本添加一个学生的数据表,重新启动项目。
CREATE TABLE student (
id INT(4),
name VARCHAR(20),
sex CHAR(1));
现在更改V1__add_student_table.sql文件。
CREATE TABLE student (
id INT(4),
name VARCHAR(20),
sex CHAR(1));
DROP PROCEDURE IF EXISTS `sp_select_one_age_dogs`;
delimiter $
CREATE PROCEDURE sp_select_one_age_dogs()
begin
select * from dog d where d.dog_age <=1;
end $
再重新启动项目,报错信息如下。
新建一个以R开头的可重复执行的SQL文件R__add_procedure.sql,重新启动项目。
再pom.xml文件中添加对应的Maven插件,配置好数据库连接。
org.flywaydb
flyway-maven-plugin
${flyway.version}
${env.DATABASE_SYSTEM_URL}
${env.DATABASE_SYSTEM_USERNAME}
${env.DATABASE_SYSTEM_PASSWORD}
com.mysql.cj.jdbc.Driver
更新maven插件列表,就可以看到flyway的全部命令了。
此时,我们双击执行上图中的flyway:migrate的效果和启动整个工程执行migrate的效果是一样的。
其它命令的作用如下列出,各位可自行实验体会:
baseline,对已经存在数据库Schema结构的数据库一种解决方案。实现在非空数据库新建MetaData表,并把Migrations应用到该数据库;也可以在已有表结构的数据库中实现添加Metadata表。
clean,清除掉对应数据库Schema中所有的对象,包括表结构,视图,存储过程等,clean操作在dev 和 test阶段很好用,但在生产环境务必禁用。
info,用于打印所有的Migrations的详细和状态信息,也是通过MetaData和Migrations完成的,可以快速定位当前的数据库版本。
repair,repair操作能够修复metaData表,该操作在metadata出现错误时很有用。
undo,撤销操作,社区版不支持。
validate,验证已经apply的Migrations是否有变更,默认开启的,原理是对比MetaData表与本地Migrations的checkNum值,如果值相同则验证通过,否则失败。
通过上面的介绍相信你很快就会使用 Flyway 进行数据库版本控制了。这里总结了一些在实际开发中的使用经验:
spring.flyway.cleanDisabled=false
。V1.0.1__ProjectName_{Feature|fix}_Developer_Description.sql
,这种命名同时也可以获取更多脚本的开发者和相关功能的信息。spring.flyway.outOfOrder
取值 生产上使用 false
,开发中使用 true
。schema
时配置spring.flyway.table
为不同的系统设置不同的 metadata
表名而不使用缺省值 flyway_schema_history
。在进行了如上的实验后,相信我们都已经掌握了flyway的初步使用。目前还是在探索阶段,实际开发中还没有使用起来,后续肯定还会遇到很多问题,本博客会依据实际情况,持续不断更新。