繁体   English   中英

这种零停机数据库迁移计划可行吗?

[英]Is this zero-downtime database migration plan viable?

我正在考虑执行零停机时间的数据库迁移,并提出了最少的必要步骤。

“迁移”是指同一数据库中不向后兼容的任何更改,例如重命名、拆分或删除列。

由于我在其他地方找不到太多信息,因此我想与有这方面实践经验的人验证我的推理。 假设我们有能力执行滚动部署,否则我不相信零停机时间的数据库迁移是可能的。 所以:

  1. 初始状态:V1 部署在 prod 中。 它使用table1.oldColumn
  2. 目标:将table1.oldColumn重命名为table1.newColumn ,停机时间为零

脚步:

  1. 创建table1.newColumnALTER TABLE table1 ADD COLUMN newColumn(...)

  2. 逐步部署 V2。 V2 代码包含以下更改:

    • SELECT 使用 oldColumn: SELECT oldColumn FROM table1 WHERE userId = 1001 那是因为现在只有oldColumn包含完整数据,而newColumn只包含它的一个子集
    • UPDATE 使用两者,但是当 newColumn 中缺少新值时,它会从oldColumn复制。 如果我们不这样做,我们将永远追逐不断变化oldColumn
    • INSERT 使用两列: INSERT INTO table1 (oldColumn, newColumn) VALUES ('abcd', 'abcd')
    • DELETE 通常是无关紧要的,因为删除会删除整行: DELETE FROM table1 WHERE userId = 1001
      • 但是,如果列是 UNIQUE KEY,则使用 oldColumn: DELETE FROM table1 WHERE oldColumn = 'xyz'
  3. 现在所有新数据始终保持同步, oldColumnnewColumn之间仍然存在差异。 为了消除oldColumnnewColumn之间的差异,我们运行一个后台脚本,从oldColumn复制newColumn中缺少的值

  4. 现在列已同步,逐步部署 V3。 V3 代码包含以下更改:SELECT、UPDATE、INSERT 和 DELETE 现在转到newColumn table1.oldColumn不再使用

  5. 删除未使用的table1.oldColumnALTER table1 DROP COLUMN oldColumn

注意:步骤 3 和 5 可以在 V2 和 V3 启动期间作为数据库迁移的一部分执行

回顾:

  1. 最初newColumn为空,所有数据都转到oldColumn
  2. 当我们逐渐将 V1 替换为 V2 时,数据开始与oldColumn一起newColumn 此时,一些数据仍仅流入oldColumn (因为我们正在执行滚动更新,因此并非所有实例都是 V2)
  3. 一旦部署 V2,数据就会在oldColumnnewColumn中流动。 我们镜像更新和插入以保持列同步
  4. 但是,在设计oldColumn之前将一些数据插入到newColumn中,并且一些数据是从滚动更新期间存在的剩余 V1 实例中获取的。 我们必须摆脱这种差异
  5. 运行脚本时,将oldColumn中缺少的newColumn中的数据复制到那里

您对术语的使用有点令人困惑,因为您所描述的不是通常使用的术语“迁移”。 此外,不清楚您所描述的需要零停机时间的要求是什么。 停机意味着使某些东西在一段时间内不可用; 您可以在不使该表对用户不可用的情况下从表中添加/删除列,因此更改需要零停机时间 - 但显然任何引用已删除列的查询将不再有效。

如果您想在不破坏任何内容的情况下更改数据库结构,那么您需要控制访问数据库的所有内容(这不太可能),并且您可以一次性部署数据库更改以及受其影响的所有内容 - 或者您可以保护用户通过使用隐藏数据库实现并只允许用户访问视图的视图来避免更改。

如果您所做的更改非常重要以至于无法隐藏在视图定义更改中,那么您可能别无选择,只能将此更改传达给您的用户,他们都需要通过适当的 SDLC 来确定更改是否会影响他们并更新他们的代码(如果有的话)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM