Flyway:數據庫版本遷移工具的介紹

[TOC]java

Flyway介紹

Flyway的定位:數據庫的版本控制。linux

用一種簡單、乾淨的方案,幫助用戶完成數據庫遷移的工做。使用Flyway,用戶能夠從任意一個數據庫版本遷移到最新版本,簡單並且有效。android

支持多個平臺:windows、ios、linux、docker、java、androidios

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

開源:sql

支持多種使用方式:docker

基於命令行模式,用戶從官網下載工具包,進行一些必要的配置,就能夠經過命令行使用其功能。數據庫

基於Java API,用戶能夠將Flyway提供的第三方包加入classpath,經過Flyway提供的API來使用其功能。windows

基於Maven或Gradle,用戶能夠經過配置插件,運行mvn或gradle命令來使用其功能。app

支持多種數據庫:

被spring-boot集成:

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

P.S. 開源版本支持大部分經常使用的功能,Flyway還有商業版本,會支持一些額外的功能。

Flyway的工做模式

這一節主要介紹Flyway是如何工做的,也能夠理解爲flyway的數據庫升級方案。

Flyway能夠對數據庫進行升級,從任意一個版本升級到最新的版本。可是升級的依據是用戶本身編寫的sql腳本,用戶本身決定每個版本的升級內容。

Flyway不限定腳本里面的內容,可是對腳本文件的名稱有必定的要求:

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

具體要求:

  • 版本號和版本描述之間,使用兩個下劃線分隔。
  • 版本描述之間,使用一個下劃線分隔單詞。
  • 版本號惟一:不容許多個腳本文件有相同的版本號。

使用Flyway升級,flyway會自動建立一張歷史記錄表:flyway_schema_history。

這張表記錄了每一次升級的記錄,包括已經執行了哪些腳本,腳本的文件名,內容校驗和,執行的時間和結果:

flyway在升級數據庫的時候,會檢查已經執行過的版本對應的腳本是否發生變化,包括腳本文件名,以及腳本內容。若是flyway檢測到發生了變化,則拋出錯誤,並終止升級。

若是已經執行過的腳本沒有發生變化,flyway會跳過這些腳本,依次執行後續版本的腳本,並在記錄表中插入對應的升級記錄。

因此,flyway老是冪等的,並且能夠支持跨版本的升級。

若是你好奇,flyway如何檢查腳本文件的內容是否有修改。你能夠注意如下記錄表中有一個字段checksum,它記錄了腳本文件的校驗和。flyway經過比對文件的校驗和來檢測文件的內容是否變動。

使用上面的方式,升級一個空的數據庫,或者在一直使用flyway升級方案的數據庫上進行升級,都不會又問題。可是,若是在已有的數據庫引入flyway,就須要一些額外的工做。

flyway檢測數據庫中是否有歷史記錄表,沒有則表明是第一次升級。此時,flyway要求數據庫是空的,並拒絕對數據庫進行升級。

你能夠設置baseline-on-migrate參數爲true,flyway會自動將當前的數據庫記錄爲V1版本,而後執行升級腳本。這也表示用戶所準備的腳本中,V1版本的腳本會被跳過,只有V1以後的版本纔會被執行。

下文在介紹Maven客戶端的時候,會介紹另外一種方案,實如今已有數據庫中第一次引入flyway。

Flyway的使用場景

命令行

用戶能夠在官網下載適合本身平臺的工具包,進行相關配置以後,就能夠經過命令行的方式使用Flyway。

這一塊只是在官網上看到其介紹,本人並無嘗試,我直接選擇了後面的方案。

使用Maven或Gradle插件

這種方式能夠代替命令行的方式,由於咱們項目中就使用maven,因此我更傾向於使用這種方式。

以Maven爲例,在pom文件中進行必要的配置,包括插件及插件所須要的一些數據庫鏈接信息,就能夠經過運行插件來使用其功能。

<?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插件所支持的命令:

使用maven命令執行插件,默認在classpath:/db/migration目錄搜索腳本,若是該目錄不存在,命令將被忽略。

全部的命令,以以下的格式執行:

mvn flyway:{flyway-command}

migrate

mvn flyway:migrate

這個命令會搜索默認的腳本目錄,檢測並根據結果選擇執行升級腳本。

clean

mvn flyway:clean

這個命令會清除指定schema下全部的對象,包括table、view、triggers...,讓schema變成空的狀態。

info

mvn flyway:info

這個命令顯示指定schema的升級狀態,當前的數據庫的版本信息。

validate

mvn flyway:validate

這個命令用於校驗,範圍包括已升級的腳本是否更名,已升級的腳本內容是否修改。全部針對已升級的腳本進行的改動都會致使校驗失敗。

執行migrate會自動進行校驗,若是失敗將不會作任何的migrate。

flyway但願用戶提供的腳本是穩定的,以避免形成額外的複雜性和混亂。

baseline

mvn flyway:baseline

若是用戶從一個已有的數據庫導出腳本,做爲flyway的升級腳本。已存在的數據庫是不須要升級的。

baseline用於將當前數據庫標記爲baseline,並記錄version爲1。這表示用戶繼續執行migrate命令時,會自動跳過V1版本對應的腳本。

而對於空的數據庫,由於沒有執行baseline,因此能夠正常的執行V1版本對應的腳本。

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

Java API

Flyway提供了基於Java的API包,用戶能夠將API包引入maven依賴,直接經過調用其API來執行相關命令。

Spring-Boot集成了Flyway,只要把API包加入classpath,spring-boot在啓動應用時會去指定的目錄查找腳本文件,並根據必定的策略選擇或忽略執行。

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

若是用戶須要實現很是靈活的遷移,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

按照常規的方式,在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準備了專屬的數據源配置,可是在默認的狀況下,能夠直接使用spring.datasource的配置。

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

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

若是用戶沒有特意設置腳本的位置,則應該在/db/migration建立腳本。不然,在對應的位置建立腳本。

使用總結

咱們是在中途嘗試使用flyway,因此開發環境會有一個已存在的數據庫。咱們須要從開發環境中導出數據庫腳本,並對開發環境數據庫進行baseline標記。導出的腳本可用於新環境的部署。

若是咱們已經有了生產環境,並且生產環境和開發環境的數據庫已經有了較大的差別。暫時能夠想到的方案大概有2個方案:

方案一:

在生產環境備份數據庫,而後建立一個全新的數據庫,手動將備份庫裏的數據導入到新的數據庫。

方案二:

基於生產環境的數據庫,建立V1版本的腳本;基於開發庫相對於生產庫的變動,建立V2版本的腳本。在開發環境baseline,而後修改版本記錄,改成2。在生產環境中baseline,而後migrate使其升級到2。

方案一,須要更多的人工介入,可是比較穩妥;方案二,難點在於溯源出正確的差別,編制V2腳本。

相關文章
相關標籤/搜索