65.9K
CodeProject 正在变化。 阅读更多。
Home

避免数据库部署灾难 - 7 个技巧

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2014年7月9日

CPOL

6分钟阅读

viewsIcon

22746

如果您正在考虑采用数据库源代码控制,或者已经有了一个系统但尚未持续使用,这里有七个技巧可以帮助您避免部署灾难。

引言

任何需要管理数据库变更的人都希望能实现“持续交付”的梦想。能够使用一个经过精心打磨的部署机制来升级生产数据库,使得任何变更都可以在版本控制系统(VCS)中完成,经过集成、严格测试后,快速而自信地部署到生产环境,并有适当的回滚路径。

在最近的一篇文章中,Phil Factor 描述了数据库持续交付的挑战和好处,并特别指出:“……如果团队尽早开始部署,并持续完善其构建、测试和部署流程,最明显的好处就是可预测性。”

如果说数据库的持续交付是梦想,那么对许多团队来说,发布数据库变更的现实更像是“一边念着‘千万别出问题,千万别出问题’的古老咒语,一边按下‘开始’按钮”。数据库部署非但不是一个快速、自动化和可预测的过程,反而成了一个“路障”,会冒出无数最后一刻的问题,导致通宵达旦地紧急重写代码,并延迟向客户交付功能。

这种混乱发布之后的直接后果是,随着用户发现错误和其他问题,会周期性地出现“爆炸”情况。此时,人们往往倾向于绕过那个一开始就造成如此多痛苦的“官方”部署流程,直接在生产数据库上进行后续的升级,尤其是那些“又快又急”的修复。

即使存在一个可靠且自动化的部署流程,对任何规模的数据库通过源代码控制进行变更并进行全面测试,也可能需要数小时而非数分钟。如果线上数据库应用程序中的一个错误直接影响到客户,进而影响到整个业务,那么很可能会有强烈的要求“立即”修复,而不是在几小时后。

因此,在我们努力实现所有数据库部署都通过源代码控制完全自动化和测试的持续交付目标时,我们如何最好地应对现实情况:您要么没有设置数据库源代码控制,要么团队中没有人持续使用数据库VCS,或者您正在尝试,但还没有时间去正确学习它。因此,尽管持续交付的目标是隧道尽头的光明,但您可能连隧道入口都还没到。

这里有七件事,您应该做到“把自家后院整理好”,以便在初次部署后,因那些业务关键的数据库错误而被迫直接进行生产环境升级时,避免灾难的发生。

1. 采用VCS并持续跟踪模式版本。

如果您的数据库甚至还没有纳入源代码控制,那么毫无疑问,为您的数据库开发和部署流程能做的最好的事情,就是将您的数据库脚本和文件放入VCS中。源代码控制使数据库开发更可靠、可审计且更易于部署。它提供了帮助您管理数据库日益增长的复杂性的功能,并使其更易于维护。

如果您没有持续使用数据库源代码控制,这里有一些建议:您的团队应该能够从源代码控制中的任何版本构建出相应版本的数据库。这意味着生产数据库“2.1.0.1”版本的模式应该与VCS中“2.1.0.1”版本的模式完全匹配。如果您被迫直接修改生产数据库,您需要立即将变更重新整合到VCS中,以避免版本漂移。

2. 在进行更改前的那一刻,创建数据库快照或备份。

我没想到这会是很多人面临的问题,但我不断听说因为部署前没有备份数据库而加剧的灾难。如果是在一个大型数据库上进行紧急修复,并且您运行的是企业版SQL Server,那么数据库快照可以是一个有用且更快的替代方案。

一位自由开发者告诉我一个他曾服务过的客户的故事,该客户明确拒绝在部署前进行备份。当部署出现问题时,客户会回头找他,要求他恢复系统。这种情况发生得太频繁,浪费了他大量时间,于是他启动了一个“未经授权的备份制度”,这个制度现在已经无数次派上用场。教训很简单——在做出那个更改之前,进行一次数据库备份或快照!

3. 更新生产数据库时,最好有一个经过充分测试的回滚脚本作为保障。

换句话说,每个“up”(迁移)脚本都需要一个“down”(回滚)脚本。如果您没有将数据库纳入源代码控制,那么回滚实际上就是您的保险单。有些人会告诉您,如果您有好的备份,就不需要回滚脚本,但这是个坏建议。从备份中恢复是一种全有或全无的操作,在最关键的时候会浪费大量时间;而且,您会丢失自备份开始以来发生的所有数据更改。在对生产环境进行更改时,您需要在使用回滚脚本之前,检查它们是否按预期工作。在飞机着火前,先检查降落伞上有没有洞。

4. 将“up”脚本包装在一个事务中。

当需要将数据库变更部署到生产环境时,在 `BEGIN TRANSACTION….ROLLBACK TRANSACTION` 块中执行脚本。执行脚本(不包括 `ROLLBACK`),验证对对象和行的更改是否完全符合您的预期。如果符合,就提交;如果不符合,就回滚,并进行进一步测试。请记住,如果数据库是在线的,这可能会阻塞对受影响表的任何并发事务。

5. 任何数据库升级都应通过保存到VCS中的脚本进行。切勿使用图形用户界面(GUI)来部署更改。

GUI不是您的朋友。当然,它在日常的数据库设计和开发中能为您节省时间,但在部署数据库更改时,它可能会凶猛地反咬您一口。您需要使用有完整文档的迁移脚本,并将它们存储在VCS中。由脚本驱动的部署是可重复的,并且更容易记录和检查。它们也不太容易出现人为错误(另请参见技巧6和7)。当问题开始爆发时,您会庆幸变更脚本都保存在VCS中,团队中的任何人都可以快速参考。

6. 先在非生产系统上测试脚本。

当那些直接升级导致线上数据库性能严重下降时,“在我的机器上能用”是行不通的。您必须有一个某种程度上真实的测试环境,其数据量和分布与线上数据接近,您可以在其中进行一些基本测试。否则,无法判断更改在生产环境这个真实世界中的表现如何。

7. 在可能的情况下,部署前让第二个人验证您将要做的事情。

这一点与第6点相辅相成,因为人无完人。如果可能的话,在部署之前,请人检查一下您计划推送到生产环境的内容。微不足道的错误可能会导致大问题。一些建议是,为您的团队建立一些基于源代码的代码审查实践,这不难管理,但能带来很大的不同。

SQL源代码控制基础

如果您希望在数据库源代码控制的道路上继续前进,这本电子书详细讲解了相关概念,并附有代码示例。

下载免费电子书

本文最初发布于Simple-Talk,一个技术期刊和社区中心。

本文最初发布于 Simple-Talk,一个技术期刊和社区中心。

© . All rights reserved.