如何在部署期间移动表中的数据,同时最大限度地减少停机时间和功能损失?

时间:2016-02-20 18:17:37

标签: deployment architecture data-migration

在已经存在数据的项目中工作,项目需求的变化并不罕见,并迫使您更改表结构。

我的问题是在部署期间如何将数据从旧表架构移动到新表架构,同时以最小的停机时间应用迁移?停机时间是指您的应用无法访问的时间,从而导致错误。

假设您有一个负责迁移的数据库迁移任务(如果迁移失败,则还原MySQL语句)。

我不是在谈论重命名数据库列,因为在这种情况下,数据库只需重命名该列而不会丢失任何数据。

考虑这种情况:

原始表post,有200万个条目:

| name | slug | content | tags |

tagstext列,其中标记以逗号分隔。

为了使事情更清楚,您决定tags需要是一个单独的表,并创建一个postTag表,如下所示:

标记

| id | name | 

postTag

| postId | tagId | # both are foreign keys

我知道场景数据库结构从一开始就是糟糕的设计,我只是把它想象成一个虚构的场景来说明我的观点。

可能的解决方案1 ​​

可能的解决方案是,复制和重命名旧表,并通过某种钩子执行脚本来处理数据迁移吗?我认为这不会起作用,特别是如果该表中涉及外键。当然你可以暂时禁用外键检查,但听起来不像是一个可靠的解决方案。

此外,由于我们有200万个条目,脚本需要花费大量时间,这意味着我们的停机时间会延长。

可能的解决方案#2

如果我们使用完全独立的数据库怎么办?最初,我们将复制生产数据库(或者只是在可能的情况下复制它),一旦复制100%同步,禁用复制,并在第二个数据库上运行我们的迁移脚本。在部署期间更改数据库环境变量以指向我们的第二个数据库,然后删除第一个数据库。

我可以想到这种方法的一个可能问题是:这是 LIVE 网站!在数据库#2上的迁移完成之前,数据库#1上添加的新数据会发生什么?我们可能会丢失重要数据。当然,我们可以简单地询问我们的作者,不要在那时添加任何帖子,但是如果它是一个论坛用户贡献内容怎么办?我们必须关闭一些功能才能做到这一点,这意味着更多的“停机时间”。

我非常感谢有关此问题的任何见解。

P.S。:我之前做过类似的任务:它将数据从遗留应用程序移动到新应用程序。新的应用程序不是实时的,因此迁移更容易。

0 个答案:

没有答案