Flyway的迁移功能
官方文档地址
迁移指的是把数据库结构从一个版本更新到另一个版本。使用 Flyway 时,对数据库的所有更改都称为迁移。迁移可以是版本化,也可以是可重复。迁移脚本分为三种类型:Versioned、Repeatable和Undo。其中,Versioned用于版本升级,每个版本有唯一的版本号并只能执行一次;Repeatable可重复执行,当Flyway检测到Repeatable类型的SQL脚本的checksum有变动,Flyway就会重新应用该脚本;Undo用于撤销上一次的迁移操作。Flyway中文件命名也有要求,官图镇楼:
我们将用最新的springboot3来尝试使用它。
我的springboot版本使用最新的
<spring-boot.version>3.1.4</spring-boot.version>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>9.22.2</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<version>9.22.2</version>
</dependency>
必须同时引入flyway-mysql,否则会报不支持mysql8.1版本数据库。
因为flyway也遵循约定大于配置原则,默认存放文件路径为db.migration下:
我的springboot的yml配置
spring:
flyway:
# 历史表
baseline-on-migrate: true
# 默认1,从0开始可以规避版本1不执行问题
baseline-version: 0
# 避免数据被意外清空
clean-disabled: false
datasource:
url: jdbc:mysql://localhost:3306/top
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
版本化迁移(V)
最常见的迁移类型是版本化迁移。版本必须是唯一的。 版本化迁移仅按顺序应用一次。
版本化迁移通常用于:
- 正在创建/更改/删除表/索引/外键…
- 数据更新
例子:
CREATE TABLE car (
id INT NOT NULL PRIMARY KEY,
color VARCHAR(10) NOT NULL
);
ALTER TABLE car ADD license_id VARCHAR(100);
INSERT INTO brand (name) VALUES ('DeLorean');
必须为每个版本化迁移分配一个唯一的版本。任何版本只要符合通常的规定。在大多数情况下,一个简单的递增整数应该就可以了。 所有这些版本号都是有效的版本化迁移版本:
- 1
- 1.2.3.4.5.6
- 20130115113556
- 2013.1.15.11.35.56
命名示例:
V1__Initial_version.sql
V1.1__Fix_indexes.sql
V2__Add a new table.sql
比如现在我有V1.0.0__insert.sql文件内容:
insert into user(id) value ("111");
insert into user(id) value ("222");
启动项目后我们看到insert.sql中被成功执行:
可重复(R)
一般为可重复执行的sql语句。
命名示例:
R__My_view.sql
sql语句比如创建或者修改视图:
CREATE OR REPLACE VIEW user_view AS SELECT id, license_plate FROM user WHERE license_plate is null;
此时会自动生成user_view视图。
但和上面的insert.sql不一样的地方在于,我们可以重复修改该sql文件内容以达到我们期望的效果。
撤销(U)
撤消迁移内容与常规版本化迁移相反。一般不推荐使用,因为版本一但需要回退,可能有破坏性的操作已经执行,我们需要经过充分测试的备份和有一些还原数据的策略。目前使用此功能需要团队版本:
/**
* File name prefix for undo SQL migrations. Requires Flyway Teams.
*/
private String undoSqlMigrationPrefix;
命名和使用示例:
U1.1__Fix_indexes.sql
U2__Add a new table.sql
比如v1中的语句在U1中将成为:
delete from user where id='111';
delete from user where id='222';
一些错误收集和解决方案:
- 如果 flyway 不是项目初期引入,而是在已有表的情况下引入,必须设置 baseline-on-migrate: true。启动项目后,flyway 就会自动在数据库中创建 flyway_schema_history 表,并且会往该表中插入一条 version = 1 的建表记录,如果迁移数据有 V1__ 开头的文件,扫描文件会忽略该文件不执行迁移,进而可能引发其他迁移数据出错的问题。这个原因是因为baseline-version的默认值就是1。
- 生产环境需要将clean-disabled设置为false,避免数据被意外清空。