【问题标题】:How to migrate database on multi-node production server?如何在多节点生产服务器上迁移数据库?
【发布时间】:2016-10-18 02:40:10
【问题描述】:

我有一个多节点生产服务器(CentOS 7.x 上的 Tomcat 8.x;每个节点都是一个单独的 CentOS 实例),它使用一个 MySQL 数据库服务器(MySQL 5.7.x)。服务器的每个节点都将手动更新:系统管理员停止每个节点并部署新版本的应用程序(.war 文件)。这意味着服务不会停机,因为每时每刻都有至少一个工作节点。

数据库迁移是使用 Liquibase 变更集实现的,这些变更集位于 .war 文件中。因此,每个节点都会验证和更新(如果需要)数据库模式。实际上,只有第一个节点执行变更集,其他节点只是验证它。

问题是每个节点的更新之间存在时间间隔:当第一个节点已经用新的应用程序版本更新时,最后一个节点仍然在以前的应用程序版本上工作(可能使用数据库中的旧列例子)。可能会导致数据库不一致。

示例

假设服务器有 3 个节点。目前,他们正在开发版本 N 的应用程序。 下一个版本需要更改数据库架构:将列 title 重命名为 title_new

为了能够在不停机的情况下更新数据库架构,我们需要使用“两步更改”:

  • 版本 N+1:
    • 新增一列title_new
    • 不再使用title 列(它被标记为已弃用);
    • title列中的所有数据复制到title_new
    • 使用列title_new
  • 版本 N+2 删除一列 title

现在管理员要部署版本 N+1。他停止第一个节点进行更新,但其他两个节点仍在处理版本 N。当第一个节点更新时,一些用户可能会使用节点 2 或 3 更改他们的数据(有一个负载均衡器,将请求路由到不同的节点)。所以我们需要一种方法来禁止用户通过节点 2 和 3 进行任何更改,同时它们没有更新为 N+1 版本。

我看到了两种不同的方法来解决这个问题:

  1. 在应用程序级别使用一些read_only 模式 - 然后应用程序逻辑禁止用户进行任何更改。但是接下来我们需要实现一些方法来使用控制台或管理面板随时启用此模式(必须允许管理员启用此模式)。
  2. 在数据库级别使用read_only 模式。但我找不到任何可供 MySQL 执行此操作的现成方法。

问题:解决上述问题的最佳方法是什么?

附:应用基于 Spring 4.x 框架 + Hibernate 4.x。

【问题讨论】:

  • 如果您选择选项 1,我会找到一种方法让部署负责在所有节点上触发只读模式,而不是让用户忘记关于它。

标签: java mysql database spring hibernate


【解决方案1】:

Zero Downtime Deployment with a Database

我发现上述文章对无需停机的数据库迁移的各种选项非常有见地。

【讨论】:

  • 我只是试图解释问题的背景,但对于任何多节点服务器来说,该问题都应该很受欢迎。因此,欢迎必须处理此类问题的人提供任何其他提示!
【解决方案2】:

解决此问题的另一种方法可能是:“使用数据库触发器”:

版本 N+1:

  • 为每个重命名的列创建一个触发器,将 title 中插入/更新的数据复制到 title_new(参见 here

版本 N+2:

  • 删除触发器,删除旧列

这种方法的优点是:

  • 完全可以用 liquibase 完成(不需要管理员额外的步骤)
  • 您的所有节点都保持完整功能(非只读)

缺点:

  • 您必须编写/使用触发器
  • 如果您的数据库更新更复杂(如列重命名 + 新数据库约束),可能会很棘手

【讨论】:

  • 非常感谢!我猜这就是我需要的。稍后将尝试使用此解决方案并将答案标记为已接受。
猜你喜欢
  • 1970-01-01
  • 2018-03-23
  • 2013-06-05
  • 2020-05-23
  • 2013-04-17
  • 2017-02-09
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多