MySQL主从复制无复制锁,但从库SQL Thread单线程回放易因大事务、DDL等引发MDL锁或行锁阻塞,导致延迟;优化需启用多线程复制、避免从库DDL、控制事务粒度并监控锁等待。

主从复制本身不加锁,但写操作和同步延迟会间接引发锁竞争
MySQL 主从复制是异步的,主库写入时不会为复制本身加锁;但从库在回放 Relay Log 时,SQL Thread 是单线程(默认)顺序执行事务,如果遇到大事务、长事务或 DDL 操作,就会卡住后续所有同步任务,造成复制延迟。此时虽然主库没被锁,但应用层读从库可能拿到过期数据,而从库自身在执行 ALTER TABLE 或 UPDATE ... WHERE 全表扫描时,会真实持有 MDL 锁或行锁,阻塞其他查询。
- 主库的
binlog写入本身受sync_binlog和innodb_flush_log_at_trx_commit控制——设为 1 时每次事务都刷盘,IO 压力上升,但不涉及“复制锁” - 从库 SQL Thread 单线程回放是性能瓶颈根源,尤其在高并发写场景下,容易堆积 relay log,表现为
Seconds_Behind_Master > 0 - 从库开启
read_only=1可防止误写,但它不阻止内部 SQL Thread 的写操作,也不影响锁行为
如何确认是不是锁导致从库变慢?看这三处指标
别猜,直接查。重点不是“有没有锁”,而是“锁是否在从库回放阶段成了瓶颈”:
- 执行
SHOW PROCESSLIST,找状态为Waiting for table metadata lock或Updating且 Command 是Query的线程,尤其是长时间运行的 - 查
SELECT * FROM information_schema.INNODB_TRX,看是否有事务持续时间远超平均值(比如 >60s),同时留意TRX_STATE = 'RUNNING'但TRX_ROWS_LOCKED很高 - 对比
SHOW SLAVE STATUS\G中的Exec_Master_Log_Pos和Read_Master_Log_Pos:如果差值稳定增长,说明 I/O Thread 正常,问题在 SQL Thread 回放慢;如果两者都停滞,可能是主库 binlog 写阻塞或网络中断
真正有效的调优动作:绕开锁瓶颈,而不是调锁参数
MySQL 复制层没有“复制锁开关”,优化方向是减少锁争用机会、加速回放、拆分压力源:
- 从库升级到 MySQL 5.7+,启用多线程复制:
slave_parallel_type=LOGICAL_CLOCK+slave_parallel_workers=4,按库或事务组并行回放(注意:需主库开启binlog_group_commit_sync_delay配合) - 避免在从库执行耗时 DDL —— 所有结构变更必须在主库完成,并评估是否可改用
pt-online-schema-change等工具降低锁持有时间 - 主库写入端控制事务粒度:单个事务不要更新 >10 万行;批量导入改用
LOAD DATA INFILE并分批次提交,减少 binlog 事件体积和从库回放压力 - 监控
innodb_row_lock_waits和innodb_row_lock_time_avg,若从库这两项明显高于主库,说明回放逻辑正在触发激烈行锁竞争(常见于无索引 WHERE 条件更新)
一个典型陷阱:以为 set global read_only=1 就安全了
read_only=1 只禁止普通用户写,但复制线程(system user)、管理员(SUPER 权限账号)仍可写。更危险的是:它不阻止从库因回放产生的锁,也不缓解 SQL Thread 单点瓶颈。很多团队开了 read_only 就放松监控,结果某天一个未加索引的 UPDATE 在从库跑满 2 小时,拖垮所有报表查询,却查不到人为写操作痕迹。
真正要盯住的,从来不是“能不能写”,而是“回放快不快”和“锁住久不久”。复制延迟不是数字,是正在发生的锁等待链。



















