Flyway
一、 介绍
通过版本化数据库,提高数据库迁移的可靠性。即启动项目时就按版本执行sql脚本,实现数据库自动迁移。
Flyway是一款开源的数据库版本管理工具,它能够实现数据库迁移和版本控制。Flyway通过SQL脚本或Java代码进行数据库变更,支持多种数据库,如MySQL、Oracle、SQL Server等。它可以帮助团队更加方便、合理地管理数据库变更,实现数据库的自动化迁移、备份和还原等操作
官网:https://flywaydb.org/
github: https://github.com/flyway/flyway
官方文档:https://documentation.red-gate.com/flyway/quickstart-how-flyway-works
二、 原理
- 初次运行Flyway时,flyway会在数据库中创建
flyway_schema_history
表,用于记录schema的变化记录;如果数据库不是空库且配置项baseline-on-migrate=true
,表中会初始化一条数据,代表初始的数据库状态,type=baseline;即基线库
- flyway扫描应用程序下的脚本进行执行,脚本可以是Sql脚本或者java脚本;执行时会按照版本号排序,按从小到大执行;
- 每执行一个脚本,就会在
flyway_schema_history
表插入一条记录,记录版本、描述、类型、脚本名称、校验和、安装人、安装时间、执行耗时、成功否; - 有了新的数据库变化,写入新的sql脚本,运行flyway,flyway会再次扫描脚本文件,和数据库
flyway_schema_history
中的记录做对比,并检查已经执行过的脚本的校验和,如果和数据库记录不一致,则抛出异常,即已经执行过的脚本不能修改; - 校验和没问题,则把没执行过的且版本号大于最后执行记录版本的脚本排序,依次执行;没执行过但版本号小于记录版本的,也不会执行;
按照flyway执行逻辑,仅需要维护数据库创建脚本,以及后续的更新脚本即可记录数据库的整个生命周期,到新环境部署也没有任何问题
三、SpringBoot集成(mysql数据库)
3.1 pom
核心依赖包
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
全量基础依赖,有的版本需要引入flyway-mysql的包
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>
</dependencies>
3.2 编写脚本文件
- 脚本位置: 默认在
resouces/db/migration
下 - 脚本命名规则:
V<version>__<description>.sql
前缀(Prefix):
- V:表示这是一个有版本号的数据库迁移脚本。
- U:表示这是一个用于回滚特定版本的数据库迁移脚本(不是所有Flyway版本都支持U前缀)。
- R:表示这是一个可重复运行的迁移脚本,它会在每次迁移时运行,无论其是否已经运行过。
- B:基线迁移
版本号(Version):
紧跟在前缀后面的是版本号,它用于确定迁移脚本的执行顺序。
版本号通常采用主版本号.次版本号.修订版本号的格式,例如1.0.0。
Flyway会根据版本号的大小顺序来执行数据库迁移脚本。分隔符(Separator):
在版本号和描述之间,通常使用双下划线__作为分隔符。
描述(Description):
描述字段用于简要说明迁移脚本的作用或内容。
描述可以是任何字符串,但为了清晰起见,建议使用下划线_或空格进行分隔。后缀(Suffix):
表示这是一个SQL文件,因此后缀应为.sql。
示例:
V1.0.0__Create_user_table.sql
:表示一个版本号为1.0.0的迁移脚本,用于创建用户表。R__Reset_data.sql
:表示一个可重复运行的迁移脚本,用于重置数据。
正常配置spring的数据库链接,启动项目即可,项目每次启动都会检查并执行脚本;
注意
baseline-on-migrate
默认情况下是false
, 表示没有flyway_schema_history
表时,仅接受空库。
四、SpringBoot中Flyway的配置
spring已经给定了一套默认值,一般不需要进行单独配置,如需修改的可参照一下进行
# flyway 配置
spring:
flyway:
# 启用或禁用 flyway
enabled: true
# flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是 false 理论上作为默认配置是不科学的。
clean-disabled: true
# SQL 脚本的目录,多个路径使用逗号分隔 默认值 classpath:db/migration
locations: classpath:db/migration
# metadata 版本控制信息表 默认 flyway_schema_history
table: flyway_schema_history
# 如果没有 flyway_schema_history 这个 metadata 表, 在执行 flyway migrate 命令之前, 必须先执行 flyway baseline 命令
# 设置为 true 后 flyway 将在需要 baseline 的时候, 自动执行一次 baseline。
baseline-on-migrate: true
# 指定 baseline 的版本号,默认值为 1, 低于该版本号的 SQL 文件, migrate 时会被忽略
baseline-version: 1
# 字符编码 默认 UTF-8
encoding: UTF-8
out-of-order: false
# 需要 flyway 管控的 schema list,这里我们配置为flyway 缺省的话, 使用spring.datasource.url 配置的那个 schema,
# 可以指定多个schema, 但仅会在第一个schema下建立 metadata 表, 也仅在第一个schema应用migration sql 脚本.
# 但flyway Clean 命令会依次在这些schema下都执行一遍. 所以 确保生产 spring.flyway.clean-disabled 为 true
schemas: tests
# 执行迁移时是否自动调用验证
validate-on-migrate: true
五、基线迁移
在实际使用过程中,数据库的更新脚本可能会越来越多,这个时候,当我们要部署新环境时,就需要从头把所有脚本都执行一边,太耗时间,为解决此问题,flyway引入基线迁移。创建基线迁移脚本
B<version>__<description>.sql
示例:B2.0.1__20240516.sql
在原来环境中基线脚本会被忽略,在新环境中基线脚本才起作用,即当没有flyway_schema_history
表时,会找到最新
的基线脚本,即版本号最大的,执行该脚本,并顺序执行版本号大于基线版本的其他迁移脚本。