如何在现实世界中“升级”数据库?

6
我的公司使用php + mysql开发了一个Web应用程序。该系统可以向用户显示产品的原始价格和折扣价格。如果您没有登录,您将得到原始价格;如果您已经登录,则会获得折扣价。这很容易理解。
但是,我的公司希望在系统中添加更多功能,它希望根据不同的用户显示不同的价格。例如,用户A是黄金合作伙伴,他可以享受50%的折扣。用户B是银色合作伙伴,只有30%的折扣。但是,在原始系统中没有准备好这种逻辑,因此我需要在数据库中添加一些属性,例如在这个例子中至少需要一个用户类型。是否有任何建议可以将当前数据库合并到我的新版本数据库中?此外,所有数据都应该被保留,并且服务器应该24/7运行(不停止数据库)。
这样做可能吗?同时,是否有未来维护建议的推荐?谢谢。

你是否在寻求一种方法来同时升级数据库和代码?您是否有任何“复杂”的缓存?如果您将整个网站设置为“维护模式”,告诉用户他们目前无法登录-您能否同时运行SQL ALTER语句并上传代码?我们在谈论多少rps?在清晨几秒钟的停机时间内,是否会有人注意到? - jlindenbaum
我明白你的意思... 我想我可以安排几个小时进行维护。 - Tattat
3个回答

1

1
我建议编写一个工具来逐步运行SQL查询到您的数据库中,就像Rails迁移一样。
在我目前工作的系统中,我们有这样一个用Python编写的工具,我们将脚本命名为000000_somename.sql,其中0是我们SCM(子版本)中的修订号,该工具作为开发/测试的一部分运行,并最终部署到生产环境中。
这样做的好处是能够回溯数据库更改的历史记录,就像代码一样(如果您使用源代码版本控制工具)。

0

你在数据访问层使用ORM了吗?我知道Doctrine带有迁移API,允许版本向上或向下切换(以防新版本出现问题)。

除了任何框架或ORM的考虑之外,快速脚本将最小化减速(或如果进程太长则会停机)。

依我之见,我宁愿网站访问中断30秒并显示信息页面,也不愿意出现更短的中断时间,但出现可见的错误或根本没有显示。如果中断时间很重要,最好在夜间或交通较少时进行。

这可以在一个脚本中完成(或者至少由一个命令行启动),当我们需要执行这样的脚本时,我们将其包含在shell脚本中:

  • 将应用程序置于待机状态(临时静态页面):您可以使用.htaccess重定向或适用于您的应用程序/服务器环境的任何内容。
  • svn更新(或切换)源代码和资产升级
  • 清空缓存,清理临时文件等。
  • 重新生成生成的类(仅限Symfony)
  • 使用ALTER / CREATE TABLE查询升级DB结构
  • 如果需要,从旧结构迁移数据到新结构:根据您在结构上所做的更改,可能需要在更改DB结构之前获取数据,或使用tmp表。
  • 如果一切顺利,请删除临时页面。升级完成
  • 如果出现问题,请向操作员显示红色消息,以便它可以看到发生了什么,尝试修复它,然后手动删除等待页面。

脚本应在每个步骤进行检查并停止第一个错误,并且应在所有步骤中详细说明其所做的事情,因此如果出现故障,则可以更快地修复应用程序。最好是可恢复的脚本(在第2步出错-停止过程-手动修复-在第3步恢复),我从未花时间以这种方式实现它。

这个工作非常好,但是这种脚本必须经过密集测试,使用尽可能接近生产环境的环境。通常我们在本地开发这样的脚本,并在与生产环境相同的平台上进行测试(只是不同的路径和数据库)。

如果等待页面不是一个选项,您可以不用等待,但需要确保数据和用户会话的完整性。例如,在升级/数据传输期间对表使用LOCK,并在修改的文件上使用独占锁(我认为SVN会这样做)。

可能有其他更好的解决方案,但基本上这就是我使用的方法,它为我们完成了工作。主要缺点是这种脚本必须在每个主要版本发布时重新编写,这促使我寻找其他选项来完成此操作,但是哪一个?如果这里有人有更好和更简单的替代方案,我会很高兴。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接