mysql 5.7的logical_clock并行复制依靠主库组提交生成的last_committed值判断事务能否并行:同一组提交的事务具有相同last_committed值,从库据此分发给多个worker线程并发执行。

MySQL 5.7 的 LOGICAL_CLOCK 并行复制靠什么判断事务能否并行?
它依赖主库的组提交(Group Commit)机制:同一组内提交的事务,会被标记相同的 last_committed 值,从库据此分发给多个 worker 线程并行执行。但这个值只在主库并发高、事务能“凑成组”时才有效。
常见问题现象:Seconds_Behind_Master 波动大,低峰期几乎不下降;SHOW SLAVE STATUS 中 Slave_SQL_Running_State 长时间卡在 “Waiting for an event from Coordinator” —— 实际是 coordinator 等不到足够多事务组成一个组。
关键限制条件:
-
binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count需人工调优,业务流量一变就失效 - 即使两个事务毫无冲突(比如更新不同表的完全无关行),只要没进同一组,就只能串行
- 单线程写入场景(如定时任务批量更新)下,
last_committed几乎总是递增,等效于退化为单线程复制
MySQL 8.0 的 WRITESET 是怎么绕过组提交瓶颈的?
WRITESET 不再依赖主库是否“凑组”,而是直接分析事务修改的**具体行级数据**:每个事务提交前,会计算其所有变更行(基于主键或唯一键)的哈希值,存入一个集合(write_set)。这些哈希值随 binlog 一起写入,并在从库用于冲突判定。
核心逻辑是:只要两个事务的 write_set 没有交集,就认为它们无冲突,可并行回放。这使得原本被组提交割裂开的事务(例如相隔几分钟的两次单行更新),只要改的不是同一行,就能被重新调度到同一批 worker 中执行。
实际配置要点:
- 必须开启:
binlog_transaction_dependency_tracking = WRITESET - 主库需启用:
transaction_write_set_extraction = XXHASH64(默认值,不建议改) - 从库必须设为:
slave_parallel_type = LOGICAL_CLOCK(WRITESET 是 dependency tracking 模式,不是独立的 parallel_type) - 注意:
WRITESET_SESSION会强制同一线程发起的事务保持顺序,适合强一致性要求场景,但牺牲部分并行度
WRITESET 的哈希到底算什么?哪些列参与?
哈希值不是对整行内容计算,而是针对每行的**主键(PRIMARY KEY)和所有唯一键(UNIQUE KEY)字段值**分别生成。例如一张表有 id(PK)、email(UK)、sn(UK),插入一行 (100, 'a@b.com', 'SN-001'),就会产生至少 3 个哈希项:
PRIMARY?test?4t1?4\200\000\000d UNIQUE?test?4t1?4a@b.com UNIQUE?test?4t1?4SN-001
这些字符串经 XXHASH64 计算后存入事务的 write_set。所以:
- 没有主键或唯一键的表,WRITESET 无法生成有效哈希,该事务会被视为“全表冲突”,只能串行
- 大字段(如长文本、JSON)若出现在唯一键中,会显著增加哈希计算开销和内存占用
-
INSERT ... ON DUPLICATE KEY UPDATE会同时计入插入键和更新键的哈希,可能意外扩大 writeset 范围
为什么开了 WRITESET 还是没提速?几个典型盲区
WRITESET 不是银弹,以下情况会让并行效果归零或倒退:
- 从库
slave_parallel_workers设为 0 或 1,等于白配 - 主库大量使用
INSERT ... SELECT、LOAD DATA INFILE等语句,它们不走行级 writeset 跟踪,降级为 COMMIT_ORDER 模式 - 事务频繁更新热点行(如计数器字段、状态字段),导致 writeset 高频重叠,worker 线程反复等待
- 从库 I/O 或 CPU 已饱和,加 worker 只是增加锁竞争,
Performance Schema中查replication_applier_status_by_coordinator会显示大量WAITING状态 - 主库
binlog_row_image设为MINIMAL且未建唯一键,writeset 无法准确推导变更行
最易被忽略的一点:WRITESET 依赖主库准确记录依赖关系,如果主库 MySQL 版本低于 8.0.1(WRITESET 引入版本),或者从库版本低于 8.0,该策略根本不会生效——它不是向后兼容的复制协议升级,而是 binlog 事件格式层面的变更。











