Flyway學習筆記


Flyway做為database migration開源工具,功能上像是git、svn這種代碼版本控制。google搜索database migration,或者針對性更強些搜索database migration java,會有其它的framework、tool、甚至aws的service。因為項目使用到了flyway,而且確實google中排第一位的搜索結果就是flyway,那就之后有機會再與其它方案做比較,先對flyway做下學習筆記。

 

0.支持的數據庫

支持數據庫有 Oracle, SQL Server, SQL Azure, DB2, DB2 z/OS, MySQL (including Amazon RDS), MariaDB, Google Cloud SQL, PostgreSQL (including Amazon RDS and Heroku), Redshift, Vertica, H2, Hsql, Derby, SQLite, SAP HANA, solidDB, Sybase ASE and Phoenix。

 

1. 安裝

1.1 Cli

從官網下載壓縮包:https://flywaydb.org/documentation/commandline/

解壓后cd到目錄下,就可以直接執行flyway。解壓后的文件夾結構如下圖:

 

如果操作數據庫,需要先在/conf/flyway.conf文件中做下配置,主要是對flyway.url、flyway.user和flyway.password(如何支持針對多個database,尚未做實驗,待論),注釋中給出了url的詳細格式,可以根據環境自行添加。

1.2 Spring Integrating

dataSource中已經配置了數據庫的driver、與flyway.conf中flyway.url格式相同的數據庫信息,同時還有username和password,相當於這里就是為flyway配置conf文件
 
2 <bean id="flyway" class="org.Flyway.core.Flyway" init-method="migrate" depends-on="dataSource">
3     <property name="dataSource" ref="dataSource" />
4     <property name="locations" value="postgresql/db/migrations/" />
5 </bean>

每次app啟動的時候,確切說在flyway的bean初始化的時候,就會自動檢測掃描locations路徑下的文件。locations文件夾中的文件,按照flyway官方默認的命名方式,就是用Vx_x__description.sql。sql文件,還有實現JdbcMigration接口生成的class文件(后文描述),都會列在schema_version表中,作為版本控制的原子項。比如在部署環境,只要war包中locations中的sql文件改變了,那么數據庫就會做出相應的調整。
 

2. 配置

2.1 flyway.conf

flyway.conf:加載配置文件遵循下列順序,並且后面加載的配置會覆蓋前面的配置。

· <install-dir>/conf/flyway.conf

· <user-home>/flyway.conf

· <current-dir>/flyway.conf

文件中除了配置數據庫信息,還能對比如prefix、separator、suffix做定義,默認prefix是V(執行一遍,並且版本號唯一,如果有重復就會報錯)或R(重復執行,不需要版本號),separator是雙下划線__,suffix是.sql。

 

官方文檔中給出了SQL migration執行過程中掃描文件的順序,即classpath:db/migration或者file system: 自定義文件夾。或者在執行flyway migration的時候使用-X參數,就能看到執行流程,這個確實有助於理解flyway的workflow。

2.2 drivers

flyway使用JDBC連接數據庫,在drivers文件夾下有默認的幾種,

· SQL Server (jTDS)

· MySQL

· MariaDB

· PostgreSQL

· Redshift

· H2

· Hsql

· Derby

· SQLite

如果要操作其它數據庫,需要手動添加JDBC的driver到此文件夾下。

 

如果是用Spring集成,那么需要特別指定用的drivers是哪一個,比如org.postgresql.Driver

3. 基本指令

一共就6個基本指令:migrate、clean、info、validate、baseline、repair。強烈推薦在使用初期使用-X參數,log會顯示flyway自己的業務邏輯。

4. 處理邏輯

4.1 schema_version

Flyway會生成一個表schema_version來記錄文件的執行情況,關於生成與修改這個表的相關文件,在lib文件夾中有一個jar包flyway-core-2.1.1.jar,可以用WinZip打開,在下圖位置示例了生成表的createMetaDataTable.sql文件,以及操作相關的class文件。

 

schema_version表中記錄的每個腳本文件的執行情況,官方文檔上有pending、success、failed、outdated和future,我還沒有出現failed和outdated,不過有ignored,可能是因為用了V0。

 

4.2 文件處理邏輯

做為測試,我使用的執行步驟如下:

1. V1__create放入文件夾,migrate成功

2. V0__drop放入文件夾,migrate,結果是ignored

3. V0改為V1,numeric沖突,報錯了

4. V0__drop改為V1_1__drop,migrate,執行成功

5. V1_1_drop刪除,migrate,在schema_version表中,V1_1_drop狀態為future,說明表中不會自己刪除那些文件已不存在的item,而且drop掉的表不會再被創建,因為在schema_version表中V1__create的狀態已經是success了。

