MySQL实时数据库迁移/转换

3

这可能是任何团队在某个时候都会遇到的问题,因此我依靠其他人的经验。

我们正在将旧的MySQL数据库迁移到一个结构有很大改变的新数据库中。一些表被拆分成多个较小的表,一些数据从多个较小的表合并成了一个较大的表。

我们进行了一次测试,将数据库迁移到新形式需要几个小时。问题是,旧的数据库是我们的生产数据库,每分钟都在更新。我们不能有几个小时的停机时间。

您认为在这种情况下采取什么方法比较好呢?

假设您有一个名为“users”的表,其中包含1M行。它每秒钟都在发生更改。某些字段会更新,某些行会添加,某些行会删除。这就是为什么我们不能在特定时间点拍摄快照的问题,因为在迁移完成后,我们将有3个小时的未同步数据。

3个回答

1

我过去使用的一种方法是使用复制

我们在旧生产数据库和一个从库之间创建了一个复制方案,用于数据迁移。当我们开始迁移时,暂时关闭了复制,并使用从数据库作为迁移的数据源;旧生产系统仍然可用。

一旦迁移脚本完成并且我们的一致性检查运行完毕,我们重新启用了从旧生产系统到复制的从库的复制。一旦复制完成,我们在生产环境上挂起“维护中”标志,重新运行数据迁移脚本和一致性检查,将系统指向新数据库,然后撤下“维护中”标志。

虽然有一些停机时间,但只有几分钟而已。

这取决于您的数据库模式是否易于识别更改/新数据。

如果您的模式不适合轻松查询以查找新记录或更改记录,并且您不想添加新列来跟踪此信息,则最简单的解决方案是创建单独的表来跟踪迁移状态。

例如:

TABLE: USERS (your normal, replicated table)
----------------------
USER_ID
NAME
ADDRESS
.....


TABLE: USERS_STATUS (keeps track of changes, only exists on the "slave")
-----------------
USER_ID
STATUS
DATE

你可以通过在USERS表上设置插入、删除和更新的触发器来填充此表,对于每个操作,您都可以设置单独的状态。
这样可以快速找到自第一次运行迁移脚本以来发生更改的所有记录,并且只迁移这些记录。
由于您没有修改生产环境,并且触发器仅在“从属”环境上触发,因此不应在生产环境中引入任何性能或不稳定性问题。

这里的关键点是“这取决于您的数据库架构,以便轻松识别更改/新数据。”如果您在表中有几百万条记录,那么查看更改的数据需要一些时间。但这指引了我正确的方向。也许我们可以在重新启动复制后以某种方式使用从服务器中继日志文件。 - Mathew
请查看编辑 - 有一些识别更改数据的方法,但这非常依赖于原始模式 - 如果没有主键,那就变得相当棘手了... - Neville Kuyt
是的,这是一个很好的解决方案 - 至少对于我的情况是这样。即使没有主键,我们也可以添加它们,但通常都有。我也想到了类似的解决方案,但在实时数据库上操作需要谨慎。引入复制和从服务器非常棒。谢谢! - Mathew

0

我曾经使用过一种方法,这种方法对你也适用,但是你需要修改生产数据集。简单来说:

  1. 为要迁移的每个表添加一个名为“migrated”(或其他名称)的新列。将其设置为布尔类型,并默认设置为0。
  2. 当您的迁移脚本运行时,它必须将此标志设置为1,以便为已迁移到新数据库的每个条目设置。所有已经是“1”的条目都必须被忽略。这样,您就不会遇到同步问题。

这样,您可以随意运行迁移脚本。

您将有停机时间,但这只是一个最小的停机时间,因为在此期间,您只需要迁移一些数据集(实际上是迁移脚本上次运行和现在之间的最后一个“增量”)。


非常感谢您的回复。我已经考虑了相同的方法,但问题是 - 这仅适用于添加新行的表格。如果行被删除或数据集中间某处发生更改,我该如何知道呢? - Mathew
为了跟踪数据集中的更改,我通常在每个数据集中都有一个版本控制列。每次更改(UPDATE)时,该值都会递增。您可以轻松比较生产和迁移数据库之间的这些数据。对于已删除的行,恐怕您需要在停机时间内进行一些比较。基于主键,找出在生产环境中已删除的行并在迁移的数据库中将它们删除不应该花费太长时间。 - Jan Petzold

0

你能否将新数据库与当前的数据库并行运行?这样,您可以稍后将旧数据从旧数据库迁移到新数据库,并且您的“实时”情况已经在新数据库中捕获。

我的意思是:当您向旧数据库写入内容时,您还必须将数据写入新数据库。


谢谢您的建议。我们确实考虑过这个问题,但问题在于,在某些情况下,我们有数百个地方需要更改一个表格,因此以这种方式进行更改将需要太多时间,并且可能会出现错误。在更有组织的代码中,我认为这将是一个可行的解决方案。 - Mathew

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