当前位置: 首页 > 数据库 > 存储技术 > 正文

数据库变更部署的自动化秘诀

时间:2016-01-26 infoq Yaniv Yehuda

瞬息万变的世界:敏捷 & DevOps

由于业务需求是变更最主要的驱动者,少做一些,但做得更好,交付更快,这是领先的企业和成功的企业与其他企业的不同之处。

当竞争对手交付了相关功能,速度比你快,质量比你好,那么你最终会丧失市场份额。用投资于销售和市场营销活动的方式弥补产品的不足,其代价会很高,而且可能不可靠,而且你可能会发现,客户转向了质量卓越的产品。

这正是“敏捷开发”产生的原因:需要更快地采取行动,应对不断变化的需求(因为我们的目标市场和竞争对手永远不会静止不动),可信赖的最佳品质,经常资源不足。敏捷就是源于科技公司和IT部门的期望。

自然地,下一步是找到一个将敏捷应用于生产的方法:连接开发和运维。这就产生了“DevOps”。

运维的主要目标是保证应用程序的稳定和健康,而开发的主要目标是不断地创新,并提供满足业务和客户需求的应用程序。理解这两点是DevOps发展的关键。既然变更是稳定最大的敌人这点没有疑问,那么理解和调和这种冲突应该是DevOps的主要目标。

为了有效地掌握敏捷冲刺部署以及实施DevOps,人们需要能够实现部署自动化。否则,部署和发布就需要手动操作步骤和过程,而这些操作并不总是能够准确地重复,容易出现人为错误,并且无法进行高频率地处理。

处理数据库部署并不简单;不像其它软件组件和代码或者已编译的代码,数据库不是一个文件集合。那不是可以从开发环境复制到测试环境然后复制到生产环境的东西,因为数据库是个容器,里面装了我们最有价值且必须保存的资产——业务数据。它保存了所有应有程序内容、客户事务处理等。为了促成数据库变更,需要开发迁移代码——用于处理数据库模式结构(表结构)的脚本、数据库代码(过程、函数等)和应用程序使用的内容(元数据表、查找内容表或者参数表)。

数据库变更部署流程的挑战

应对数据库挑战的一个方法是,迫使数据库变更遵循一般过程:创建数据库对象的脚本,然后存储在传统的版本控制系统中。

那造成了其它的挑战,包括:

由于是两个单独的系统,版本控制系统中的脚本与它们所代表的数据库对象之间没有关联。数据库代码的编写和测试都是在数据库端完成,脱离了任何最佳编码实践(检入、检出、标记等),容易出现“旧时代”的所有问题,比如:

代码覆盖在数据库中很常见,因为没有什么能够防止它发生。

在数据库上运行代码之前,要先从版本控制系统中取得脚本,还要防止工作在错误的版本上;但是没有强制措施可以保证这一点。

脚本在版本控制系统中的路径可能会出错,因为开发人员靠记忆做这件事。

流程之外的更新会被忽视等等。

脚本是手动编写的,容易出现认为错误、语法错误等等。

为了拥有以后可能需要的一切,开发人员竟然不得不为每个对象保存两到三个脚本:对象的实际代码、升级脚本和回滚脚本。

脚本很难进行整体测试。一个人单独更新了一个对象,而另一个人单独更新了另一个对象,如果脚本需要以特定的顺序运行,那么以任意顺序运行通常就会由于错误的依赖关系而产生错误。

如果一个脚本被开发成代表整个更新而不是单个变更的单独脚本,那么它可以处理依赖关系,但处理项目范围的变更就要困难得多了。那是一个很长的命令列表。

除非非常有经验,否则这些脚本中会缺少从编写到运行这段时间内发生在目标环境里的变更;可能会覆盖生产环境中的热补丁,或者与另一个团队并行操作。

内容变更管理非常困难。实际上,版本控制系统不适合元数据或者查找内容。在大部分情况下,根本就没有对它们进行管理。