如何连续同步/合并两个 MySQL 数据库到第三个

Posted

技术标签:

【中文标题】如何连续同步/合并两个 MySQL 数据库到第三个【英文标题】:How to continuously sync/merge two MySQL databases into a third one 【发布时间】:2015-07-03 16:47:42 【问题描述】:

我有两个 mysql(也可以是 MariaSQL)数据库。它们具有相同的结构。假设他们有两张桌子。客户和订单。

我需要不断地将这两个数据库合并/同步/复制到一个包含来自这两个数据库的数据的单个数据库中。这第三个数据库也将具有相同的结构,但某些表将具有不同的主索引。因为两个源数据库中的订单 ID 可能会发生冲突,所以我需要为订单 ID 和客户 ID 的第三个数据库创建复合索引。

我只会从第三个数据库读取数据,因此无需将更改同步回源数据库。不同的应用程序正在将数据写入这两个源数据库。此应用不受我控制,我无法更改数据或数据库结构。

我这样做的原因是我有两个数据源和一个可以访问来自这些源的数据的应用程序。而且我无法知道给定客户存储在哪个数据库中,因此如果我想避免同时搜索两者,我需要将它们全部同步到一个数据库中。

所以问题是:将这两个数据库同步为一个的最简单方法是什么?

谢谢!

【问题讨论】:

【参考方案1】:

假设Orders 具有在一台服务器上有效的customer_id 值,您必须编写代码 来确定如何处理来自另一台服务器的冲突ID。您通过请求“持续合并”使问题进一步复杂化。

我不得不说“不可能”。并在设计系统时“重新开始”。

【讨论】:

没有冲突的 customer_id 值。这些在整个系统中都是独一无二的。只有 order_id 值冲突,但 Ordes 表还有一个 customer_id 列,并且该组合是全局唯一的。不幸的是,我们的外部系统仅根据 order_id 更新源数据库中的数据,因此我认为不可能进行简单的复制。重新设计整个结构不是排序术语中的选项。我从不根据冲突的 id 进行选择,但我认为最好的选择可能是在一台服务器上的多个数据库上进行一次选择。 order_id 在每个服务器中是唯一的吗?是AUTO_INCREMENT吗?但服务器之间不是唯一的?如果 order_ids 发生变化,是否有任何外部关心 - 例如向一台服务器添加 1M? 是的,它们在每个服务器中都是唯一的,但如果它们被合并,它们可能会发生冲突。它不是自动增量。外部系统正在向每个源数据库添加和修改订单。【参考方案2】:

您正在寻找多源复制。在 MySQL 5.7 中有一个非常简单的实现:

http://dev.mysql.com/doc/refman/5.7/en/replication-multi-source.html

但是,它不会应用任何逻辑。

在 5.6 中有一个 binlog api,更多信息:http://cdn.oreillystatic.com/en/assets/1/event/61/Binary%20log%20API_%20A%20Library%20for%20Change%20Data%20Capture%20using%20MySQL%20Presentation.pdf

传统上,您会使用 mysqlbinlog 从 master 中提取数据并将其合并到客户端。这不是那么简单,因为您必须处理重启、崩溃、故障等问题。它仍然是可行的,我已经在 perl 中实现了。

【讨论】:

谢谢。这些应该有效。我喜欢多源复制的简单性,但对此有疑问。如果在源数据库中更新 ID 为 7 的订单会发生什么情况。如果复制数据库中有两个 ID 为 7 的订单,复制系统会知道要在复制数据库中更新哪一个吗?或者它会更新两者还是随机更新? 您只需在填充数据时就能弄清楚所有这些问题 :) 我不确定我是否理解正确。你是说多源复制对我来说不是一个可行的解决方案吗?我有点困惑我是否应该调查并尝试它,或者它是否不适合我想做的事情。经过更多研究,我还在考虑将两个数据库放在同一台服务器上,并同时从两个数据库中执行 SELECT,从而消除复制的需要。 我认为 OP 希望将来自两个源的行复制到一个表中,但 AUTO_INCREMENT 值会导致“重复键”问题。

以上是关于如何连续同步/合并两个 MySQL 数据库到第三个的主要内容,如果未能解决你的问题,请参考以下文章

1.合并两个数组,并保持仍然有序。2.删除合并后数组中的重复元素

如何从命令行合并两个 CSV 文件?

如何把两个完全相同的mysql数据库合并到另一个数据库中

MySQL中如何合并结构和记录数都不同的两个表?

合并两个父>子表集

如何合并两个excel中的指定数据?如何让2个excel窗口同时在前台显示?