Flyway:數(shù)據(jù)庫(kù)遷移
有什么好處
1.方便團(tuán)隊(duì)協(xié)作
- 開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境的數(shù)據(jù)庫(kù)結(jié)構(gòu)統(tǒng)一(隨著項(xiàng)目的進(jìn)行,肯定有數(shù)據(jù)庫(kù)結(jié)構(gòu)的變動(dòng))
操作命令
- Clean: 刪除所有創(chuàng)建的數(shù)據(jù)庫(kù)對(duì)象, 包括用戶、表、視圖等. 注意不要在生產(chǎn)庫(kù)上執(zhí)行 clean 操作.
- Migrate: 對(duì)數(shù)據(jù)庫(kù)依次應(yīng)用版本更改.
- Info: 獲取目前數(shù)據(jù)庫(kù)的狀態(tài). 那些遷移已經(jīng)完成, 那些遷移待完成. 所有遷移的執(zhí)行時(shí)間以及結(jié)果.
- Validate: 驗(yàn)證已 Apply 的腳本是否有變更, Flyway 的 Migration 默認(rèn)先做 Validate.
- Baseline: 根據(jù)現(xiàn)有的數(shù)據(jù)庫(kù)結(jié)構(gòu)生成一個(gè)基準(zhǔn)遷移腳本.
- Repair: 修復(fù)命令盡量不要使用, 修復(fù)場(chǎng)景有:`
- 移除失敗的 migration 記錄.
- 已經(jīng)應(yīng)用的 SQL 腳本被修改, 我們想重新應(yīng)用該 SQL 腳本.
接下來(lái)在項(xiàng)目中集成Flyway
添加pom依賴
<!-- https://mvnrepository.com/artifact/org.flywaydb/flyway-maven-plugin-->
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>6.2.3</version>
</plugin>
maven插件命令:
mvn flyway:migrate
工作原理
- flyway 需要在 DB 中先創(chuàng)建一個(gè) metdata 表 (缺省表名為 flyway_schema_history), 在該表中保存著每次 migration 的記錄, 記錄包含 migration 腳本的版本號(hào)和 SQL 腳本的 checksum 值.
- 當(dāng)一個(gè)新的 SQL 腳本被掃描到后, Flyway解析該 SQL 腳本的版本號(hào), 并和 metadata 表已 apply 的的 migration 對(duì)比, 如果該 SQL 腳本版本更新的話, 將在指定的 DB 上執(zhí)行該 SQL 文件, 否則跳過(guò)該 SQL 文件.
兩個(gè) flyway 版本號(hào)的比較, 采用左對(duì)齊原則, 缺位用 0 代替. 舉例如下:
1.2.9.4 比 1.2.9 版本高.
1.2.10 比 1.2.9.4 版本高.
1.2.10 和 1.2.010 版本號(hào)一樣高, 每個(gè)版本號(hào)部分的前導(dǎo) 0 會(huì)被忽略.
Flyway SQL 文件可以分為兩類: Versioned 和 Repeatable.
Versioned migration 用于版本升級(jí), 每個(gè)版本有唯一的版本號(hào)并只能 apply 一次.
Repeatable migration 是指可重復(fù)加載的 migration, 一旦 SQL 腳本的 checksum 有變動(dòng), flyway 就會(huì)重新應(yīng)用該腳本. 它并不用于版本更新, 這類的 migration 總是在 versioned migration 執(zhí)行之后才被執(zhí)行.
默認(rèn)情況下, Migration SQL的命名規(guī)則如下圖:

其中的文件名由以下部分組成,除了使用默認(rèn)配置外,某些部分還可自定義規(guī)則.
- prefix: 可配置,前綴標(biāo)識(shí),默認(rèn)值 V 表示 Versioned, R 表示 Repeatable
- version: 標(biāo)識(shí)版本號(hào), 由一個(gè)或多個(gè)數(shù)字構(gòu)成, 數(shù)字之間的分隔符可用點(diǎn).或下劃線_
- separator: 可配置, 用于分隔版本標(biāo)識(shí)與描述信息, 默認(rèn)為兩個(gè)下劃線__
- description: 描述信息, 文字之間可以用下劃線或空格分隔
- suffix: 可配置, 后續(xù)標(biāo)識(shí), 默認(rèn)為.sql
flyway 的 metadata 表結(jié)果如下:
CREATE TABLE flyway_schema_history
(
installed_rank INT NOT NULL,
version VARCHAR(50),
description VARCHAR(200) NOT NULL,
type VARCHAR(20) NOT NULL,
script VARCHAR(1000) NOT NULL,
checksum INT,
installed_by VARCHAR(100) NOT NULL,
installed_on TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
execution_time INT NOT NULL,
success TINYINT(1) NOT NULL,
PRIMARY KEY (installed_rank),
INDEX flyway_schema_history_s_idx (success)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
flyway核心包:(flyway 其實(shí)僅依賴 spring-boot-starter-jdbc 包)
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>6.2.3</version>
</dependency>
flyway配置信息:
spring:
## 設(shè)定 flyway 屬性
flyway:
# flyway 的 clean 命令會(huì)刪除指定 schema 下的所有 table, 殺傷力太大了, 應(yīng)該禁掉.
clean-disabled: true
# 禁用/啟用flyway
enabled: true
# 設(shè)定 SQL 腳本的目錄,多個(gè)路徑使用逗號(hào)分隔, 比如取值為 classpath:db/migration,filesystem:/sql-migrations
locations: classpath:db/migration
# 如果指定 schema 包含了其他表,但沒(méi)有 flyway schema history 表的話, 在執(zhí)行 flyway migrate 命令之前, 必須先執(zhí)行 flyway baseline 命令.
baseline-on-migrate: true
# 指定 baseline 的版本號(hào),缺省值為 1, 低于該版本號(hào)的 SQL 文件, migrate 的時(shí)候被忽略.
baseline-version: 1
# sql文件編碼
encoding: UTF-8
# 設(shè)定 flyway 的 metadata 表名, 缺省為 flyway_schema_history
table: flyway_schema_history_myapp
# 開(kāi)發(fā)環(huán)境最好開(kāi)啟 outOfOrder, 生產(chǎn)環(huán)境關(guān)閉 outOfOrder .
out-of-order: true
開(kāi)始使用
1.在resources/db/migration 新建SQL文件
SQL文件名是:
V0.0.1__init_table.sql
V0.0.2__add_column.sql
tips:前面兩個(gè)"__"前面說(shuō)了,out-of-order: true開(kāi)發(fā)環(huán)境開(kāi)啟,生產(chǎn)環(huán)境關(guān)閉。
那么關(guān)閉了,我們?nèi)绾问謩?dòng)在生產(chǎn)環(huán)境遷移數(shù)據(jù)庫(kù)?
很多方法,其一是通過(guò)Maven插件命令:
mvn flyway:migrate -Dflyway.url=... -Dflyway.user=... -Dflyway.password=...
需要添加配置:-Dflyway.url=... -Dflyway.user=... -Dflyway.password=...
不然是會(huì)報(bào)錯(cuò)的!
執(zhí)行結(jié)果:

至此,整合完畢!
