it编程 > 数据库 > Mysql

详解Mysql并行复制的原理

10人参与 2025-10-27 Mysql

并行复制是 mysql 复制技术中一个至关重要的性能特性,它主要用于解决主从延迟(replication lag)问题。它的核心思想是:在从库上,使用多个工作线程来并发应用(apply)从主库接收到的二进制日志(binary log)事件,从而大幅提升从库的数据回放速度。

一、为什么需要并行复制?—— 问题的根源

在传统的单线程复制模式下(sql 线程为单线程),从库的 sql 线程严格按照主库二进制日志(binlog)中事件的顺序,逐一地、串行地执行 sql 事件。

这就导致了:从库的应用速度远远跟不上主库的写入速度,数据延迟(seconds behind master)会越来越大。并行复制就是为了将这个“单车道”改造成“多车道”。

二、并行复制的核心:如何判断哪些事务可以并行?

并行复制并非简单地将所有事件乱序并行执行,因为存在依赖关系的事务(例如,对同一行的修改)必须按顺序执行,否则会导致数据不一致。因此,并行复制的核心技术在于如何准确地识别出哪些事务之间没有依赖关系,可以安全地并行执行

mysql 的并行复制技术经历了多个版本的演进,其算法也在不断优化:

2.1 mysql 5.6:按数据库(schema)并行

缺点:粒度太粗。绝大多数应用通常只使用一个数据库,或者不同数据库的负载不均衡,导致无法有效并行。这对于现代微服务或多租户架构来说效果有限。

slave_parallel_workers = 4  -- 设置并行工作线程数
slave_parallel_type = database -- 并行策略为 database

2.2 mysql 5.7:logical_clock(基于组提交)

这是里程碑式的改进,极大地提升了并行复制的效率和通用性。

策略:基于主库的组提交(group commit) 信息。

工作原理

主库:事务在 prepare 阶段会进入一个队列。当某个事务要刷盘时,它会将其队列中所有已经 prepare 好的事务一起打包成一个组。

binlog:记录形式如下。last_committed 相同的事务(如 6、7、8)可以并行。

# sequence_number=6 last_committed=5 ... 
# sequence_number=7 last_committed=5 ... 
# sequence_number=8 last_committed=5 ... 
# sequence_number=9 last_committed=8 ... -- 必须等8提交后才能执行

从库:协调线程(coordinator thread)会读取这些信息,将 last_committed 相同的事务分发给不同的工作线程(worker thread)并行执行。只有 last_committed 小于当前已执行事务 sequence_number 的事务才能被分发,以保证依赖关系。

优点:并行粒度从数据库级别细化到了事务级别,只要事务在主库上是并行提交的,在从库就能并行回放,效果非常好。

配置

slave_parallel_workers = 8
slave_parallel_type = logical_clock
-- 控制组提交的积极性,值越小组提交越频繁,意味着从库并行度可能更高
binlog_group_commit_sync_delay = 100  -- 微秒级延迟,以等待更多事务成组
binlog_group_commit_sync_no_delay_count = 10 -- 达到一定数量立即成组

2.3 mysql 8.0:writeset(基于事务冲突)

在 5.7 的基础上,mysql 8.0 引入了更先进的 writeset 策略,进一步提升了并行效率。

策略:不再依赖主库的组提交时机,而是直接分析事务本身修改了哪些数据。

优点

配置

slave_parallel_workers = 16
slave_parallel_type = logical_clock -- writeset 是 logical_clock 的增强子功能

-- 在主库上开启 writeset 识别(也用于增强半同步复制)
transaction_write_set_extraction = xxhash64 -- 计算 writeset 的哈希算法
binlog_transaction_dependency_tracking = writeset -- 依赖跟踪模式:commit_order(5.7默认), writeset, writeset_session

三、并行复制的架构

在启用并行复制后,从库的 sql 线程演变为一个协调者线程(coordinator) 和多个工作线程(worker threads) 的架构:

i/o thread:保持不变,负责从主库拉取 binlog 事件并写入本地的中继日志(relay log)。

coordinator thread

worker threads:多个工作线程,真正负责执行被分配到的 relay log 中的事务。它们是并行的执行单元。

四、举例组提交和writeset提交

想象一下,主库是一个接一个地发出指令的指挥官(串行提交事务),从库是一队士兵。

4.1 组提交(logical_clock)模式的做法:

指挥官发出指令时没有特意 grouping(因为压力小,指令是串行发出的)。那么从库的士兵们就会认为:“指令1、2、3是在不同时间收到的,它们必须按顺序执行。”
所以执行顺序是:a完成 -> b开始并完成 -> c开始并完成
结果: 士兵b明明可以去独立完成任务,却被迫要等士兵a完成后才能开始。效率低下。

4.2 writeset模式的做法:

从库这边有一个超级智能的参谋长。他拿到指令清单后,会分析每条指令的具体内容

参谋长的推理:

于是,参谋长制定了这样一个并行执行计划

最终结果:

技术原理解析:last_committed的魔法

在writeset模式下,主库在写binlog时,会基于writeset历史映射表,为每个事务重新计算一个last_committed值。

从库的协调线程看到的是:

事务1: last_committed=0, sequence_number=1
事务2: last_committed=0, sequence_number=2  // 与事务1的last_committed相同!
事务3: last_committed=1, sequence_number=3  // 必须等seq_num=1的事务完成

协调规则没变:last_committed相同的事务可以并行。

到此这篇关于详解mysql并行复制的原理的文章就介绍到这了,更多相关mysql并行复制内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网! 

(0)

您想发表意见!!点此发布评论

推荐阅读

MySQL使用show processlist命令的实现

10-27

Mysql中单表和多表DQL查询语句详解

10-27

MySQL MHA 高可用集群搭建过程详解

10-27

MySQL数据库约束从入门到精通

10-27

从零搭建vsftpd服务器完整步骤:避坑指南+实战解决方案

10-27

Ubuntu24.04搭建部署OpenStack私有云的图文教程

10-25

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论