1 概述
在系統開發過程中,我們對軟件源代碼的版本管理,已經有了比較成熟的解決方案。通過使用TFVC或GIT等源代碼管理工具,可以非常方便的對軟件代碼實現回退、比較、分支合並等版本操作。對於軟件依賴的數據庫呢,我們是否也需要版本管理,如何實現版本管理?
是否需要對數據庫實現版本管理,我們首先來看一個這樣的示例:
假設有一個簡單軟件系統的架構如下,包含了一個軟件應用和一個數據庫節點,軟件通過連接數據庫的方式為用戶提供服務。
這種簡單的軟件結構,在系統開發過程中的實際情況,很可能是這樣的:
Figure 2
從上圖可以看到,在系統開發過程中,我們面對的不是一個單一的數據庫實例;還需要管理不同開發人員、不同運行環境上的數據庫。不同的數據庫實例的結構或數據不一致,都會導致軟件運行的結果不同,甚至出現邏輯錯誤、系統奔潰等現象。如何確保不同服務器上的數據庫實例得到統一管理?這是許多軟件研發團隊頭疼的問題。
在實際開發過程中,許多開發團隊通過手工方式更新不同環境的數據庫腳本,有些甚至通過一些臨時的配置更新數據庫。通過這樣的方式管理數據庫,研發團隊可能立即面臨下面的一些困惑:
- 這個數據庫實例是一個什么狀況?
- 最后一次更新是誰操作的?
- 必須的數據庫腳本/更新是否已經應用到了這個數據庫實例中?
- 怎么新建一個完全一樣的數據庫實例?
- 等等……
面對這些關鍵的問題,你可能完全無所適從。為了解決這些問題,我們需要對數據庫實例實現版本管理,從而精確掌握數據庫的運行狀況。
數據庫版本管理的方案的通用方案是這樣的,在數據庫中創建用於存儲數據庫變更記錄的表(Schema Table);在這張表中記錄每次變更的內容、變更者、變更時間和版本次序等關鍵信息,並以此作為版本管理的基礎數據。根據這種思路,開發團隊可以手工維護這張表的記錄,也可同通過工具自動維護這張表的信息。在這篇文章中,我要為大家介紹一個自動化管理數據庫版本的工具(Flyway),並通過這個工具集成TFS系統,在代碼庫(TFVC或Git)中管理數據庫腳本,並使用TFS系統的持續集成或持續交付功能,實現完全自動維護數據庫腳本的目標。
Flyway是一個專門用於數據庫版本管理的開源工具,支持包括DB2、MySQL
、Oracle、PostgreSQL、SQL Server、SQLite、Sybase、Greenplum等多達20多種常見數據庫,同時可以通過運行在Windows、Linux平台上,並且可以集成在Ant、Maven等自動化工具中,甚至可以直接集成在你的Java程序中。基於這些特征,許多研發團隊使用Flyway作為數據庫實例的版本管理工具。在下面的內容中,我主要介紹如何應用這個工具與TFS服務器的持續集成功能,實現數據腳本的自動化管理。
2 下載flyway命令行工具
首先需要下載必要的軟件。在下面的實驗中,我們利用Flyway的命令行工具,在Windows服務器上,實現對SQL Server數據庫實例的版本管理。你也可以嘗試使用Maven、ant的方式,在TFS系統中實現部署自動化。
l 下載地址:http://flywaydb.org
l 工具文件:Flyway-commondline-w.2.0-windows-x64.zip
說明:Flyway是基於Java的一個軟件工具,但是在上面的軟件包中已經包含了Java運行時環境(JRE);在運行Flyway的過程中,這個工具自動設置Java所需要的系統環境變量,因此你不需要在服務器上安裝JRE,或者配置JAVA_HOME等。
3 配置環境變量
為了可以在任意目錄運行flyway命令,需要將flyway的運行軟件目錄添加到環境變量Path中,如下圖:
4 Flyway的快速入門
安裝好了上面的環境以后,我們就可以通過下面的指導快速瀏覽一下Flyway的功能。
1 查看Flyway功能。你可以在任意目錄中運行flyway,查看這個工具的參數
Figure 3
Fllyway有以下6個主要功能:
命令 |
功能 |
Baseline |
對數據庫的現有狀態創建基線,適用於第一次使用flyway |
Clean |
刪除數據庫中的所有對象 |
Info |
打印數據庫版本的基本信息,例如已經安裝的、當前的和掛起的腳本 |
Validate |
驗證當前腳本與數據的沖突 |
Repair |
修復元數據表中的內容 |
Migrate |
升級,將數據庫腳本中的文件應用到數據庫實例中 |
Flyway還擁有豐富的參數配置。如果在運行腳本過程中不設置任何參考,flyway會自動使用安裝目錄路中的配置文件config/flyway.conf中的配置信息,例如服務器地址、賬戶密碼等。下表是flyway的所有參考信息:
Options (Format: -key=value) ------- driver : Fully qualified classname of the jdbc driver url : Jdbc url to use to connect to the database user : User to use to connect to the database password : Password to use to connect to the database schemas : Comma-separated list of the schemas managed by Flyway table : Name of Flyway's metadata table locations : Classpath locations to scan recursively for migrations resolvers : Comma-separated list of custom MigrationResolvers skipDefaultResolvers : Skips default resolvers (jdbc, sql and Spring-jdbc) sqlMigrationPrefix : File name prefix for sql migrations repeatableSqlMigrationPrefix : File name prefix for repeatable sql migrations sqlMigrationSeparator : File name separator for sql migrations sqlMigrationSuffix : File name suffix for sql migrations mixed : Allow mixing transactional and non-transactional statements encoding : Encoding of sql migrations placeholderReplacement : Whether placeholders should be replaced placeholders : Placeholders to replace in sql migrations placeholderPrefix : Prefix of every placeholder placeholderSuffix : Suffix of every placeholder installedBy : Username that will be recorded in the metadata table target : Target version up to which Flyway should use migrations outOfOrder : Allows migrations to be run "out of order" callbacks : Comma-separated list of FlywayCallback classes skipDefaultCallbacks : Skips default callbacks (sql) validateOnMigrate : Validate when running migrate ignoreMissingMigrations : Allow missing migrations when validating ignoreFutureMigrations : Allow future migrations when validating cleanOnValidationError : Automatically clean on a validation error cleanDisabled : Whether to disable clean baselineVersion : Version to tag schema with when executing baseline baselineDescription : Description to tag schema with when executing baseline baselineOnMigrate : Baseline on migrate against uninitialized non-empty schema configFile : Config file to use (default: <install-dir>/conf/flyway.conf) configFileEncoding : Encoding of the config file (default: UTF-8) jarDirs : Dirs for Jdbc drivers & Java migrations (default: jars) Add -X to print debug output Add -q to suppress all output, except for errors and warnings Add -n to suppress prompting for a user and password Add -v to print the Flyway version and exit Example ------- flyway -user=myuser -password=s3cr3t -url=jdbc:h2:mem -placeholders.abc=def migrate More info at https://flywaydb.org/documentation/commandline |
2 在數據庫服務器上新建一個數據庫,名稱為flywaydb
3 在數據庫服務器新建一個賬戶,flyway,並將其配置為上一步中數據庫的dbowner權限
4 使用flyway初始化數據庫基線
編寫flyway安裝目錄下的配置文件,設置數據庫的路徑、賬戶和密碼
Figure 4 – 修改配置信息
運行flyway的基線命令: flyway baseline,如果命令成功你會看到類似的反饋信息,並在數據庫中看到成功創建了schema_version數據表。
Figure 5 – 運行flyway基線命令
Figure 6 – 基線命令在數據庫中創建的版本數據表:schema_version
5 准備升級的數據庫腳本
我們首先在安裝目錄的sql目錄路中新建SQL腳本文件,文件名的命名規則如下:V1.1__<描述文字>sql
例如,可以使用下面示例的文件名:
- V1.1__CreateUserTable.SQL
- V1.2__InsertUserInfo.SQL
注意:文件名中的分隔符是兩個下划線,否則系統一直提示你文件命名不正確!!!
6 運行數據庫升級腳本
Figure 7
上面的命令將sql目錄中的所有腳本應用到了數據庫中,並更新了schema_version表中的版本記錄,如下圖:
Figure 8
下次更新,你只需要按照上面的規則,增加數據庫腳本文件,再次運行flyway migrate命令,就可以完成數據庫版本的升級,shema_version中會清晰記錄升級版本的歷程。
5 配置TFS持續集成
自TFS 2015開始,TFS提供的全新的持續集成功能,使用條目化、順序完成持續集成過程中的所有任務。我們下面的示例以目前最新的TFS 2018為例,在持續發布中配置Flyway任務。
5.1 將腳本文件上傳到TFS代碼庫中(Git)
Figure 9
5.2 配置持續集成,發布代碼
配置持續集成的目的是,每次當數據庫代碼更新以后,可以將數據庫腳本發布在生成結果中,以備發布使用。如果在發布過程中不需要流程控制,也可以直接參考后面的配置,在生成流程中配置flyway的發布任務。
在下面的截圖中,我配置了一個簡單的生產流程,它將代碼庫中的數據庫文件上傳到生產結果中。
Figure 10
5.3 在發布流程中配置flyway工具
1) 在發布流程中添加上一步創建的生產定義。
2) 安裝自己的需要增加發布環境,如下圖
Figure 11
3) 在發布環境中增加Flyway任務,如下圖
發布流程中添加了一個命令行的任務,命令和參數如下:
Flyway migrate -locations=filesystem:$(Agent.ReleaseDirectory)\$(BUILD.DEFINITIONNAME)\SQLScripts -url=jdbc:jtds:sqlserver://sql2017:1433/flywaydb -user=$(flyway.user) -password=$(flyway.password) |
注意:由於flyway命令需要傳入數據庫訪問的賬戶和密碼,為了密碼數據的保密性,我們可以在發布流程中將password定義成加密的參數(flyway.password)。具體任務的設置如下圖:
Figure 12
4) 執行發布流程
發布完成以后,可以在發布清單中查詢發布的結果;如果發布失敗,也可以在發布日志中查詢明細。
Figure 13 -發布成功清單
Figure 14 – 在發布日志中查看明細
6 總結
我們在上面演示中,介紹了使用TFS系統的代碼庫、持續集成/發布功能,並集成Flyway工具,可以方便的實現數據庫的版本管理,為系統開發人員管理應用軟件中的數據庫更新提供了一個清晰的管理思路。
(http://www.cnblogs.com/danzhang TFS MVP 張洪君)
--End--















