Flyway:數(shù)據(jù)庫版本遷移工具的介紹

flyway-logo.jpg

Flyway介紹

Flyway的定位:數(shù)據(jù)庫的版本控制。

用一種簡單澈吨、干凈的方案把敢,幫助用戶完成數(shù)據(jù)庫遷移的工作。使用Flyway谅辣,用戶可以從任意一個數(shù)據(jù)庫版本遷移到最新版本修赞,簡單而且有效。

支持多個平臺:windows桑阶、ios柏副、linux、docker蚣录、java割择、android

2018年度,產品被下載1千萬多次:

flyway-download-stat.jpg

開源:

flyway-open-source.jpg

支持多種使用方式:

flyway-varias-client.jpg

基于命令行模式包归,用戶從官網下載工具包锨推,進行一些必要的配置铅歼,就可以通過命令行使用其功能。

基于Java API换可,用戶可以將Flyway提供的第三方包加入classpath椎椰,通過Flyway提供的API來使用其功能。

基于Maven或Gradle沾鳄,用戶可以通過配置插件慨飘,運行mvn或gradle命令來使用其功能。

支持多種數(shù)據(jù)庫:

flyway-database-support.jpg

被spring-boot集成:

flyway-spring-boot-support.jpg

官方文檔簡潔译荞,以我這樣蹩腳的英語水平瓤的,也很容易理解。

P.S. 開源版本支持大部分常用的功能吞歼,F(xiàn)lyway還有商業(yè)版本圈膏,會支持一些額外的功能。

Flyway的工作模式

這一節(jié)主要介紹Flyway是如何工作的篙骡,也可以理解為flyway的數(shù)據(jù)庫升級方案稽坤。

Flyway可以對數(shù)據(jù)庫進行升級,從任意一個版本升級到最新的版本糯俗。但是升級的依據(jù)是用戶自己編寫的sql腳本尿褪,用戶自己決定每一個版本的升級內容。

Flyway不限定腳本里面的內容得湘,但是對腳本文件的名稱有一定的要求:

flyway-script-name.jpg

版本號可以使用小版本杖玲,如V1.1。

具體要求:

  • 版本號和版本描述之間淘正,使用兩個下劃線分隔摆马。
  • 版本描述之間,使用一個下劃線分隔單詞跪帝。
  • 版本號唯一:不允許多個腳本文件有相同的版本號今膊。

使用Flyway升級,flyway會自動創(chuàng)建一張歷史記錄表:flyway_schema_history伞剑。

這張表記錄了每一次升級的記錄斑唬,包括已經執(zhí)行了哪些腳本,腳本的文件名黎泣,內容校驗和恕刘,執(zhí)行的時間和結果:

flyway-schema-history.jpg

flyway在升級數(shù)據(jù)庫的時候,會檢查已經執(zhí)行過的版本對應的腳本是否發(fā)生變化抒倚,包括腳本文件名褐着,以及腳本內容。如果flyway檢測到發(fā)生了變化托呕,則拋出錯誤含蓉,并終止升級频敛。

如果已經執(zhí)行過的腳本沒有發(fā)生變化,flyway會跳過這些腳本馅扣,依次執(zhí)行后續(xù)版本的腳本斟赚,并在記錄表中插入對應的升級記錄。

所以差油,flyway總是冪等的拗军,而且可以支持跨版本的升級。

如果你好奇蓄喇,flyway如何檢查腳本文件的內容是否有修改发侵。你可以注意以下記錄表中有一個字段checksum,它記錄了腳本文件的校驗和妆偏。flyway通過比對文件的校驗和來檢測文件的內容是否變更刃鳄。

使用上面的方式,升級一個空的數(shù)據(jù)庫钱骂,或者在一直使用flyway升級方案的數(shù)據(jù)庫上進行升級铲汪,都不會又問題。但是罐柳,如果在已有的數(shù)據(jù)庫引入flyway,就需要一些額外的工作狰住。

flyway檢測數(shù)據(jù)庫中是否有歷史記錄表张吉,沒有則代表是第一次升級。此時催植,flyway要求數(shù)據(jù)庫是空的肮蛹,并拒絕對數(shù)據(jù)庫進行升級。

