slave_parallel_workers设了却没效果,先确认slave_parallel_type是否为LOGICAL_CLOCK而非DATABASE;若为DATABASE且业务单库写入,则无论设多大值均仅1个线程工作,须切为LOGICAL_CLOCK并重启SQL线程才生效。

slave_parallel_workers设了却没效果?先看slave_parallel_type是不是还在DATABASE
MySQL 5.6 默认的并行模式是 DATABASE,它只按库名分组事务:不同库的事务能并发,同一库的所有事务仍串行回放。如果你业务写入集中在单个库(比如 app_db),哪怕把 slave_parallel_workers 设成 16,SQL 线程也只会用 1 个 worker 处理全部事务。
实操建议:
- 先查当前配置:
SELECT @@slave_parallel_type, @@slave_parallel_workers; - 确认是单库写入后,必须切到
LOGICAL_CLOCK模式:SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK'; - 切换后必须重启 SQL 线程才生效:
STOP SLAVE SQL_THREAD; START SLAVE SQL_THREAD; -
LOGICAL_CLOCK依赖主库的组提交信息(last_committed和sequence_number),所以主库需确保binlog_order_commits = OFF(默认值),否则人为串行化提交,MTS 就白开了
为什么Seconds_Behind_Master显示为 0,但实际延迟还在?
这个值只反映 relay log 最后一个事务的提交时间与当前系统时间差,完全不体现正在执行的长事务、大事务阻塞队列,或 IO 线程拉得慢但 SQL 线程空闲的情况。
更准的判断方式:
- 查是否卡在长事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), TRX_STARTED)) > 60; - 对比 relay log 进度和 master 日志位置:
SHOW SLAVE STATUS\G,重点比对Relay_Log_File/Relay_Log_Pos和Master_Log_File/Read_Master_Log_Pos - 如果差距稳定扩大,说明 IO 线程跟不上;如果差距不变但
Seconds_Behind_Master波动大,大概率是 SQL 线程被某个大事务(如ALTER TABLE、全表UPDATE)独占,后续事务排队
slave_parallel_workers不是越多越好,超核数反而拖慢
worker 线程数超过物理 CPU 核数(尤其未绑核时),上下文切换开销和锁竞争(比如争抢 slave_worker_info 表、relay log 文件读取)会吃掉并行收益。
合理设置原则:
- 从
slave_parallel_workers = min(4, CPU核心数 - 1)起步,留至少 1 核给 IO 线程和系统 - 观察
SHOW PROCESSLIST中以system user开头的线程数是否稳定达到设定值;若频繁出现Waiting for an event from Coordinator,说明 coordinator 分发不过来,可能是大事务太多或 relay log 切换太勤 - 绝对避免设成 0 或 1——前者禁用 MTS,后者退化为单线程
主库组提交没调好,从库MTS就是摆设
LOGICAL_CLOCK 模式下,并行粒度取决于主库能否把多个事务打包进同一个组提交(即共享相同的 last_committed)。如果主库提交太“散”,从库就只能串行回放。
关键参数要配合调整:
- 主库开启
binlog_group_commit_sync_delay = 100000(单位微秒,即 100ms),让事务稍作等待再刷盘,提高组内事务数 - 同时设
binlog_group_commit_sync_no_delay_count = 20,防止等太久,达到 20 个事务就强制提交 - 这两个值需按业务节奏调:OLTP 类短事务可压低 delay,批量导入类可适当放宽
- 注意:
binlog_order_commits = OFF必须保持,否则组提交失效
真正影响 MTS 效果的从来不只是从库参数,而是主库如何生成 last_committed —— 这一点最容易被忽略,也最难排查。











