Team Foundation Server (TFS)集成Flyway,实现数据库的版本管理
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--