必须切换到LOGICAL_CLOCK模式才能实现真正并发,因默认DATABASE模式下即使多Schema也仅按库串行,且slave_parallel_workers仅控制线程数而不决定并行逻辑;需同时配置slave_parallel_type='LOGICAL_CLOCK'、slave_parallel_workers>0、slave_preserve_commit_order=ON及master_info_repository=TABLE等参数才生效。

不能直接配置“基于多Schema的并行复制”——MySQL 5.7 默认的 slave_parallel_type = DATABASE 就是按 Schema 分发事务,但它在单库场景下完全不并行,且无法通过调参“增强”多 Schema 并行能力;真要提升复制吞吐,必须切到 LOGICAL_CLOCK 模式。
为什么 set global slave_parallel_workers=4 对多 Schema 复制没用?
常见错误现象:SHOW SLAVE STATUS\G 中 SQL_Thread_Running: Yes 依然显示单线程状态,Seconds_Behind_Master 不降反升。
-
slave_parallel_workers只控制 worker 数量,不决定并行逻辑;它依赖slave_parallel_type的策略生效 - 默认值
DATABASE表示:每个 Schema 独占一个 SQL 线程,但一个 Schema 内所有事务仍串行执行 - 即使主库有 10 个 Schema,若从库只设
slave_parallel_workers = 4,那最多只启用 4 个 worker —— 剩余 6 个 Schema 的事务会被排队等待空闲 worker,不是并发执行 - 更关键的是:如果主库写入集中在 2 个 Schema(比如
user_db和order_db),而其他 8 个 Schema 长期空闲,那实际并行度还是 ≤2,和workers设多少无关
如何让多 Schema 场景真正并发回放?
必须切换到 LOGICAL_CLOCK 模式,它不看 Schema,只看 binlog 中的 last_committed 时间戳分组。同一组内事务可跨 Schema 并行。
- 先停 SQL 线程:
STOP SLAVE SQL_THREAD; - 改并行策略(顺序不能错):
SET GLOBAL slave_parallel_type = 'LOGICAL_CLOCK'; - 再设 worker 数(建议 4~8):
SET GLOBAL slave_parallel_workers = 4; - 强制保序(否则可能破坏事务可见性):
SET GLOBAL slave_preserve_commit_order = ON; - 重启 SQL 线程:
START SLAVE SQL_THREAD;
验证是否生效:SELECT * FROM performance_schema.replication_applier_status_by_worker; 应看到多条非空记录,且 WORKER_ID > 0;同时 SHOW SLAVE STATUS\G 中 Slave_SQL_Running_State 出现 Waiting for an event from Coordinator。
master_info_repository 和 relay_log_info_repository 必须设为 TABLE
这是容易被跳过的硬性前提。若保持默认 FILE,多个 worker 会争抢更新 master.info 和 relay-log.info 文件,引发 I/O 瓶颈甚至元数据损坏。
- 在线修改(无需重启):
SET GLOBAL master_info_repository = 'TABLE';和SET GLOBAL relay_log_info_repository = 'TABLE'; - 执行后原
.info文件会被自动删除,信息迁移到mysql.slave_master_info和mysql.slave_relay_log_info - 该设置对多源复制、GTID、并行复制三者都属于强制要求,不是可选项
主库 binlog_group_commit_sync_delay 要大于 0 才能产生组提交
LOGICAL_CLOCK 依赖主库的组提交(group commit)生成 last_committed。若主库 binlog_group_commit_sync_delay = 0(默认),事务几乎逐个刷盘,last_committed 基本全不同,从库仍退化为串行。
- 主库需设:
SET GLOBAL binlog_group_commit_sync_delay = 10000;(单位微秒,即 10ms) - 配合设:
SET GLOBAL binlog_group_commit_sync_no_delay_count = 10;(凑够 10 个事务就立即提交,避免空等) - 注意:这两个参数只影响主库 binlog 写入行为,不影响从库配置,但它们是
LOGICAL_CLOCK发挥作用的前提
真正起效的点很细:worker 数量、slave_preserve_commit_order 开关、元数据存储方式、主库组提交配置,四者缺一不可。漏掉任意一个,看起来“开了并行”,实际仍是单线程回放。











