slave_parallel_workers设为16仍单线程,因并行复制启动开关未打开:需同时满足slave_parallel_type=writeset、binlog_format=row、gtid_mode=on、enforce_gtid_consistency=on、log_slave_updates=on等全部前提。

不能彻底消除同步延迟,但能压到 200ms 以内——前提是所有前提条件都满足,漏一个就退回单线程。
为什么 slave_parallel_workers 设了 16 却还是单线程回放?
常见现象:执行 SHOW PROCESSLIST 只看到一个 SQL Thread,Seconds_Behind_Master 持续上涨。这不是参数没生效,而是并行复制的“启动开关”根本没打开。
-
slave_parallel_type必须是'WRITESET'或'LOGICAL_CLOCK'(MySQL 8.0.22+ 推荐WRITESET),不能是默认的'DATABASE' -
binlog_format必须为ROW(STATEMENT和MIXED不支持WRITESET) -
gtid_mode = ON且enforce_gtid_consistency = ON(WRITESET依赖 GTID 标识事务边界) -
log_slave_updates = ON(不是可选项,是强制项;否则slave_preserve_commit_order失效,WRITESET自动降级)
log_slave_updates = ON 在并行复制里到底起什么作用?
它不直接开启多线程,但它是整个 WRITESET 机制能跑起来的基础设施。
- 从库 SQL 线程执行完 relay log 后,必须把变更再写进自己的 binlog,才能构建完整的 GTID + writeset 事件链
- 没有它,
slave_preserve_commit_order = 1就无法校验跨事务的写集冲突 - 即使你设了
slave_parallel_type = 'WRITESET',MySQL 也会静默回退到LOGICAL_CLOCK,甚至最终 fallback 到单线程 - 哪怕你当前没做级联复制,也必须开——生产环境配 MTS 时把它当必填项处理
主库必须配的三个关键参数(WRITESET 模式专用)
只配从库不够,主库不配合,WRITESET 就是空转。
-
binlog_transaction_dependency_tracking = WRITESET(启用写集依赖追踪) -
transaction_write_set_extraction = XXHASH64(推荐哈希算法,比XXHASH32冲突率更低) -
binlog_transaction_dependency_history_size = 25000(控制写集历史缓存大小,太小会导致频繁清理、误判冲突) - 附带要求:
binlog_row_image = FULL(否则无法提取完整写集,UPDATE/DELETE 会退化为全表扫描)
表结构和业务代码最容易踩的坑
就算所有参数都对,这两点出问题,WRITESET 仍会失效或报错。
- 每张参与复制的表**必须有显式主键或非空唯一键**;没有的话,写集为空,事务被强制串行,还会触发
Error_code: 1032 - DDL 语句(如
ALTER TABLE)始终阻塞后续所有事务,建议用pt-online-schema-change替代 - 大事务(> 100MB binlog event 或执行时间 > 30s)会卡住整个并行队列,应拆成小批次
- 验证是否真生效:查
performance_schema.replication_applier_status_by_coordinator,看WORKERS_PROCESSED是否持续增长;若长期为 0,优先检查表主键和binlog_row_image
真正难的从来不是改几个参数,而是确认所有环节——主库 binlog 格式、GTID、写集配置;从库 log_slave_updates、类型、worker 数;再到每张表的主键、每条 DDL 的执行方式。少一环,就回到单线程原点。











