mysql 5.7+ 并行复制需 slave_parallel_type=logical_clock 配合 slave_parallel_workers 才生效;仅调大后者无效,因默认 database 级并发无法突破单库瓶颈。

为什么 slave_parallel_workers 设了却没加速?
MySQL 5.7+ 的并行回放依赖 slave_parallel_type 和 slave_parallel_workers 配合生效,光调大后者没用。默认 slave_parallel_type=DATABASE,只按库级并发,如果主库所有写都在同一个库(比如全在 app_db),那从库还是单线程回放。
- 必须设为
LOGICAL_CLOCK才能基于组提交(binlog_group_commit_sync_delay影响)实现事务级并行 -
slave_parallel_workers建议设为 CPU 核数的 1–2 倍,但超过 8 后收益常不明显,反而增加调度开销 - 确认
binlog_format=ROW,否则LOGICAL_CLOCK模式下可能退化为单线程
主库没开组提交,从库并行就等于摆设
从库并行回放依赖主库 binlog 中的 last_committed 和 sequence_number 标记,而这由主库的组提交机制生成。如果主库 binlog_group_commit_sync_delay=0(默认)且 binlog_group_commit_sync_no_delay_count=0,高并发下仍可能产生大量单事务组,导致从库无法并行。
- 适当调大
binlog_group_commit_sync_delay(如 100000,单位微秒),让多个事务攒批提交,提升组内事务数 - 注意:这会略微增加主库响应延迟,需权衡一致性敏感度
- 检查主库
SHOW MASTER STATUS输出的Executed_Gtid_Set是否连续,若跳跃严重,说明组提交未生效
Seconds_Behind_Master 为 0 却还在延迟?
这个值只反映 SQL 线程读取 relay log 的位置和当前系统时间差,不反映实际数据可见性。尤其在开启并行回放后,SQL 线程本身不执行事务,只是分发给 worker 线程——而 Seconds_Behind_Master 不统计 worker 队列积压。
- 查真实延迟用:
SELECT TIMESTAMPDIFF(SECOND, MAX(timestamp), NOW()) FROM mysql.slave_relay_log_info(需启用relay_log_info_repository=TABLE) - 更准的方式是主从同步一个带时间戳的表(如
heartbeat表定时更新),从库查该时间戳与本地 NOW() 差值 - 观察
SHOW PROCESSLIST中system user开头的Worker线程状态,若大量处于Waiting for an event from Coordinator,说明 coordinator 分发慢或 worker 阻塞
GTID 模式下跳过事务,为什么延迟反而恶化?
用 SET GTID_NEXT='xxx'; BEGIN; COMMIT; 跳过某个事务后,后续事务的 last_committed 可能被破坏,导致从库 worker 线程因依赖关系被迫串行等待。
- 跳过前先查
SELECT * FROM performance_schema.replication_applier_status_by_worker,确认哪些 worker 正在处理哪些 GTID - 优先用
STOP SLAVE; SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;(仅限非 GTID 模式);GTID 下务必用gtid_purged手动清理 + 重置从库,避免依赖链断裂 - 跳过操作后,观察
Retrieved_Gtid_Set和Executed_Gtid_Set差值是否持续扩大,若是,说明并行逻辑已紊乱
真正卡住的点往往不在参数调多大,而在主库组提交是否稳定、GTID 链是否完整、以及你怎么定义“延迟”——监控指标和业务感知之间,永远隔着一层事务可见性。










