一、flyway簡介
Flyway是一個簡單開源數據庫版本控制器(約定大于配置),主要提供migrate、clean、info、validate、baseline、repair等命令。它支持SQL(PL/SQL、T-SQL)方式和Java方式,支持命令行客戶端等,還提供一系列的插件支持(Maven、Gradle、SBT、ANT等)。
二、使用Flyway背景
部門開發一直是后端人員自行維護新增腳本,所以每次部署項目測試,都需要后端開發人員將 sql腳本在對應環境數據庫上執行一遍,這樣就造成有時候腳本文件混亂或者忘記執行,導致一些不必要的麻煩,所以就想要使用一款可以記錄SQL文件版本迭代的工具。
三、Springboot集成Flyway
廢話少說,我們直接開始進行Springboot的集成吧。
首先看一下Flyway執行流程:
1)Flyway 會掃描配置的腳本目錄下的腳本文件;
2)如果歷史記錄表不存在,則新建歷史記錄表;
3)如果是一次性執行腳本(V),按版本號從小到大執行遷移腳本,與當前歷史表中的版本號做對比,大于當前版本號的腳本才會被執行遷移;
4)如果是可重復執行腳本(R),檢查腳本是否有變動,有變動的可重復腳本才會被執行遷移;
1.引入依賴
Springboot2.x版本已經對Flyway有所依賴了,我們直接引入,不需要進行版本的申明,有時你寫上版本號還可能被項目自動覆蓋哦,這塊注意檢查一下。
<dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId>
</dependency>
2.配置文件 yml
要遷移的數據庫的 DB url。 如果未設置,則使用主要配置的數據源,正常我們的項目都有jdbc的連接信息,我們使用默認就行,無需配置。
pring:flyway:# 開啟 flywayenabled: true# 檢測遷移腳本的路徑是否存在,如不存在,則拋出異常check-location: true# 是否禁用數據庫清理clean-disabled: true# SQL 遷移的編碼encoding: UTF-8# 遷移腳本的位置,默認db/migration.locations: classpath:flyway# 版本記錄信息表table: tb_flyway_history# SQL 遷移的文件名前綴。sql-migration-prefix: V# SQL 遷移的文件名分隔符。sql-migration-separator: __# SQL 遷移的文件名后綴。sql-migration-suffixes: .sql# 是否在執行遷移時自動調用驗證。validate-on-migrate: true# 遷移時發現目標schema非空,而且帶有沒有元數據的表時,是否自動執行基準遷移,默認false.baseline-on-migrate: true#如果不想用元數據的表明,可以更改元表名spring.flyway.table=test
3.新建flyway文件夾和sql文件
Flyway 的默認掃描遷移腳本目錄在:spring.flyway.locations: classpath:db/migration,用于掃描的遷移腳本目錄
Flyway 的默認版本變化記錄表名稱:spring.flyway.table: flyway_schema_history,用于記錄所有的版本變化記錄(可在配置文件中進行更改)
3.1 根據第2步配置了遷移腳本目錄,我們在 src/main resources 目錄下創建flyway目錄,如下圖:
3.2 下面我們創建兩個sql腳本,如上圖:
SQL腳本的命名規則(約定大于配置必須遵守)
命名規則主要有兩種:
1、僅需要被執行一次的SQL命名以大寫的"V"開頭,V+版本號(版本號的數字間以”.“或”_“分隔開)+雙下劃線(用來分隔版本號和描述)+文件描述+后綴名。例如: ?V20231100__create_user.sql、V2.1.5__create_user_ddl.sql、V4.1_2__add_user_dml.sql ?。
2、可重復運行的SQL,則以大寫的“R”開頭,后面再以兩個下劃線分割,其后跟文件名稱,最后以.sql結尾。(不推薦使用)比如: R__truncate_user_dml.sql 。
?
前綴:V用于版本化(可配置), U用于撤消(可配置)和 R用于可重復遷移(可配置)
版本:帶點或下劃線的版本可以根據需要分開多個部分(不適用于可重復的遷移)
分隔符 :( __兩個下劃線)(可配置)
描述:下劃線或空格分隔單詞
后綴:.sql(配置)
-- V1.0.0__user_create.sql 創建標簽表
DROP TABLE IF EXISTS tb_user;
CREATE TABLE `tb_user` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID',`user_code` varchar(100) DEFAULT NULL COMMENT '用戶code',`user_name` varchar(50) DEFAULT NULL COMMENT '用戶名稱',`user_type` int(2) DEFAULT 3 COMMENT '用戶類型',`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用戶表';-- V1.0.1__user_insert.sql 標簽表插入數據
INSERT INTO tb_user
(user_code, user_name, user_type)
values("U12345", "張三", 1);
四、啟動項目
2022-05-17 16:13:37.912||||[main] INFO ?o.f.core.internal.database.base.DatabaseType 49 - Database: jdbc:mysql://localhost:3366/db (MySQL 5.7)
2022-05-17 16:13:37.999||||[main] INFO ?org.flywaydb.core.internal.command.DbValidate 49 - Successfully validated 2 migrations (execution time 00:00.048s)
2022-05-17 16:13:38.025||||[main] INFO ?org.flywaydb.core.internal.command.DbMigrate 49 - Current version of schema `db`: << Empty Schema >>
2022-05-17 16:13:38.039||||[main] INFO ?org.flywaydb.core.internal.command.DbMigrate 49 - Migrating schema `db` to version "1.0.0 - create"
2022-05-17 16:13:38.123||||[main] INFO ?org.flywaydb.core.internal.command.DbMigrate 49 - Migrating schema `db` to version "1.0.1 - insert"
2022-05-17 16:13:38.157||||[main] INFO ?org.flywaydb.core.internal.command.DbMigrate 49 - Successfully applied 2 migrations to schema `db` (execution time 00:00.153s)
數據庫中flyway記錄歷史信息表如下:
五、 開發時注意事項
1.報錯后需要刪除flyway_schema_history中記錄,否則啟動失敗
2.V的優先級高于R,假如三個V遷移腳本和一個R(無論新建還是修改)一起執行,其中一個V報錯,則V會
全部執行完成且記錄到flyway_schema_history中,而R不執行且不記錄,刪除表中報錯記錄后,查詢啟
動,則執行原錯誤V和未執行的R
3.多個要執行的R中,如果出現了其中一個出現了錯誤,則在其后的R都不執行
4.R的執行順序根據命名來進行排序
5.一個文件中ddl并不由一個事務管理,比如創建三個表,中間創建表語句報錯,則第一個表還是會創建
成功并且提交事務
6.已經執行過的遷移文件(V)不能修改,否則報錯。
7.同一個遷移文件下同表內DDL無法回滾,DML可回滾, 從報錯點開始不往下執行,Flyway使用數據庫鎖
機制
8.版本號相同會報錯(Found more than one migration with version 1.0.0.9)
9.同一個遷移文件下假設都是dml,那么如果中間出現錯誤,所有的dml語句都會回滾
10.刪除sql文件后啟動會報錯,報錯如下
If you removed this migration intentionally, run repair to mark the migration as
deleted.
六、部署上線時注意事項
如果不手動創建元數據表,則需要進行以下配置,用于自動創建
validate-on-migrate: true
如果數據庫不是空表,則需進行以下配置,否則啟動報錯
baseline-on-migrate: true
clean命令會刪除數據庫中所有表,包括數據,結構等,這是不合理的,所以需要進行以下配置
clean-disabled: true (該配置由于默認值不合理,所以在V9版本中修改默認值由false為true)
使用flyway要注意版本兼容問題,springboot與flyway,flyway與數據庫版本,否則啟動報錯
如果啟動的時候像忽略某些遷移文件,可進行以下參數配置
baseline-version=20230809,以忽略 20230809 版本以及之前的所有 migration
多人開發中,如果一個人提交V2一個人提交V1,而V2先入庫執行了,那么V1入庫就不會執行,如果需要執行則需進行如下配置,但是不建議這么做
out-of-order=true