探索MySQL的高效数据同步:并行复制原理
在聊 MySQL 的探索同步并行原理之前,我们要了解什么会有这个概念,高效以及这个要解决什么问题。数据这就不得不提到主从延迟这个概念了。并行
什么是复制数据库的主从延迟,如何解决?原理
数据库的主从延迟指的是主服务器(Master)和从服务器(Slave)之间数据同步的时间差或延迟。导致主从延迟的探索同步常见原因包括:

解决主从延迟可以考虑以下几个方面:
优化网络:确保主从节点之间的网络连接稳定,尽量在同一城市或同一数据中心部署,以减小网络延迟。提升从服务器性能:增加从服务器的硬件资源,亿华云计算例如增加 CPU 核数、内存容量和改善磁盘性能,以提升从服务器处理复制事件的能力。并行复制:利用 MySQL 提供的并行复制能力,同时处理多个复制事件,提高复制效率,从而降低主从延迟。这些措施可以有助于减少主从延迟,提升数据库复制的效率和稳定性。
上面提到了并行复制这个概念,接下来我们就简单聊聊并行复制。
在 MySQL 的主从复制中,我们已经介绍过其基本原理。在复制过程中,主库的 binlog 会不断地同步到从库,而从库则通过一个 SQL 线程不断地拉取并重放这些 SQL 语句。然而,当日志内容过多时,单个线程的执行会产生延迟,导致主从延迟。
为了解决这一问题,MySQL 提供了并行复制的方案。在多个版本中,MySQL 相继推出了多种并行复制的方案:
MySQL 5.6 引入了基于库级别的并行复制。WordPress模板MySQL 5.7 推出了基于组提交的并行复制。MySQL 8.0 推出了基于 WRITESET 的并行复制。库级别并行复制
在 MySQL 5.6 中,并行复制是基于 Schema(即基于库)的,可以配置多个库并行进行复制。每个库都可以有自己的复制线程,并行处理来自不同库的写入,从而提升并行复制的性能和效率。
然而,实际上大多数业务都是单库的,这使得这一方案在推出后并未获得广大开发者和 DBA 的认可,认为其实用性不足。
组提交的的并行复制
由于 MySQL 5.6 的并行复制饱受诟病,MySQL 5.7 推出了基于组提交的并行复制,这才是真正意义上的并行复制,即著名的 MTS(Enhanced Multi-Threaded Slave)。香港云服务器可参考官方文档:
https://dev.mysql.com/blog-archive/multi-threaded-replication-performance-in-mysql-5-7/
这里先简单了解下组提交,然后继续往下看。
在介绍组提交时我们提到,一个组中的多个事务在处于 Prepare 阶段之后,才会被优化成组提交。这意味着,如果多个事务能够在同一个组内提交,这些事务在锁上一定是没有冲突的。
复制binlog_transaction_dependency_tracking = WRITESET # COMMIT_ORDER transaction_write_set_extraction = XXHASH641.2.换句话说,这几个事务修改的记录一定不是同一行,因此它们之间才能互不影响地同时进入 Prepare 阶段,并进行组提交。
那么,没有冲突的多条 SQL,是不是就可以在主备同步过程中,在备库上并行执行回放呢?
答案是肯定的。因为一个组中的多条 SQL 之间互不影响,无论先执行哪一条,结果都是相同的。
因此,Slave 可以使用多个 SQL 线程来并行执行一个组提交中的多条 SQL,从而提高效率,减少主从延迟。
基于 WRITESET 的并行复制
前面的组提交大大提升了主从复制的效率,但它有一个特点,即依赖于主库的并行度。如果主库的并发度较高,才可以进行组提交,从而利用组提交的并行复制优化。
如果主库的 SQL 执行并不频繁,时间间隔可能会超过组提交的参数阈值,就不会进行组提交,这样在复制时就无法使用并行复制。
为了解决这个问题,MySQL 8.0 引入了基于 WriteSet 的并行复制。在这种情况下,即使主库是串行提交的事务,只要这些事务之间互不冲突,备库就可以并行回放,从而提升复制效率。
开启 WRITESET:
复制binlog_transaction_dependency_tracking = WRITESET # COMMIT_ORDER transaction_write_set_extraction = XXHASH641.2.实际上,WriteSet 是一个集合,使用的是 C++ STL 中的 set 容器。
复制std::set<uint64> write_set_unique;1.集合中的每一个元素都是哈希值,这个哈希值与 transaction_write_set_extraction 参数指定的算法有关(可选值为 OFF、MURMUR32、XXHASH64,默认值为 XXHASH64),其来源是行数据的主键和唯一键。
WriteSet 通过检测两个事务是否更新了相同的记录来判断事务能否并行回放,因此需要在运行时保存已提交的事务信息以记录历史事务更新了哪些行。在进行更新时,需要进行冲突检测,将新更新的记录计算出的哈希值与 WriteSet 进行比较,如果不存在冲突,则认为是不冲突的,这样就可以共用同一个 last_committed。
last_committed 指的是该事务提交时,上一个事务提交的编号。
就这样,能够确保同一个 write_set 中的变更都是不冲突的,因此可以通过多个线程并行地回放 SQL。
相关文章
电脑恢复重置教程(一步步教你如何进行电脑恢复重置,让电脑焕然一新)
摘要:在使用电脑的过程中,我们常常会遇到系统崩溃、软件冲突等问题。为了解决这些问题,电脑恢复重置成为了一个不错的选择。本教程将详细介绍如何进行电脑恢复重置的步骤,让你的电脑焕然一新。...2025-11-04
RPC框架的实现又到年初了,大家又要开始准备面试了。为了方便大家,我就写几篇面试相关的文章吧,这次是Dubbo相信很多小伙伴已经看了很多Dubbo的八股文了。比如,Dubbo支持哪些序列化框架,支持哪2025-11-04- nacos 2.2.0 是一个重要的版本,其中包括一些大的更改。删除 1.X 和命名的冗余代码和重复代码更新后 1.x 的 nacos-server 无法直接升级到 2.2.0 ,只能从 2.0.02025-11-04
 
Rust 写的 Undermoon Redis 集群 -Redis Cluster Protocol与Server Proxy
感谢 doyoubi 提供这么好的项目,原文:https://github.com/doyoubi/undermoon/blob/master/docs/redis_cluste2025-11-04iPhone5s升级iOS8.1的全面指南(了解如何为iPhone5s安装最新的iOS8.1系统)
摘要:随着技术的不断发展,iOS系统的升级已成为智能手机用户的重要事项之一。本文将为您提供一份完整的指南,教您如何将iPhone5s升级至最新的iOS8.1版本。无论您是为了体验新功能,...2025-11-04
近日 Swift 社区发布公告,为了进一步提供 Swift 和 C++ 之间的互操作性支持,他们成立了 Swift 和 C++ 互操作性工作组,以作为 Swift 项目的一部分。2025-11-04

最新评论