在后台同时更改prod中的sql表/迁移的最佳策略



我目前正在为一个网站设计sql表(我选择了PostgreSQL(,在产品中更新数据库方面我没有太多经验。

同时,我还在对依赖于这个数据库的后端(node.js中(进行编码。

在未来,我将部署所有内容,有时,我可能不得不更新现有的表,如重命名列/表,或删除列等。

现在我希望这些更新对用户来说是完全不可见的,这样我就不希望我的网站离线。

通常,我的策略是在负载均衡器后面有两个实例b1b2,所以当你进行更新时,你会更新b1,重新启动它,在重新启动期间,用户仍然被重定向到b2,然后你更新b2,而用户被重定向到b1

但现在,如果我只是单独更新数据库或后端,无论如何都会出现不匹配。

例如,假设我有下表:

--------
Account
--------
id: bigint
name: varchar(32)

在这里,如果我想将name重命名为firstname,我需要确保后端&数据库同时部署在生产中。

因此,我可以有一个部署脚本来关闭prod中的后端,更新数据库(即将name重命名为firstname(,用该更改更新后端并重新启动后端,棘手的部分是如何确保用户在更新过程中不会断开连接。

一些公司设法做到了这一点,所以它永远不会引人注目(谷歌(,但不确定做这件事的最佳策略是什么,也许有两个数据库可以在更新后重新同步?

无停机策略类似于

  1. 添加名为firstname的列
  2. 开始双重写入并更新name和firstname
  3. 运行一个脚本来复制name值,并为firstname没有值的每一行更新firstname(这本质上是一个回填(
  4. 现在开始读取名字而不是名字
  5. 删除名称列

根据您使用的框架,第2部分可以通过利用ORM变得更容易。对于Rails来说,提交后挂钩工作得非常好。Postgresql也将有触发器,您也可以使用。

你的另一个选择是从应用程序的可用性预算中扣除停机时间。为一个少于1000万行的表重命名一列需要几秒钟的时间(当然不到一分钟(,如果只是少数需要部署代码的实例,那么部署新应用程序也不需要很长时间。(推荐,工作量小得多(

我肯定会选择后者,除非你有更多的数据或负担不起停机时间/5xx。

最新更新