你可以設置baseline-on-migrate參數(shù)為true创南,flyway會自動將當前的數(shù)據(jù)庫記錄為V1版本伦忠,然后執(zhí)行升級腳本。這也表示用戶所準備的腳本中稿辙,V1版本的腳本會被跳過昆码,只有V1之后的版本才會被執(zhí)行。

下文在介紹Maven客戶端的時候邻储,會介紹另一種方案赋咽,實現(xiàn)在已有數(shù)據(jù)庫中第一次引入flyway。

Flyway的使用場景

命令行

用戶可以在官網下載適合自己平臺的工具包吨娜,進行相關配置之后脓匿,就可以通過命令行的方式使用Flyway。

這一塊只是在官網上看到其介紹宦赠,本人并沒有嘗試陪毡,我直接選擇了后面的方案米母。

使用Maven或Gradle插件

這種方式可以代替命令行的方式,因為我們項目中就使用maven毡琉,所以我更傾向于使用這種方式铁瞒。

以Maven為例,在pom文件中進行必要的配置绊起,包括插件及插件所需要的一些數(shù)據(jù)庫連接信息精拟,就可以通過運行插件來使用其功能。

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
    <properties>
        <flyway.user>postgres</flyway.user>
        <flyway.password>postgres</flyway.password>
        <flyway.url>jdbc:postgresql://localhost:5432/test?currentSchema=demo_flyway</flyway.url>
        <flyway.driver>org.postgresql.Driver</flyway.driver>
    </properties>

    <dependencies>
        ...
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        ...
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.flywaydb</groupId>
                <artifactId>flyway-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

maven插件所支持的命令:

flyway-maven-support.jpg

使用maven命令執(zhí)行插件虱歪,默認在classpath:/db/migration目錄搜索腳本蜂绎,如果該目錄不存在,命令將被忽略笋鄙。

所有的命令师枣,以如下的格式執(zhí)行:

mvn flyway:{flyway-command}

migrate

mvn flyway:migrate

這個命令會搜索默認的腳本目錄,檢測并根據(jù)結果選擇執(zhí)行升級腳本萧落。

clean

mvn flyway:clean

這個命令會清除指定schema下所有的對象践美,包括table、view找岖、triggers...陨倡,讓schema變成空的狀態(tài)。

info

mvn flyway:info

這個命令顯示指定schema的升級狀態(tài)许布,當前的數(shù)據(jù)庫的版本信息兴革。

validate

mvn flyway:validate

這個命令用于校驗,范圍包括已升級的腳本是否改名蜜唾,已升級的腳本內容是否修改杂曲。所有針對已升級的腳本進行的改動都會導致校驗失敗。

執(zhí)行migrate會自動進行校驗袁余,如果失敗將不會做任何的migrate擎勘。

flyway希望用戶提供的腳本是穩(wěn)定的,以免造成額外的復雜性和混亂颖榜。

baseline

mvn flyway:baseline

如果用戶從一個已有的數(shù)據(jù)庫導出腳本棚饵,作為flyway的升級腳本。已存在的數(shù)據(jù)庫是不需要升級的朱转。

baseline用于將當前數(shù)據(jù)庫標記為baseline蟹地,并記錄version為1。這表示用戶繼續(xù)執(zhí)行migrate命令時藤为,會自動跳過V1版本對應的腳本怪与。

而對于空的數(shù)據(jù)庫,因為沒有執(zhí)行baseline缅疟,所以可以正常的執(zhí)行V1版本對應的腳本分别。

P.S. 手動修改flyway自動生成的baseline記錄遍愿,將版本號改為其他的版本號,將自動跳過該版本及更早的版本耘斩。

Java API

Flyway提供了基于Java的API包沼填,用戶可以將API包引入maven依賴,直接通過調用其API來執(zhí)行相關命令括授。

Spring-Boot集成了Flyway坞笙,只要把API包加入classpath,spring-boot在啟動應用時會去指定的目錄查找腳本文件荚虚,并根據(jù)一定的策略選擇或忽略執(zhí)行薛夜。

使用Spring-Boot,用戶不必再顯式的編寫代碼調用API版述,只需要將腳本文件放在約定的目錄梯澜,或者告訴Spring-Boot你把腳本文件放在哪里了。

