近期我们升级了自创立 InfoQ.com 以来一直使用的后台数据库。然而,一切并没有完全按照计划进行,虽然我们已经完成了大部分工作的顺利迁移,并解决了在迁移过程中遇到的一些意料之外的问题。这篇文章主要是讨论我们的计划是什么,哪些有效,哪些无效,以及如何检测错误并从这些错误中恢复。
计划
本次升级的规划还是很复杂的,横跨了几个月。由于我们的硬件在 2006 年系统上线以来就没有升级过,所以我们现有的数据库服务器基本上是在满负荷运作,而且这已经开始导致网站在性能上出现一些问题,特别是在执行一些定期的报表任务的时候。另外,对于 InfoQ 来说,这次升级提供了一个很好的契机,我们把数据库从单一的主 MySQL 数据库迁移到了主 / 从 MySQL 配置,这样可以更好地支持故障热切,运行报表和数据备份,从而避免用户在访问网站时受到这些进程的性能影响。
迁移计划包括如下步骤:
- 准备工作:这包括互联网服务供应商(Contegix)与我们的开发部门、运营团队的电话会议,制定执行计划,准备好所有必须的配置文件,同时确保互联网服务提供商知道所有的计划细节
- 服务时间 / 数据传输:这包括安全可控的关闭 MySQL(停止 Web 服务器,确保所有的事务都被提交,设置数据库为只读,校验事务日志,关闭 MySQL),通过物理方式把旧的数据库服务器与数据中心的新服务器连接起来以保证最大的传输速度,从旧的服务器复制数据到新服务器并进行数据校验,然后重新恢复网站的所有服务,InfoQ.com 就可以继续运行(这时还是使用旧的数据库服务器)
- 存储引擎 InnoDB 的表转换:主要工作包括在新数据库服务器上启动 MySQL,通过 mysqldump 导出表数据,关闭 MySQL,清除已有数据,重新导入数据并将其转换为 file-per-table 模式(每个步骤都要进行校验)。
- 第一个从属服务器的设置:在旧服务器上指定新的从属数据库服务器,确保主从服务器的数据被正确复制,然后把报表任务指向新的从属服务器
- 第二个从属服务器的设置:第一个新的数据库服务器上指定第二个新的从属服务器,确保主从服务器的数据被正确复制——配置方式是主服务器 <–第一个从属服务器 <–第二个从属服务器,这种方式可以实现两个从属服务器之间的快速同步,而不是从一个已经满负荷或过载的主服务器上同步数据,那种配置方式是主服务器 <–第一个从属服务器,第二个从属服务器
- 主服务器的交换:从现在的旧的主服务器切换到新服务器(也就是第一从属服务器),然后把旧主服务器设置为一个新的从属服务器,同时把 web 服务器指向新的主数据库
同时还决定的事情包括,在两个新的从属服务器上安装 MySQL5.1,这可以节省后续的 MySQL 升级时间。我们的研究表明可以成功实现从 MySQL5.0 的主服务器到 MySQL5.1 的从属服务器的同步,所以,通过在从属服务器上使用 MySQL5.1,我们就可以在把第一个从属服务器切换成新的主服务器同时,实现 MySQL5.1 的升级
其他可能的选项之一(主要是考虑避免停机)是在主服务器执行 mysqldump 并将数据转移到从属服务器上,而不是停掉主服务器之后再进行文件复制——不过,高应用级别服务器需求排除了这一可能性,因为在主数据库服务器上执行备份任务将对服务器造成巨大的负载压力,最终会形成事实上的停机,因为我们可以预料到站点会变的有多慢。
执行计划
第一个挑战是找到一个很好的时间来进行升级——开发团队在罗马尼亚,ISP 在密苏里州,运营团队在温哥华和美国俄勒冈州。最终我们选择了太平洋时间周五晚上(欧洲的周六早晨),这是因为这个时间点 InfoQ.com 的访问量相对平缓,还有一个好处就是运营团队晚上开始,开发团队早晨开始(罗马尼亚和温哥华有 10 小时的时差)。一旦时间确定,第一步也就完成了。
第二步,最初预计停机时间是 2 小时,主要工作就是通过以太网把两台服务器连接起来。然而由于遇到一些网络问题,最终用了 5 个多小时才完成。这也告诉了我们重要的一点:如果你认为独立的数据中心不会发生网络问题,那么你就大错特错了。
在此之后,步骤 3 到 6 都进行得非常顺利,没有遇到其他问题。2 月 26 日我们实现了新的主数据库的切换,在一轮基本的测试完成之后,我们感到所有的事情似乎都比较正常。网站的响应速度快了很多,这是一个非常好的工作成果,我们对总体进程也感到很满意。
然而,如果故事就此结束,那么这将是一篇很无聊的文章 :)
评论系统的问题
系统迁移之后的几天,首先引起我们注意的是评论系统出现了一些问题。尤其是新的评论似乎被添加到网站上了,但是很快,几分钟之后这些评论就消失了,给用户造成的印象是这些评论被删除了。最终我们吃惊的发现,造成这一结果的原因是由于我们激活了数据库服务器的主/ 从复制功能,但 Jive 论坛目前使用的数据版本仍然是没有评论的。解决这一问题的办法是把事务的隔离级别从 READ_UNCOMMITTED 改为 REPEATABLE_READ(这是因为在复制环境中采用 READ_UNCOMMITTED 隔离级别会抛出错误),修改后评论可以被再次创建了。
但是,这并没有最终解决所有问题。虽然我们的初步测试表明添加评论已经可以正常工作了,但一两天之后我们又开始发现一些非常奇怪的数据一致性问题:特别是,我们注意到在数据库迁移之后创建的文章评论似乎被随意的合并到网站上的现有会话中。通过深入发掘,我们发现 Jive 对它使用的唯一 ID 进行了复位,以保持对主题的跟踪,同时在日志中不显示任何错误或警告信息,基于这样一个分析结果,我们可能覆盖或损坏了现有(尽管是旧的)论坛主题,影响范围应该是计数器从 16000 左右复位为 0 之后。造成这个问题的罪魁祸首是我们为 MySQL 选择了基于行的复制策略,一旦知道了是这个问题我们就能够解决它,并对被错误分配到论坛主题的评论进行数据清洗。
我们学到了什么
在这次升级的过程中,我们有几个额外的收获:
- 详细的计划是重要的:做计划时应该尽可能考虑周全,同时准备好应急预案(包括在某种情况下失败或遇到错误怎么处理),这样事情会顺利得多,而且你可以在出现问题的时候继续坚持计划,而不是在升级过程中被一些意外情况所干扰
- 计划是会变化的:有句老话说得好,“没有任何计划能在遇敌后继续执行”——对于计划而言这句话确实值得思考,但你依然需要准备应对一些突发事件,因为你永远无法考虑到所有的情况
- 系统的调试可以节省时间:你越快排除掉一些可能的情况,就能越快速的找到问题的真正原因。一旦看到一个错误,就 Google 一下,看看 Google 能告诉你什么——对于那些含糊的、非显而易见的错误来说,这样做可以节省大把的时间。
- 积极的寻求反馈:不要等待用户在遇到问题时给你发邮件或直接与你联系——我们第一次了解到这个问题是通过密切关注 Twitter 上的评论,如果我们等待用户发邮件告诉我们他遇到的问题,那么这个问题会存在更长的时间。Twitter 搜索和 Google 快讯是你的朋友——使用他们。
一如往常,我们很想听到您的任何反馈,您可以通过以下的一个或多个反馈渠道为我们提供反馈信息:
- 在 Twitter 上跟随 @InfoQ 中文站(无需翻墙)
- 给我们发邮件 feedback@infoq.com
- 通过 Google 上的 InfoQ 中文站用户组(需翻墙)
- 在 InfoQ 中文站上发表评论
查看英文原文: Upgrading InfoQ.com’s Database: Mostly Smooth, A Couple of Bumps
译者简介:池建强,12 年软件从业经验,先后在洪恩软件和用友集团任职。目前在用友集团瑞友科技 IT 应用研究院任副院长,负责公司基础应用平台的研发和整个公司的技术管理。主要关注领域:企业应用软件平台研发、领域驱动设计,OSGi,动态语言应用、云计算、移动互联等相关技术。
评论 1 条评论