设slave_parallel_workers>0仅是开启多线程复制的开关,不是加速器;真正生效必须主库binlog_format=row、binlog_transaction_dependency_tracking=writeset、binlog_row_image=full且表有主键/唯一键,从库slave_parallel_type=logical_clock并执行stop/start slave。

设 slave_parallel_workers 大于 0 不等于并行生效——它只是开关,不是加速器。真正起效必须主从协同配置,否则从库永远单线程回放。
为什么 slave_parallel_workers 设了却没效果?
常见现象是 SHOW SLAVE STATUS\G 中 Slave_SQL_Running_State 长期卡在 Waiting for preceding transaction to commit,performance_schema.replication_applier_status_by_worker 里多数 worker 状态为 Waiting for an event from Coordinator,WORKERS_PROCESSED 几乎不增长。
根本原因不是参数没生效,而是 MySQL 主动降级回单线程:它检测到事务之间存在逻辑依赖,无法安全并行。
- 主库
binlog_format不是ROW→ 直接退化为单线程(STATEMENT或MIXED不支持WRITESET) - 主库未启用
binlog_transaction_dependency_tracking = 'WRITESET'→ 默认用COMMIT_ORDER,只看提交时间,对同一 session 连续事务完全无法并行 - 表无主键或非空唯一键 →
WRITESET无法生成写集,自动 fallback 到COMMIT_ORDER,甚至进一步退化 - 从库启用了
slave_preserve_commit_order = ON(MySQL 8.0.27+ 默认开启)→ 即使事务可并行,也强制按主库顺序提交,worker 实际串行等待
如何验证主从是否具备并行条件?
不要只查从库,主库配置才是源头。必须两端同时确认:
- 查主库:
SELECT @@binlog_transaction_dependency_tracking, @@binlog_format, @@transaction_write_set_extraction;—— 三者应分别为'WRITESET'、'ROW'、'XXHASH64' - 查主库:
SELECT @@binlog_row_image;—— 必须是'FULL'(MINIMAL会导致写集提取失败) - 查从库:
SELECT * FROM performance_schema.replication_applier_status_by_coordinator\G—— 关注WORKERS_WAITING是否远高于WORKERS_PROCESSED;若持续接近 0,说明事务分发基本没发生 - 查从库:
SHOW PROCESSLIST—— 应看到多个Slave_worker线程处于Waiting for an event from Coordinator或正在执行 SQL;若只有 1 个活跃 worker,说明并行未触发
怎样让 slave_parallel_workers 真正跑起来?
必须同步完成三端动作,缺一不可:
- 主库侧(最容易被忽略):
SET PERSIST binlog_transaction_dependency_tracking = 'WRITESET';SET PERSIST transaction_write_set_extraction = 'XXHASH64';SET PERSIST binlog_row_image = 'FULL';
确保所有被写入的表都有PRIMARY KEY或非空UNIQUE KEY - 从库侧(运行时可调):
STOP SLAVE;SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK';(8.0 默认已是,但需确认)SET GLOBAL slave_parallel_workers = 8;(勿超 16)SET GLOBAL slave_preserve_commit_order = OFF;(如业务允许乱序提交,可关掉保序)START SLAVE; - 验证组提交是否启用:主库执行
SHOW GLOBAL STATUS LIKE 'Binlog_group_commit%';,观察Binlog_group_commit_trigger_count每秒是否有稳定增量;若为 0,说明主库根本没产生可并行的事务组,worker 再多也无用
slave_parallel_workers 设多少才合理?
不是看 CPU 核数,而是看主库每秒实际产生的可并行事务组数:
- 先在主库执行
SHOW GLOBAL STATUS LIKE 'Binlog_group_commit_trigger_count';,间隔 10 秒取两次值,差值除以 10 得出平均每秒组数 - 每秒 3–5 组 →
slave_parallel_workers = 4足够 - 每秒超 10 组 → 可设为 8 或 12
- 勿设 >16:MySQL 8.0 对 >16 个 worker 的调度优化有限,反而因锁竞争拖慢整体 SQL 线程
- 动态生效必须配
STOP SLAVE; SET GLOBAL ...; START SLAVE;,只改变量不重启复制无效
最常被忽略的点是:主库没开 WRITESET,或者表缺失主键,导致从库即使开了 16 个 worker,所有事务的 last_committed 都是 0,Coordinator 只能扔给第一个 worker 执行——看起来像“并行配置生效了”,其实全是假象。