如果用戶需要實現(xiàn)非常靈活的遷移渴析,Spring-Boot默認的方案無法滿足晚伙,也可以嘗試尋找自己編碼調用API的方案。

以下內容介紹基于Spring-Boot + Maven的集成方案:

step1:在maven中引入flyway依賴

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
    ...
    <dependencies>
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
              ...
    </dependencies>
    ...
</project>

flyway-core即為我們所說的API包俭茧,除此之外咆疗,還要引入postgresql驅動包和spring-boot-starter-jdbc。

step2:配置application

按照常規(guī)的方式母债,在application.yml文件中配置spring.datasource系列:

spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/test?currentSchema=demo_flyway
    driver-class-name: org.postgresql.Driver
    username: postgres
    password: postgres

spring為flyway準備了專屬的數(shù)據(jù)源配置民傻,但是在默認的情況下,可以直接使用spring.datasource的配置场斑。

flyway-config-datasource.jpg

用戶可以將腳本放在約定的位置:classpath:/db/migration,或者配置一個自定義的位置:

flyway-config-locations.jpg

step3:在指定的目錄編寫腳本

如果用戶沒有特地設置腳本的位置牵署,則應該在/db/migration創(chuàng)建腳本漏隐。否則,在對應的位置創(chuàng)建腳本奴迅。

使用總結

我們是在中途嘗試使用flyway青责,所以開發(fā)環(huán)境會有一個已存在的數(shù)據(jù)庫。我們需要從開發(fā)環(huán)境中導出數(shù)據(jù)庫腳本取具,并對開發(fā)環(huán)境數(shù)據(jù)庫進行baseline標記脖隶。導出的腳本可用于新環(huán)境的部署。

如果我們已經有了生產環(huán)境暇检,而且生產環(huán)境和開發(fā)環(huán)境的數(shù)據(jù)庫已經有了較大的差異产阱。暫時可以想到的方案大概有2個方案:

方案一:

在生產環(huán)境備份數(shù)據(jù)庫,然后創(chuàng)建一個全新的數(shù)據(jù)庫块仆,手動將備份庫里的數(shù)據(jù)導入到新的數(shù)據(jù)庫构蹬。

方案二:

基于生產環(huán)境的數(shù)據(jù)庫王暗,創(chuàng)建V1版本的腳本;基于開發(fā)庫相對于生產庫的變更庄敛,創(chuàng)建V2版本的腳本俗壹。在開發(fā)環(huán)境baseline,然后修改版本記錄藻烤,改為2绷雏。在生產環(huán)境中baseline,然后migrate使其升級到2怖亭。

方案一涎显,需要更多的人工介入,但是比較穩(wěn)妥依许;方案二棺禾,難點在于溯源出正確的差異,編制V2腳本峭跳。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末膘婶,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蛀醉,更是在濱河造成了極大的恐慌悬襟,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拯刁,死亡現(xiàn)場離奇詭異脊岳,居然都是意外死亡,警方通過查閱死者的電腦和手機垛玻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門割捅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人帚桩,你說我怎么就攤上這事亿驾。” “怎么了账嚎?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵莫瞬,是天一觀的道長。 經常有香客問我郭蕉,道長疼邀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任召锈,我火速辦了婚禮旁振,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己规求,他們只是感情好筐付,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著阻肿,像睡著了一般瓦戚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丛塌,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天较解,我揣著相機與錄音,去河邊找鬼赴邻。 笑死印衔,一個胖子當著我的面吹牛,可吹牛的內容都是我干的姥敛。 我是一名探鬼主播奸焙,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼彤敛!你這毒婦竟也來了与帆?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤墨榄,失蹤者是張志新(化名)和其女友劉穎玄糟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體袄秩,經...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡阵翎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了之剧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片郭卫。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖背稼,靈堂內的尸體忽然破棺而出箱沦,到底是詐尸還是另有隱情,我是刑警寧澤雇庙,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站灶伊,受9級特大地震影響疆前,放射性物質發(fā)生泄漏。R本人自食惡果不足惜聘萨,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一竹椒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧米辐,春花似錦胸完、人聲如沸书释。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爆惧。三九已至,卻和暖如春锨能,著一層夾襖步出監(jiān)牢的瞬間扯再,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工址遇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留熄阻,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓倔约,卻偏偏與公主長得像秃殉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子浸剩,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內容