mysql 8.0 多线程复制必须设置 replica_parallel_workers > 0 才启用,但需同时配置 replica_parallel_type = logical_clock 或 writeset、主库 binlog_format = row,并执行 stop replica; set global 相关参数; start replica 才生效,否则仍为单线程回放。

MySQL 8.0 多线程复制必须用 replica_parallel_workers
MySQL 8.0 默认启用的是单线程 SQL 线程(sql_thread),即使开了并行,也不生效——除非显式配置并启用基于 WRITESET 或 LOGICAL_CLOCK 的并行调度。关键参数是 replica_parallel_workers,它控制实际并发执行 relay log 的工作线程数。值为 0 表示禁用多线程(退化为旧版单线程模式);设为大于 0 的整数(如 4 或 8)才真正启用。
但光设这个不够:必须同时设置 replica_parallel_type = LOGICAL_CLOCK(MySQL 8.0.13+ 推荐)或 WRITESET(更严格,要求主库开启 binlog_transaction_dependency_tracking = WRITESET)。否则 replica_parallel_workers 会被忽略,状态里 Replica_SQL_Running_State 仍显示 “Waiting for master to send event”。
-
replica_parallel_type = LOGICAL_CLOCK:依赖 binlog 中的 commit order 时间戳,兼容性好,主库无需额外配置 -
replica_parallel_type = WRITESET:需主库设binlog_transaction_dependency_tracking = WRITESET,且事务间无行冲突才真正并行,吞吐更高但配置更严 - 不建议用已废弃的
DATABASE类型(只按库分发,极易串行)
从库启动前必须停掉 SQL 线程再重配
修改 replica_parallel_workers 后不能直接生效。MySQL 要求先停止复制、刷新配置、再重新启动——否则变量只在内存生效,重启后丢失,且 SQL 线程不会自动切换调度模式。
实操步骤:
- 在从库执行:
STOP REPLICA; - 设置参数:
SET GLOBAL replica_parallel_workers = 4;(或写入/etc/my.cnf的[mysqld]段持久化) - 确认类型:
SET GLOBAL replica_parallel_type = 'LOGICAL_CLOCK'; - 重启复制:
START REPLICA; - 验证:
SHOW REPLICA STATUS\G,检查Replica_IO_Running和Replica_SQL_Running均为Yes,且Replica_SQL_Running_State出现 “Worker thread … running” 字样
主库 binlog_format 必须是 ROW
多线程复制依赖事务级并行判断,而 STATEMENT 格式下,同一条 SQL 可能因函数(如 NOW()、UUID())在主从产生不同结果,无法安全并行。MySQL 8.0 的并行机制(尤其是 WRITESET)强制要求 binlog_format = ROW。
如果主库当前是 STATEMENT 或 MIXED:
- 停主库写入(或选业务低峰),执行:
SET GLOBAL binlog_format = 'ROW'; - 立即写入配置文件
/etc/my.cnf,避免重启回退:binlog_format=ROW - 注意:切换后所有新事务都以行格式记录,已有 binlog 不受影响,但后续从库只能消费 ROW 格式日志
容易被忽略的权限和状态检查点
多线程复制不是“开个开关就加速”,它对主从环境有隐含约束:
- 从库账号必须有
REPLICATION SLAVE权限——但很多人忘了它还隐含需要SELECT权限才能读取系统表(如performance_schema.replication_applier_status_by_coordinator),否则SHOW PROCESSLIST看不到 worker 线程 -
replica_parallel_workers值不能超过 CPU 核心数 × 2,否则线程争抢反而降低吞吐;建议从4开始压测,观察Seconds_Behind_Master是否持续下降 - 如果主库有大量大事务(如单个 UPDATE 影响百万行),它会阻塞整个并行队列——因为 MySQL 必须保证事务原子性,这类事务永远由 coordinator 线程串行执行











