要真正启用MySQL并行回放,slave_parallel_type必须设为LOGICAL_CLOCK或DATABASE(MySQL 5.7+)或WRITESET(8.0.22+),设为NONE则即使配置worker也仅用1个线程。

slave_parallel_type 设为什么值才真正启用并行回放
MySQL 的并行复制不是设了 slave_parallel_workers 就自动生效的——必须先设对 slave_parallel_type。它只有两个合法值:DATABASE 和 LOGICAL_CLOCK(MySQL 5.7+),NONE 表示彻底禁用并行(默认值)。设成 NONE 时,哪怕开了 16 个 worker,也只会用 1 个线程干活。
常见错误现象:改完 slave_parallel_workers 后 SHOW PROCESSLIST 里还是只看到一个 SQL Thread,根本没出现 Worker thread;或者 Seconds_Behind_Master 没变化,但 Performance_schema.threads 里查不到活跃 worker。
-
slave_parallel_type = DATABASE:按库分发事务,同一库的事务串行执行;适合多库、单库写入压力不高的场景;但若所有写都集中在db1,并行度直接归零 -
slave_parallel_type = LOGICAL_CLOCK:基于组提交(group commit)信息调度,只要主库开启了binlog_group_commit_sync_delay或有并发事务提交,就能在从库拆成多个逻辑时间点并行;实际效果更稳,推荐优先选它 - MySQL 8.0.22+ 还支持
WRITESET(需同时设slave_parallel_type = WRITESET+slave_preserve_commit_order = ON),但要注意:它依赖主库的binlog_transaction_dependency_tracking配置,且对无主键/无唯一键的表会退化为LOGICAL_CLOCK
为什么设了 LOGICAL_CLOCK 还是单线程回放
看起来配对了,但 SHOW SLAVE STATUS\G 里 Slave_SQL_Running_State 仍显示 Reading event from the relay log,没有 Worker thread 参与——大概率是主库没产生可并行的 binlog 组。
根本原因:MySQL 从库的 LOGICAL_CLOCK 并行依赖主库的 group commit。如果主库是单线程写、或 innodb_flush_log_at_trx_commit = 1 + sync_binlog = 1 且事务非常轻量,就很难形成多事务同时处于 prepare → commit 的窗口,binlog 里也就没有足够多的 last_committed / sequence_number 差异。
- 检查主库是否真有组提交:执行
SHOW BINLOG EVENTS IN 'mysql-bin.000001' LIMIT 20,看last_committed字段是否有重复值(比如连续几行都是 123,下一行变成 124) - 从库上确认是否识别到逻辑时钟:在从库执行
SELECT * FROM performance_schema.replication_applier_status_by_coordinator\G,THREAD_ID不为空说明 coordinator 已启动;再查replication_applier_status_by_worker,看WORKER_ID对应的线程是否在STATE = 'Executing' - 如果主库是低负载测试环境,可以人工制造并发:用多个连接同时执行
INSERT INTO t VALUES (1); COMMIT;,比单连接循环快得多
slave_parallel_workers 设多少才合理
这个值不是越大越好,也不是核数多少就设多少。它代表从库 SQL 层最多启用几个 worker 线程,但每个 worker 仍要争抢 relay log 文件读取、event 解析、InnoDB 行锁等资源。
典型误判:看到机器是 32 核,直接设 slave_parallel_workers = 32,结果 CPU 跑满、磁盘 IO 崩溃,Seconds_Behind_Master 反而拉大。
- 生产环境建议从
4或8起步,观察SHOW SLAVE STATUS中Seconds_Behind_Master是否下降,以及SHOW GLOBAL STATUS LIKE 'Threads_connected'是否异常升高 - 如果主库写入集中在 1–2 个库,
slave_parallel_type = DATABASE下设超过库数量的 worker 是浪费;此时不如切到LOGICAL_CLOCK再调 worker 数 - 注意
slave_parallel_workers > 0会强制开启slave_preserve_commit_order = ON(MySQL 5.7.22+),这会让从库 commit 阶段变慢一点,但能保证事务顺序一致性——别手动关它
WRITESET 模式下容易被忽略的约束条件
想用 WRITESET 获得最高并行度?它确实能按行粒度拆分事务,但前提是主库和从库都满足一连串隐性要求,漏掉任意一条就会静默降级为 LOGICAL_CLOCK。
最常踩的坑是:以为只要从库设了 slave_parallel_type = WRITESET 就行,结果 performance_schema.replication_applier_status_by_worker 里 LAST_ERROR_MESSAGE 显示空,但并行度就是上不去。
- 主库必须设
binlog_transaction_dependency_tracking = WRITESET(默认是COMMIT_ORDER);且binlog_format = ROW(STATEMENT 或 MIXED 不支持) - 主库表必须有显式主键或非空唯一键;否则事务无法生成 writeset hash,降级处理
- 从库必须设
slave_preserve_commit_order = ON(WRITESET 模式强制要求);否则启动复制时报错 - DDL 语句(如
ALTER TABLE)永远不能并行,会阻塞所有 worker,直到它执行完
WRITESET 的真实价值在高并发、多表、小事务场景;如果主库单事务更新几百行,writeset 计算开销反而可能拖慢整体速度。上线前务必用真实 binlog 流压测验证。










