slave_parallel_workers设为大于0仅是开启多线程复制的开关,真正生效需主库binlog_format=ROW、binlog_transaction_dependency_tracking=WRITESET、表有主键或唯一键,且从库slave_preserve_commit_order配置合理。

slave_parallel_workers 设为大于 0 的值,只是打开并行复制的“开关”,不是加速器本身。真正让多个 Slave_worker 线程跑起来、并持续干活,必须主从两端同时满足一系列硬性条件,缺一不可。
主库 binlog_format 必须是 ROW
这是所有并行复制的前提。如果主库是 STATEMENT 或 MIXED,从库会直接退化为单线程回放,slave_parallel_workers 完全无效。
-
SET PERSIST binlog_format = 'ROW';(推荐,永久生效) - 验证:
SELECT @@binlog_format;必须返回ROW - 注意:改完需重启主库或确保后续事务都走新格式;已有旧格式 binlog 不会自动重写
主库必须启用 WRITESET 依赖追踪
MySQL 8.0 默认用 COMMIT_ORDER,它只按提交时间排序,对同一连接连续执行的事务完全无法并行。只有开启 WRITESET,才能基于行级写集判断事务是否真正独立。
SET PERSIST binlog_transaction_dependency_tracking = 'WRITESET';SET PERSIST transaction_write_set_extraction = 'XXHASH64';-
SET PERSIST binlog_row_image = 'FULL';(MINIMAL会导致写集提取失败) - 验证:
SELECT @@binlog_transaction_dependency_tracking, @@transaction_write_set_extraction, @@binlog_row_image;三者应分别为WRITESET、XXHASH64、FULL
从库表结构必须支持写集生成
即使主库配置全对,只要被更新的表没有主键或非空唯一键,MySQL 就无法生成可靠写集,自动 fallback 到 COMMIT_ORDER,最终仍单线程。
- 检查方式:
SELECT table_schema, table_name FROM information_schema.tables WHERE (table_schema, table_name) IN (SELECT table_schema, table_name FROM information_schema.columns WHERE column_key IN ('PRI', 'UNI') AND is_nullable = 'NO' GROUP BY table_schema, table_name) GROUP BY table_schema, table_name;—— 这只是粗筛,实际应逐个确认业务核心表 - 常见陷阱:
INSERT ... SELECT、CREATE TABLE ... AS SELECT、无主键的UPDATE,这些语句在 binlog 中会被标记为不可并行 - 修复路径:给缺失主键/唯一键的表补上;或避免在复制链路中使用这类语句
从库 slave_preserve_commit_order 默认开启,要小心它锁死并行
MySQL 8.0.27+ 默认 slave_preserve_commit_order = ON。它强制 worker 按主库顺序提交事务,哪怕逻辑上可并行,也会排队等前一个 commit 完——此时你看到多个 Slave_worker,但状态全是 Waiting for preceding transaction to commit。
- 若业务能接受轻微的提交顺序不一致(绝大多数 OLAP、报表类场景可以),建议关掉:
SET GLOBAL slave_preserve_commit_order = OFF; - 验证:
SHOW SLAVE STATUS\G中查看Slave_SQL_Running_State是否仍有大量 “Waiting for preceding transaction to commit” - 注意:关闭后,
Seconds_Behind_Master的含义会变模糊,不能简单等同于延迟毫秒数
performance_schema.replication_applier_status_by_worker 里 WORKERS_PROCESSED 应稳定增长,且多个 worker 的 LAST_SEEN_TRANSACTION 各不相同;SHOW PROCESSLIST 能看到多个 Slave_worker 处于 executing 或 Waiting for an event from Coordinator,而不是全部卡在等待 commit。这些细节比参数值本身更值得盯紧。


















