write_set_extraction 是 mysql 组复制中用于提取事务写集(行级唯一标识)的哈希算法,必须设为 xxhash64;因其保障跨节点 write set 字节级一致,避免哈希碰撞导致冲突漏检,且 8.0.29+ 已强制要求。

write_set_extraction 是什么,为什么必须设为 XXHASH64
MySQL 组复制(Group Replication)依赖 write_set_extraction 提取每条事务修改的行级唯一标识(即 write set),用于后续冲突检测。它不是可选优化项,而是组复制能正常工作的前提——如果设成 NONE 或 MURMUR32,节点间会因 write set 不一致而静默跳过冲突检测,导致数据不一致却无报错。
MySQL 8.0.29+ 强制要求 write_set_extraction=XXHASH64,旧版本(如 8.0.27)虽允许 MURMUR32,但实际在多主写入场景下极易漏检冲突。原因在于 MURMUR32 哈希碰撞概率高,且不保证跨平台/跨版本一致性;XXHASH64 碰撞率低两个数量级,且 MySQL 内部所有节点使用同一哈希实现,确保 write set 字节级可比。
-
SET PERSIST write_set_extraction='XXHASH64';—— 必须用PERSIST,避免重启失效 - 检查是否生效:
SELECT @@write_set_extraction;,返回值必须是XXHASH64,不是xxhash64(大小写敏感) - 若已启用组复制,修改后需
STOP GROUP_REPLICATION; START GROUP_REPLICATION;才能生效
冲突检测真正触发的三个必要条件
很多人以为只要开了组复制、写了表,冲突就会被拦住——其实不会。write set 冲突检测只在特定条件下激活,缺一不可。
- 事务必须修改**同一张表的同一行**(主键或唯一键值完全相同),UPDATE/DELETE 的 WHERE 条件匹配到的行,INSERT 的唯一键值,都算“同一行”
- 两个事务必须**同时处于未提交状态**,并在不同节点上发起(即“并发写”),单节点串行执行永远不会触发检测
- 目标列必须属于**主键或至少一个唯一索引**;普通二级索引或非索引列修改不会生成 write set 条目,也就无法参与冲突比对
典型误判:在节点 A 执行 UPDATE t SET c1='x' WHERE id=1;,节点 B 同时执行 UPDATE t SET c2='y' WHERE id=1;,如果 id 是主键,冲突会被检测并回滚后者;但如果 id 只是普通字段、表无主键,则两个事务都会成功——write set 为空,检测直接跳过。
如何验证 write set 是否真被提取和比对
不能只看 performance_schema.replication_applier_status_by_coordinator,那只是最终结果。要确认 write set 生效,得查两层日志:
- 开启
log_error_verbosity=3并重启,然后在错误日志里搜Conflict detection found conflict或Transaction was aborted,这是 write set 检测命中的直接证据 - 查
performance_schema.table_write_requests(MySQL 8.0.33+):对某张表执行写操作后,该表对应行的WRITE_SET_HASHES列应有非空值,说明 write set 已生成 - 手动构造冲突测试时,务必用
BEGIN; ... ; COMMIT;显式事务包裹,autocommit=1 的单语句事务可能因执行太快而错过并发窗口,导致“测不出冲突”
注意:SHOW ENGINE INNODB STATUS 里的 TRANSACTIONS 部分不显示 write set 内容,别白费时间翻。
常见配置陷阱与兼容性断点
看似配对的参数,组合起来反而让 write set 失效。最常踩的坑是和 binlog 格式、GTID、加密插件互相干扰。
-
binlog_format=STATEMENT会导致 write set 为空——组复制强制要求ROW,否则write_set_extraction被忽略 -
group_replication_enforce_update_everywhere_checks=OFF(默认值)时,即使开启了多主模式,冲突检测也只在“写入非本节点 primary 成员”时触发;设为ON才对所有多主写入做全量检测 - 启用
mysqlx插件或keyring_encryption时,某些 MySQL 8.0.30–8.0.32 版本存在哈希计算异常,表现是 write set 值全为0x00,需升级到 8.0.33+ 或临时禁用加密插件验证
write set 不是黑盒,它依赖 binlog event 解析、行镜像提取、哈希计算三步串联。任何一步断链,冲突检测就形同虚设——而错误日志里往往只报“transaction rollback”,不会告诉你哪步掉了链子。










