必须先执行 STOP SLAVE 才能修改 slave_parallel_workers,否则修改无效且看不到 Worker 线程;MySQL 5.6 仅支持 database 级并行,效果弱;Worker 存在但延迟不降,可能是磁盘 I/O 瓶颈或事务依赖阻塞。

slave_parallel_workers设了但show processlist看不到Worker线程
这说明并行复制根本没启动,最常见原因是没先执行 STOP SLAVE。MySQL 的 slave_parallel_workers 和 slave_parallel_type 都是只读变量,运行时直接 SET GLOBAL 会报错:ERROR 1238 (HY000): Variable 'slave_parallel_workers' is a read only variable。
- 必须严格按顺序操作:
STOP SLAVE→ 修改参数 →START SLAVE - 改完立刻执行
SHOW PROCESSLIST,过滤出Worker关键字,才能确认是否真有多个线程在跑 - 如果用的是 MySQL 5.6,
slave_parallel_type不支持logical_clock,只能设为database,且并行效果极弱——升级到 5.7+ 才能真正启用逻辑时钟分组
看到Worker线程但Seconds_Behind_Master没下降
Worker 线程起来了,不代表 SQL 回放就变快。并行复制只加速 SQL 线程阶段,IO 线程写 relay log 还是单线程,如果磁盘 I/O 已经打满,Worker 再多也得等 relay log 写完才能读。
- 检查
iostat -x 1,重点关注从库 relay log 所在磁盘的%util和await:若%util > 90%或await > 20ms,就是磁盘瓶颈 - 确认
relay_log路径没落在根分区或 tmpfs 上——容器环境尤其容易配错,比如把/var/lib/mysql映射到 host 的慢盘或空间不足目录 -
sync_relay_log = 1会强制每次写都刷盘,对机械盘是灾难;生产建议设为10000或更高(需权衡崩溃丢失风险)
Worker线程频繁报1032或卡在Waiting for dependent transaction to commit
这是典型的事务依赖阻塞,不是配置问题,而是数据层缺陷。MySQL 8.0 的 MTS(Multi-Threaded Slave)靠 logical_clock 判断事务能否并发,但前提是事务之间无锁等待、无跨表强依赖。
- 查
SHOW SLAVE STATUS\G中的Slave_SQL_Running_State:如果是Waiting for dependent transaction to commit,说明当前事务在等上游某个事务提交,整个流水线被卡死 - 主库存在无主键表?
UPDATE/DELETE在 RBR 模式下靠主键定位行,没主键就用隐式row_id,而主从row_id计数器不一致,并行时极易触发Error_code: 1032 - 从库正在跑大查询或 DDL?
MDL lock会阻塞 SQL 线程,哪怕 Worker 线程空闲也动不了——执行SELECT * FROM performance_schema.metadata_locks WHERE OBJECT_TYPE = 'TABLE'查锁源
为什么用了logical_clock还是串行回放
MySQL 的 logical_clock 并行机制依赖 binlog event 的 last_committed 和 sequence_number 字段,这两个值由主库生成。如果主库没开 binlog_order_commits=ON(默认开启),或者用的是旧版本 MySQL(last_committed 可能全为 0,所有事务被当成强依赖,被迫串行。
- 在主库查:
SHOW VARIABLES LIKE 'binlog_order_commits';,必须为ON - 主库 binlog 格式必须是
ROW,MIXED或STATEMENT下logical_clock不生效 - 主库
innodb_flush_log_at_trx_commit = 1+sync_binlog = 1组合虽安全,但会显著降低last_committed的区分度,间接削弱并行能力
真正卡住并行复制的,往往不是参数没开,而是主库生成的 binlog 天然不具备并发条件,或者从库磁盘、锁、数据结构等某一个环节拖了后腿。盯着 SHOW PROCESSLIST 和 SHOW SLAVE STATUS\G 的实时输出,比反复调参数更管用。


















