logical_clock不分析行级修改,仅依赖组提交时间戳last_committed;writeset则基于主键或唯一索引计算每行哈希值,通过write_set交集精准判断行级冲突,实现真正细粒度并行。

MySQL 5.7 的 LOGICAL_CLOCK 为什么根本看不到索引冲突?
因为 LOGICAL_CLOCK 压根不分析事务改了哪些行,它只看主库“打包提交”的时间戳——也就是 last_committed 值。这个值由组提交(Group Commit)生成,同一刷盘批次的事务共享一个 last_committed,从库才分发给多个 worker 并行回放。
问题就在这里:两个事务哪怕修改的是 orders 和 users 完全无关的表、甚至相隔几分钟提交,只要没被主库凑进同一组,last_committed 就不同,从库就只能串行执行。它对“行级是否冲突”完全无感。
- 定时任务每秒一条
UPDATE t SET x=1 WHERE id = ?→last_committed几乎总是递增 → SQL 线程退化为单线程 - 低峰期写入稀疏 → 根本凑不成组 →
Slave_SQL_Running_State长期卡在Waiting for an event from Coordinator - 你手动调大
binlog_group_commit_sync_delay强行凑组?主库响应延迟立刻上升,不可控
MySQL 8.0 的 WRITESET 是怎么真正识别索引冲突的?
WRITESET 不依赖主库打包,而是每个事务自己算出它实际修改了哪些行的哈希值(基于主键或唯一索引),存进一个集合(write_set),随 binlog 一起传到从库。从库拿这个集合做交集判断:
事务 A:write_set = {hash('orders:1001'), hash('users:201')}
事务 B:write_set = {hash('products:99')} → 无交集 → 可并行
事务 C:write_set = {hash('orders:1001'), hash('logs:555')} → 和 A 有交集 → 必须等 A 执行完
- 即使 A 和 C 相隔 5 分钟提交,只要改的主键/唯一键不重叠,就能被调度进同一批 worker
- 冲突判断粒度是“索引键值”,不是“表名”或“提交时间”,所以能精准避开
INSERT ... ON DUPLICATE KEY UPDATE类热点冲突 - 但注意:
write_set只基于主键或唯一索引计算;如果事务修改的列没被任何唯一约束覆盖(比如只有普通索引),该行变更不会进入write_set,可能误判为无冲突
配置 WRITESET 时最容易漏掉的三个硬性条件
缺一不可,否则并行逻辑自动降级回 LOGICAL_CLOCK 或直接失效:
- 主库必须设:
binlog_transaction_dependency_tracking = WRITESET - 主库保持:
transaction_write_set_extraction = XXHASH64(默认值,别乱改成MURMUR32) - 从库必须设:
slave_parallel_type = LOGICAL_CLOCK(不是WRITESET!WRITESET是 dependency tracking 模式,不是 parallel_type)
很多人卡在第三点:看到 “WRITESET” 就下意识去设 slave_parallel_type = WRITESET,结果报错或静默无效。这是 MySQL 文档里最常被误解的配置组合。
为什么有主键还不够?唯一索引缺失仍会导致 WRITESET 失效
WRITESET 计算哈希只认主键或唯一索引。如果一张表只有普通索引(INDEX),没有 PRIMARY KEY 或 UNIQUE 约束,那么事务中所有行变更都不会生成有效哈希值,write_set 为空 → 从库认为它和任意事务都“可能冲突”,强制串行回放。
典型场景:
- 历史遗留表只有
id字段加了普通索引,但没设PRIMARY KEY或UNIQUE(id) - 业务用
INSERT IGNORE依赖唯一约束去去重,但建表时忘了加UNIQUE→WRITESET完全无法工作 - 检查方法:
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = 'db' AND TABLE_NAME = 't';确保有PRIMARY KEY或UNIQUE
真正起作用的从来不是“有没有索引”,而是“有没有能让 WRITESET 提取哈希的唯一性保证”。这点在升级前必须逐表核验,不能凭经验跳过。











