![如何将来自两个 MySQL 源的实时数据合并到一个 MySQL 目标?](https://linux22.com/image/576423/%E5%A6%82%E4%BD%95%E5%B0%86%E6%9D%A5%E8%87%AA%E4%B8%A4%E4%B8%AA%20MySQL%20%E6%BA%90%E7%9A%84%E5%AE%9E%E6%97%B6%E6%95%B0%E6%8D%AE%E5%90%88%E5%B9%B6%E5%88%B0%E4%B8%80%E4%B8%AA%20MySQL%20%E7%9B%AE%E6%A0%87%EF%BC%9F.png)
我有两个不同的 MySQL 实例,我想将它们“从属于”第三个实例。(这样我就可以轻松地在第三个实例上进行连接)
例如。
mysql1> show databases
db1
db2
mysql2> show databases
db3
db4
mysql3> show databases
db1
db2
db3
db4
我看过 maatkit(percona 工具包)pt-table-sync 但人们说它可能会损坏数据。(它显然会删除并重新添加数据以生成插入)
pt-archiver 可以用于“快照”,但 db1 大约有 6GB,复制整个数据会比实际需要的多得多。实时更新每天只有大约 100MB。
对我来说,自然的概念是允许 mysql3 作为 mysql1 和 mysql2 的副本从属运行,但这似乎不是 MySQL 中的选项
钨复制器似乎允许这种类型的数据同步,但配置起来似乎有点笨拙,而且我担心可靠性。
有没有人用过其他方法来解决这个问题?
答案1
根据设计,一个 mysqld 进程不能同时监听两个不同的Master。
CHANGE MASTER TO 命令仅允许您设置一个 Master 作为读取源。
为了模拟这种情况,您必须通过编程在两个主控之间进行切换。您该怎么做?
我在 StackOverflow 中描述了如何将从属设备手动连接到不同的主设备,其中每个主设备是一台笔记本电脑,而从属设备是一台中央计算机。
这是基本思想
- 大师M1
- 大师 M2
- 从属 S1
像这样设置 M1 到 S1 的复制,然后设置 M2 到 S1 的复制
- 1)让 S1 运行 CHANGE MASTER TO,以 M1 为源
- 2)启动从站;
- 3)运行复制一段时间
- 4)停止从站;
- 5)让 S1 运行 CHANGE MASTER TO,以 M2 为源
- 6)启动从站;
- 7)运行复制一小会儿
- 8)停止从站;
- 9)返回步骤 1
每次从一个主服务器切换到另一个主服务器时,必须记录两个值SHOW SLAVE STATUS\G
- 中继主站日志文件
- 执行主程序日志位置
这两个值代表来自主服务器并且接下来将在从服务器上执行的最后一条 SQL 语句。
有一个主要注意事项:只要 M1 和 M2 正在更新互斥数据库,该算法就应该没问题。
信不信由你,我早在 2011 年 5 月就在 ServerFault 上回答过类似的问题。实际上,我根据《高性能 MySQL》一书解释了如何使用 BLACKHOLE 存储引擎模拟真正的多主/单从属。
答案2
没有好的现成工具可以做到这一点。pt-table-sync 并不像您所说的那样工作(我编写了它;)但它不是正确的解决方案。我见过它的双向同步功能用于在故意断开连接并更新后将服务器与中央源协调,但这不是您需要的正确解决方案。
我通常不会就此类话题进行推销,但说实话,在这种情况下,我会让 Percona 为您开发新工具。有些人已经编写了适合他们个人场景的小脚本,但目前尚不存在适合一般用途的高质量解决方案,而且也不是那么难。最重要的是您需要正式测试,而 Percona Toolkit 的组件已经满足了您的 90% 需求——它们之间只需要一点点粘合剂。当然,您可以自己做这件事,但为什么要制造一个方形轮子,最终自己维护它,并在您最不想要的时候发现它的所有错误呢?
话虽如此(结束推销,抱歉)——我建议的解决方案应该避免使用黑洞表,而采用更简单、更少麻烦的技术。(是的——我也编写了高性能 MySQL。我知道。那时我还没有看到像今天这样多的黑洞表问题。)它应该大致按照 Rolando 的建议去做,但也有一些微妙之处。例如,它不应该让 I/O 线程从主服务器传输一堆数据,远远领先于 SQL 线程,然后在循环到下一个服务器时将其全部丢弃。那将非常浪费并对主服务器造成很大影响。有很多这样的小细节需要注意——另一个想到的是在使用复制导致的临时表时不要切换主服务器。