必须先切slave_parallel_type=LOGICAL_CLOCK,否则设再多slave_parallel_workers也无效;因默认DATABASE模式仅按库分组,单库写入仍串行,需切换后重启SQL线程,并确保主库binlog_format=ROW、binlog_order_commits=OFF。

必须先切 slave_parallel_type=LOGICAL_CLOCK,否则设再多 slave_parallel_workers 也白搭。
为什么 slave_parallel_workers 设了没效果?
MySQL 5.6+ 默认是 slave_parallel_type=DATABASE,它只按库名分组事务。如果业务所有写操作都落在一个库(比如 app_db),那所有事务都会被塞进同一个 worker 线程,完全串行回放——slave_parallel_workers=16 和 =1 效果一样。
- 先确认当前模式:
SELECT @@slave_parallel_type, @@slave_parallel_workers; - 主库必须开启
binlog_order_commits=OFF(否则人为串行化提交,削弱并行潜力) - 从库执行:
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK'; - 必须重启 SQL 线程才生效:
STOP SLAVE SQL_THREAD; START SLAVE SQL_THREAD;
怎么设合理的 slave_parallel_workers 值?
不是越多越好。worker 线程数超过物理 CPU 核数,上下文切换和锁竞争(比如争抢 slave_worker_info 表、relay log 文件读取)反而拖慢整体速度。
- 建议起步值:
min(4, CPU核心数 - 1)(留至少 1 核给 IO 线程和系统) - 8 核机器可试
slave_parallel_workers = 12(1.5 倍),但不要超 32 - 观察
SHOW PROCESSLIST:system user 开头的线程数是否稳定达到设定值?若大量出现Waiting for an event from Coordinator,说明 coordinator 分发不过来,可能是大事务太多或 relay log 切得太勤
为什么 Seconds_Behind_Master 显示为 0 却还有真实延迟?
这个值只反映 relay log 最后一个事务的提交时间与当前系统时间差,不体现正在执行的长事务阻塞后续队列,也不反映 IO 线程拉取慢但 SQL 线程空闲的情况。
- 查卡住的大事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), TRX_STARTED)) > 60; - 比对日志位置:
SHOW SLAVE STATUS\G中看Relay_Log_File/Relay_Log_Pos和Master_Log_File/Read_Master_Log_Pos的差距 - ALTER TABLE、全表 UPDATE 这类事务即使启用 MTS 也会独占一个 worker,后续事务排队——这不是参数能调的,得靠
pt-heartbeat监控 + 主库限流(如max_execution_time)源头控制
LOGICAL_CLOCK 模式依赖主库 last_committed 和 sequence_number 字段,这些字段只有在主库 binlog 是 ROW 格式且 binlog_group_commit 正常工作时才可靠;如果主库用了 MIXED 或 STATEMENT 格式,或 binlog_order_commits=ON,并行效果会打折扣——这点容易被忽略。



















