需要先纠正一个常见的认知误区:MySQL 8.0 中并不存在所谓的“并行 GTID”概念。GTID 的核心职责是为每个事务分配全局唯一的标识符,并自动记录主从同步位置;真正负责加速从库回放的另一套机制叫作“并行复制”。两者可以协同工作,但互不依赖。因此,关键任务是将 GTID 与并行复制合理搭配,使从库既能保持数据一致性,又能实现高效回放。

验证 MySQL 8.0 版本及 GTID 基础支持
GTID 自 MySQL 5.6.5 开始引入,但生产环境强烈建议使用 8.0.22 或更高版本——早期版本对 STOP REPLICA、SOURCE_AUTO_POSITION 等关键语法的支持并不完整,容易遇到兼容问题。
执行以下命令快速确认当前环境:
SELECT VERSION();SHOW VARIABLES LIKE 'gtid_mode';SHOW VARIABLES LIKE 'enforce_gtid_consistency';
必须确保 gtid_mode 为 ON、enforce_gtid_consistency 为 ON,否则后续所有配置都无法生效。如果显示 OFF 或 OFF_PERMISSIVE,说明 GTID 尚未启用——不要试图跳过这一步直接开启并行,这是不可行的。
主从两端统一配置 GTID 关键参数
主库和从库的 my.cnf 文件中 [mysqld] 段,必须同时包含以下参数,缺一不可:
server_id:每台机器唯一,不能重复(例如主库设为1,从库设为2)log_bin = mysql-bin:必须开启 binlog,GTID 依赖它来记录事务binlog_format = ROW:GTID 严格要求行格式,MIXED或STATEMENT会触发enforce_gtid_consistency直接拒绝执行gtid_mode = ON:核心开关,必须开启enforce_gtid_consistency = ON:禁止不安全的语句,例如CREATE TABLE ... SELECT、事务内建临时表等操作log_sla ve_updates = ON:从库也必须写 binlog,否则级联复制或故障切换时会中断复制链路
修改完成后重启 MySQL。注意:MySQL 8.0 不支持在线动态开启 gtid_mode,必须停机重启才能生效。
启用基于 WRITESET 的并行复制
MySQL 8.0 默认的并行策略为 DATABASE,效率较低;推荐改用 WRITESET,它能够跨不同数据库并行重放事件,前提是主库已开启 binlog_transaction_compression = ON(非强制但建议启用),且事务的写集信息被记录在 binlog 中。
在从库上执行以下命令:
STOP REPLICA;SET PERSIST parallel_applier_type = 'LOGICAL_CLOCK';SET PERSIST parallel_applier_workers = 4;SET PERSIST relay_log_recovery = ON;START REPLICA;
这里有三个关键点需要特别注意:
parallel_applier_type = 'LOGICAL_CLOCK'是 8.0 中启用 WRITESET 并行复制的前提(该功能底层由binlog_transaction_dependency_tracking控制,但用户无需直接设置它)parallel_applier_workers建议设置为 CPU 核数的 1–2 倍,过高反而会因锁争用降低吞吐量relay_log_recovery = ON必须开启,否则重启后并行线程的状态可能发生混乱- 特别注意:不要设置
sla ve_parallel_type = LOGICAL_CLOCK—— 这是 MySQL 5.7 的旧参数,8.0 已废弃,使用后会导致START REPLICA失败
启动 GTID 复制并验证并行是否生效
从库连接主库时,必须使用 SOURCE_AUTO_POSITION = 1(而非已废弃的 MASTER_AUTO_POSITION = 1):
CHANGE REPLICATION SOURCE TO SOURCE_HOST='master_ip', SOURCE_USER='repl', SOURCE_PASSWORD='xxx', SOURCE_AUTO_POSITION = 1;
启动后,建议通过以下方式验证是否真正进入并行模式:
SHOW REPLICA STATUSG中Sla ve_SQL_Running_State会显示类似worker 2 is waiting for an event from coordinator的信息,表明多线程正在工作SELECT * FROM performance_schema.replication_applier_status_by_worker;可查看各个 worker 的LAST_SEEN_TRANSACTION是否不同,且WORKER_ID > 0- 如果
Seconds_Behind_Master持续为 0,但Retrieved_Gtid_Set不等于Executed_Gtid_Set,说明并行线程卡在某个事务依赖上(常见于大事务或 DDL 操作)
最容易忽略的一点:即使开启了并行,单个大事务(例如一个 UPDATE 影响百万行)仍然会阻塞所有 worker,因为 writeset 无法拆分。此时只能通过业务层拆分事务,调高 parallel_applier_workers 也解决不了问题。