5. FAQ

其中幾個為官方文檔的翻譯,里面有些問題雖然沒碰到,不過先自己翻譯一遍加深理解。

原文鏈接:https://flywaydb.org/documentation/faq

對於降級操作(downgrade scripts/downward migrations)的支持

Flyway does NOT support downgrade scripts.

While the idea of downgrade scripts (popularized by Rails Migrations) is a nice one in theory, unfortunately it breaks down in practice. As soon as you have destructive changes (drop, delete, truncate, ...), you start getting into trouble. And even if you don't, you end up creating home-made alternatives for restoring backups, which need to be properly tested as well.

Flyway不支持降級的腳本:

一旦執行了諸如drop、delete、truncate這樣的清除性動作,從之前的實驗操作結果,我理解並不是說flyway不會甚至不能執行降級操作,畢竟drop、delete、truncate只是一些指令,flyway本身並沒有能力看出來是哪些操作,這個回答應該是想說,最好不要做諸如此類的清除性動作,否則麻煩就來了,除非之前已經做了充分的備份以恢復數據。

Downgrade scripts assume the whole migration failed.

A migration can fail at any point. If you have 10 statements, it is possible for the 1st, the 5th, the 7th or the 10th to fail. There is simply no way to know in advance. Downgrade scripts are written to roll back an entire migration. This renders them effectively useless, even for non-destructive changes.

Migration執行失敗可能發生在任何一個腳本,而降級操作相當於是在之前已經完成的基礎上,那么如果前面的腳本執行失敗,那么后面的操作就不會起作用,即便不是消除性操作。

我理解答案是想說明migration執行成功與否具有不確定性,而且版本號越高不確定性越強,因為會依賴先前的執行結果。

Maintain backwards compatibility between the DB and all versions of the code currently deployed in production.

This way a failed migration is not a disaster. The old version of the application is still compatible with the DB, so you can simply roll back the application code, investigate, and take corrective measures.

要確保數據庫與線上各個版本代碼的兼容性,才不會因為一次失敗的migration腳本而造成重大損失。而且當真正執行失敗的時候,也可以恢復回老版本的代碼,再對錯誤做出修正。

A much better solution is a proper, well tested, backup and restore strategy.

It is independent of the database structure, and once it is tested and proven to work, no migration script can break it. For optimal performance, and if your infrastructure supports this, we recommend using the snapshot technology of your underlying storage solution. Especially for larger data volumes, this can be several orders of magnitude faster than traditional backups and restores!

這里是推薦在條件允許的情況下,用快照對已上線的系統做數據備份,說是比傳統的數據備份與恢復要快。

 

如何做好熱修復?

比如說現在已經上線的是版本7,正在開發的是版本8,而且版本8在DB schema上有些改動。此時有些bug導致需要對版本7做些熱修復,也涉及到了schema的改動。

一般來說,雖然代碼有多個分支,不過schema不會。所以可以將熱修復的腳本標號為7.1,並且適用於修復版本7,和新的版本8。這樣在版本8真正上線的時候,也會按照7、7.1、8的順序執行腳本。

如果上述方案不行,還可以用outOfOrder(在flyway.conf有這個參數)屬性,這樣就可以允許不全部按照從小到大的順序執行migration,也就是比schema_version中記錄的最大值小的腳本,也能夠被執行。

 

多個節點能夠並行執行migration嗎?

當然可以!Flyway使用數據庫鎖機制(locking technology of your database)來協調多個節點,從而保證多套應用程序可同時執行migration,而且集群控制也可做配置。

 

如果migration執行失敗,會有回滾嗎?

Flyway在不同的事物中執行migration,如果失敗,那么事物就會回滾。不過不幸的是,現在只有DB2、PostgreSQL、Derby還有個別SQL Server擴展支持事物內的DDL。Other databases such as Oracle will implicitly sneak in a commit before and after each DDL statement, drastically reducing the effectiveness of this roll back. (沒看太懂得一句)。一個可行的辦法就是一個migration只包含單個DDL,只不過這樣做比較累。

 

Flyway是否支持多schema?

當然支持!以下有幾種策略來處理多schema的情況:

如果有多個相異的schema,可以用flyway的loop並且設置與schema對應的flyway.schemas。

 

如果schema的生命周期相同,那么可以只用一個flyway實例,設置flyway.schemas值為所有schemas以逗號隔開的字符串。所有的schema將只用到一個schema_version來記錄腳本執行情況。(不知道此時schema_version表中會不會有專門的一列顯示schema的名稱)

 

如果schemas的生命周期不同,那就要啟動多個flyway實例,每個實例處理自己的schema和metedata table,注意要把腳本分開放。

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM