做網(wǎng)站建設(shè)最好學(xué)什么手機(jī)優(yōu)化什么意思
一、Flyway簡(jiǎn)介
Flyway是一款開(kāi)源的數(shù)據(jù)庫(kù)遷移工具,可以管理和版本化數(shù)據(jù)庫(kù)架構(gòu)。通過(guò)Flyway,可以跟蹤數(shù)據(jù)庫(kù)的變化,并將這些變化作為版本控制的一部分。Flyway支持SQL和NoSQL數(shù)據(jù)庫(kù),并且可以與現(xiàn)有的開(kāi)發(fā)流程無(wú)縫集成,如持續(xù)集成(CI)和持續(xù)部署(CD)。
二、Flyway主要特性
Flyway的主要特性包括:
- 版本化遷移(Versioned Migrations):通過(guò)一系列的SQL腳本逐步更新數(shù)據(jù)庫(kù)架構(gòu),每個(gè)遷移腳本都有一個(gè)唯一的版本號(hào),例如
V1__Initial_setup.sql
。當(dāng)Flyway運(yùn)行時(shí),它會(huì)檢查數(shù)據(jù)庫(kù)中的flyway_schema_history
表,以確定哪些遷移腳本已經(jīng)執(zhí)行過(guò)了。如果發(fā)現(xiàn)有未執(zhí)行的遷移腳本,Flyway將按照版本號(hào)的順序執(zhí)行它們。 - 回退遷移(Undo Migrations):是指在某些情況下,可能需要將數(shù)據(jù)庫(kù)回滾到一個(gè)先前的狀態(tài)。Flyway并沒(méi)有內(nèi)置的回退機(jī)制,但它提供了基礎(chǔ)設(shè)施,允許你在遷移腳本中定義回退邏輯。通常是通過(guò)在遷移腳本中指定一個(gè)相反的遷移腳本來(lái)實(shí)現(xiàn)的。例如,如果你有一個(gè)遷移腳本
V2__Add_new_column.sql
,你可以創(chuàng)建一個(gè)對(duì)應(yīng)的回退腳本R2__Drop_new_column.sql
,其中R2
表示這是一個(gè)回退腳本。在需要回滾時(shí),Flyway會(huì)執(zhí)行相應(yīng)的回退腳本,將數(shù)據(jù)庫(kù)回滾到上一個(gè)穩(wěn)定的狀態(tài)。 - 可重復(fù)遷移(Repeatable Migration):是與版本化遷移不同的另一種類(lèi)型的遷移,它不依賴(lài)于版本號(hào)。這種遷移腳本通常用于那些不需要跟蹤版本的變更,比如對(duì)數(shù)據(jù)庫(kù)性能調(diào)優(yōu)的腳本。Flyway會(huì)簡(jiǎn)單地將這些腳本視為一組獨(dú)立的更改,并在每次運(yùn)行時(shí)執(zhí)行它們。
- 多數(shù)據(jù)庫(kù)支持:Flyway支持多種關(guān)系型數(shù)據(jù)庫(kù),如MySQL、Oracle、PostgreSQL等,使得在不同數(shù)據(jù)庫(kù)間遷移變得容易。
- 自動(dòng)化遷移:Flyway可以在應(yīng)用程序啟動(dòng)時(shí)自動(dòng)執(zhí)行遷移腳本,或者通過(guò)命令行手動(dòng)執(zhí)行,提高了遷移的效率和可靠性。
- 集成到開(kāi)發(fā)流程:Flyway可以集成到持續(xù)集成(CI)和持續(xù)部署(CD)流程中,確保數(shù)據(jù)庫(kù)結(jié)構(gòu)隨著應(yīng)用程序的發(fā)展而保持同步。
三、Flyway的工作流程
Flyway的設(shè)計(jì)哲學(xué)是約定優(yōu)于配置,這意味著它遵循一些預(yù)定義的規(guī)則來(lái)簡(jiǎn)化數(shù)據(jù)庫(kù)遷移的過(guò)程。下面是Flyway的基本工作流程:
- 初始化:當(dāng)你首次運(yùn)行Flyway時(shí),它會(huì)根據(jù)配置在數(shù)據(jù)庫(kù)中創(chuàng)建一個(gè)名為
flyway_schema_history
的表,這個(gè)表用來(lái)記錄所有的遷移活動(dòng),包括遷移的版本號(hào)、描述、執(zhí)行的SQL文件名、執(zhí)行時(shí)間和是否成功等信息。 - 掃描遷移腳本:Flyway會(huì)掃描指定的目錄(通常是
classpath:db/migration
)以查找遷移腳本。這些腳本通常命名為V<version>__<description>.sql
,其中<version>
是遷移的版本號(hào),<description>
是對(duì)遷移的簡(jiǎn)短描述。 - 比較版本號(hào):Flyway會(huì)比較數(shù)據(jù)庫(kù)中的
flyway_schema_history
表記錄的當(dāng)前版本號(hào)與現(xiàn)有遷移腳本中的版本號(hào)。如果存在未執(zhí)行的遷移腳本,Flyway將會(huì)執(zhí)行它們。 - 執(zhí)行遷移:對(duì)于每個(gè)需要執(zhí)行的遷移腳本,Flyway會(huì)將其作為一個(gè)事務(wù)執(zhí)行。如果在執(zhí)行過(guò)程中出現(xiàn)錯(cuò)誤,Flyway會(huì)回滾整個(gè)事務(wù),并記錄錯(cuò)誤信息。
- 記錄遷移結(jié)果:一旦遷移腳本執(zhí)行完畢,無(wú)論是成功還是失敗,Flyway都會(huì)在flyway_schema_history表中記錄下遷移的結(jié)果。
- 重復(fù)執(zhí)行:如果需要,你可以重復(fù)執(zhí)行Flyway的遷移過(guò)程,以應(yīng)用新的遷移腳本。Flyway會(huì)識(shí)別哪些遷移已經(jīng)被執(zhí)行過(guò),并跳過(guò)它們。
四、與SpringBoot項(xiàng)目整合
4.1 添加依賴(lài)
到項(xiàng)目的pom文件中添加Flyway的依賴(lài)包。
<dependency><groupId>org.flywaydb</groupId><artifactId>flyway-mysql</artifactId><version>8.5.13</version>
</dependency>
4.2 修改配置
到項(xiàng)目的application.yaml文件中添加Flyway的配置信息。
sping:flyway:#是否開(kāi)啟flyway,默認(rèn)trueenabled: true#當(dāng)遷移時(shí)發(fā)現(xiàn)目標(biāo)schema非空,而且沒(méi)有元數(shù)據(jù)的表時(shí),(即迭代中項(xiàng)目應(yīng)為true)是否自動(dòng)執(zhí)行基準(zhǔn)遷移,默認(rèn)false.baseline-on-migrate: true# 是否允許無(wú)序運(yùn)行遷移, 默認(rèn)false,建議開(kāi)發(fā)環(huán)境開(kāi)啟,生成環(huán)境關(guān)閉out-of-order: false#設(shè)定SQL腳本的目錄,可以配置多個(gè),比如為classpath:db/migration,filesystem:/sql-migrations,默認(rèn)classpath:db/migrationlocations:- classpath:db/migration
常用配置項(xiàng)如下:
- spring.flyway.enabled: 是否啟用Flyway,默認(rèn)為true。
- spring.flyway.table: Flyway元數(shù)據(jù)表的名稱(chēng),默認(rèn)為flyway_schema_history。
- spring.flyway.encoding: 遷移腳本文件的編碼,默認(rèn)為UTF-8。
- spring.flyway.validate-on-migrate: 遷移時(shí)是否進(jìn)行驗(yàn)證,默認(rèn)為true。
- spring.flyway.check-location: 是否檢查遷移腳本的位置是否存在,默認(rèn)為true。
- spring.flyway.clean-disabled: 是否禁用Flyway的clean操作,默認(rèn)為false。
- spring.flyway.baseline-on-migrate: 當(dāng)遷移時(shí)發(fā)現(xiàn)目標(biāo)schema非空,并且沒(méi)有元數(shù)據(jù)的表時(shí),是否自動(dòng)執(zhí)行基準(zhǔn)遷移,默認(rèn)為false。
- spring.flyway.baseline-version: 開(kāi)始執(zhí)行基準(zhǔn)遷移時(shí)對(duì)現(xiàn)有schema的版本打標(biāo)簽,默認(rèn)為1。
- spring.flyway.locations: 遷移腳本的位置,默認(rèn)為classpath:db/migration。
- spring.flyway.sql-migration-prefix: 遷移文件的前綴,默認(rèn)為V。
- spring.flyway.sql-migration-suffix: 遷移腳本的后綴,默認(rèn)為.sql。
- spring.flyway.out-of-order: 是否允許無(wú)序的遷移,默認(rèn)為false。
- spring.flyway.schemas: 需要Flyway遷移的schema,默認(rèn)為連接默認(rèn)的schema。
4.3 編寫(xiě)sql腳本文件
sql腳本文件名稱(chēng)要符合flyway規(guī)范,命名規(guī)則如下:
- 版本遷移腳本(Versioned Migrations):腳本文件名的前綴通常是
V
,后跟版本號(hào)(版本號(hào)之間可以用點(diǎn).
或下劃線(xiàn)_
分隔),版本號(hào)后面是__
雙下劃線(xiàn)的分隔符,分隔符后面是文件描述,最后是文件后綴名。例如:V1__Initial_Setup.sql
、V1.1.2__Initial_Setup.sql
、V1.1.2_1__Initial_Setup.sql
。 - 回退遷移(Undo Migrations):腳本文件名的前綴為
U
,前綴后面部分與版本遷移腳本的文件名相同。例如:U1__Initial_Setup.sql
、U1.1.2__Initial_Setup.sql
、U1.1.2_1__Initial_Setup.sql
。 - 可重復(fù)遷移腳本(Repeatable Migrations):腳本文件名的前綴是
R
,由于不依賴(lài)版本號(hào),所以后面可以直接跟分隔符和腳本名稱(chēng)。例如R__truncate_user_dml.sql
。
默認(rèn)情況下sql腳本文件都放在src\main\resources\db\migration
下:
4.4 啟動(dòng)項(xiàng)目自動(dòng)完成腳跟更新
項(xiàng)目啟動(dòng)日志中打印出Flyway 的腳本執(zhí)行信息如下:
五、錯(cuò)誤總結(jié)
Spring Boot版本是2.5.12,MySQL用的是8.2。
-
Unsupported Database: MySQL 8.2
這個(gè)問(wèn)題是由于開(kāi)始用的Flyway 依賴(lài)是flyway-core
的8.5.13版本,后面換成flyway-mysql
的8.5.13版本解決問(wèn)題。 -
Validate failed: Migrations have failed validation
(1)Either revert the changes to the migration, or run repair to update the schema history.
這個(gè)問(wèn)題是由于腳本已經(jīng)被migration 過(guò)了,后面又對(duì)這個(gè)腳本做了修改所導(dǎo)致的。所以已經(jīng)被migration 過(guò)腳本文件一定不要再去修改
,實(shí)在要改的話(huà)重新寫(xiě)個(gè)腳本文件去修改。這里解決問(wèn)題是刪掉flyway_schema_history表中之前執(zhí)行過(guò)的記錄
,這樣重新再啟動(dòng)的時(shí)候Flyway 校驗(yàn)這個(gè)腳本時(shí)找不到之前執(zhí)行過(guò)的記錄,就會(huì)認(rèn)為這是個(gè)全新的腳本不會(huì)與之前執(zhí)行過(guò)的腳本有沖突,才會(huì)再次執(zhí)行這個(gè)腳本。其實(shí)這樣改還不是很好,因?yàn)檫@個(gè)腳本的的確確已經(jīng)執(zhí)行過(guò)一次,如果這個(gè)腳本是個(gè)添加一條記錄的語(yǔ)句,你后面只是在這個(gè)語(yǔ)句中多加了個(gè)字段,然后再次去執(zhí)行,那結(jié)果就是再新增一條類(lèi)似的數(shù)據(jù),而我們的本意其實(shí)只是想改動(dòng)之前的數(shù)據(jù),所以如果不小心改動(dòng)了之前已經(jīng)migration 過(guò)的腳本,最好連同這個(gè)腳本執(zhí)行過(guò)的sql記錄也一起刪掉
。
(2)Please remove any half-completed changes then run repair to fix the schema history.
這個(gè)問(wèn)題是由于在項(xiàng)目啟動(dòng)時(shí)Flyway 執(zhí)行腳本出錯(cuò),但是flyway_schema_history
表中已經(jīng)記錄了這次腳本的migration失敗的操作, 當(dāng)你修改完腳本后再次啟動(dòng)項(xiàng)目時(shí),發(fā)現(xiàn)flyway_schema_history
表中有過(guò)這個(gè)腳本的migration操作,從而導(dǎo)致校驗(yàn)不通過(guò)。這種情況只需要把flyway_schema_history表中這個(gè)腳本之前失敗的記錄刪除
重啟項(xiàng)目就可以,因?yàn)橹皥?zhí)行該腳本時(shí),該腳本的sql報(bào)錯(cuò)并沒(méi)有對(duì)數(shù)據(jù)庫(kù)進(jìn)行實(shí)際的操作,所以也就不用去數(shù)據(jù)庫(kù)刪除之前這個(gè)腳本操作產(chǎn)生的實(shí)際數(shù)據(jù)了。 -
Flyway failed to initialize: none of the following migration scripts locations could be found
這個(gè)問(wèn)題是由于沒(méi)找到sql腳本文件,可能是設(shè)置指定存放sql腳本的目錄出錯(cuò)或者目錄中壓根沒(méi)有腳本文件。我這個(gè)是沒(méi)有腳本文件,項(xiàng)目啟動(dòng)時(shí)報(bào)的錯(cuò),隨便添加個(gè)空的腳本文件后就能正常啟動(dòng)了。