直接修改slave_parallel_workers需先执行stop slave再set global并start slave才生效,否则线程池不重建;必须满足binlog_format=row、binlog_transaction_dependency_tracking=writeset、表有主键或唯一键三大前提,否则自动降级单线程。

直接改 slave_parallel_workers 就生效,但必须先停复制
动态修改从库并行线程数不需要重启 MySQL 进程,但必须执行 STOP SLAVE 后再设值,否则 SET GLOBAL slave_parallel_workers = N 会静默失败(不报错,但 SHOW VARIABLES LIKE 'slave_parallel_workers' 看起来变了,实际 worker 不重建)。
这是因为 MySQL 在运行中不会销毁已分配的 SQL 线程池,只有停掉复制后重新启动,才会按新值拉起对应数量的 Slave_worker 线程。
- 正确顺序:
STOP SLAVE;→SET GLOBAL slave_parallel_workers = 8;→START SLAVE; - 改完立刻查:
SELECT * FROM performance_schema.replication_applier_status_by_worker;,确认WORKER_ID数量和状态是否匹配新值 - 如果
START SLAVE后仍只看到 1 个活跃 worker,说明不是线程数问题,而是并行前提不满足(见下一条)
slave_parallel_workers 设了却没真正并发?检查这三处硬性依赖
即使 slave_parallel_workers = 16,从库也大概率只跑 1–2 个 worker 线程——这不是参数没生效,而是 MySQL 主动降级为单线程,因为事务之间存在逻辑依赖。关键检查点:
- 主库
binlog_format必须是ROW(STATEMENT或MIXED下并行直接失效) - 主库必须启用
binlog_transaction_dependency_tracking = 'WRITESET'(默认是COMMIT_ORDER,仅靠提交时间窗口判断,并行率极低) - 所有被修改的表必须有
PRIMARY KEY或非空UNIQUE KEY(无主键/唯一键 → 写集无法生成 → 自动 fallback 到串行)
验证命令:
主库查:SELECT @@binlog_format, @@binlog_transaction_dependency_tracking;
从库查:SELECT * FROM performance_schema.replication_applier_status_by_coordinator\G,重点看 WORKERS_WAITING 是否远高于 WORKERS_PROCESSED。
为什么 slave_preserve_commit_order = ON 反而让并行“卡住”?
MySQL 8.0.27+ 默认开启 slave_preserve_commit_order = ON,它会让所有 worker 线程在提交前排队等待前序事务完成,本质上把 WRITESET 的并行执行又拉回 COMMIT_ORDER 的串行提交节奏。
- 这不是 bug,是为强一致性做的保底设计:关掉它,若主库并发更新同一行,从库可能因乱序执行导致数据不一致
- 正确做法不是关掉它,而是确保主库满足 WRITESET 三要素(
ROW+GTID+ 表有主键/唯一键),这样即使该参数为ON,worker 也能真正并行执行,只是最终提交顺序受控 - 如果发现
SHOW PROCESSLIST中大量 worker 处于Waiting for preceding transaction to commit,先别急着关参数,优先检查主库表结构和 binlog 配置
slave_parallel_workers 设多少才合理?别看 CPU 核数,看主库组提交频率
线程数不是越多越好。设太高会触发频繁线程切换和锁竞争;设太低压不住主库吞吐。关键是看主库每秒产生多少个可并行的事务组。
- 在主库执行:
SHOW GLOBAL STATUS LIKE 'Binlog_group_commit%';,观察Binlog_group_commit_trigger_count每秒增量 - 每秒平均 3–5 组 →
slave_parallel_workers = 4足够 - 每秒超 10 组 → 可设为 8 或 12;不建议超过 16(MySQL 8.0 对 >16 的调度优化有限,反而易拖慢 coordinator)
- 注意:
slave_parallel_workers是 worker 线程上限,实际并发数由主库事务组分布决定,不是“开了就满载”
真正难的不是改数字,是让主库持续产出带冲突隔离信息的事务组——这要求你对表结构、写入模式、binlog 提取方式都有控制力。否则,slave_parallel_workers 再大也只是摆设。











