DDL执行后从库SQL线程被MDL锁阻塞,导致Seconds_Behind_Master失真飙高、Relay_Log_Space猛增;真实延迟需用pt-heartbeat或GTID差值精准测量。

DDL执行后从库SQL线程卡住,Seconds_Behind_Master飙高
这不是“同步慢”,而是从库SQL线程被阻塞在某条ALTER TABLE上,后续所有事务排队等待——SHOW SLAVE STATUS\G里Slave_SQL_Running仍为Yes,但Seconds_Behind_Master持续上涨,Relay_Log_Space猛增。根本原因是DDL在从库回放时需获取元数据锁(MDL),而此时从库可能正有长查询、备份或慢SQL持有该表的读锁。
实操建议:
- 立即查从库是否真在执行DDL:
SHOW PROCESSLIST找State为Waiting for table metadata lock或altering table的线程 - 若确认是MDL阻塞,优先杀掉持有锁的无关会话:
KILL [id](注意避开业务连接) - 禁止在从库执行任何
SELECT ... FOR UPDATE、大范围JOIN或未加索引的WHERE查询,这类语句极易长期持有MDL - 检查是否正在运行
mysqldump或xtrabackup:它们会触发FLUSH TABLES WITH READ LOCK,直接卡死SQL线程
主库刚执行完ALTER,从库延迟突增几十秒甚至分钟
这是典型“单点阻塞放大”:主库ALTER TABLE执行耗时5秒,但从库SQL线程必须串行等它完成,期间积压的上百个DML事务全被拦在后面——延迟不是5秒,而是5秒+积压事务总回放时间。
实操建议:
- 主库执行DDL前,先用
pt-online-schema-change或gh-ost替代原生命令,它们把大DDL拆成小事务,对从库压力极小 - 若必须用原生
ALTER,确保从库已开启并行复制:slave_parallel_type = LOGICAL_CLOCK+slave_parallel_workers = 4(MySQL 5.7+),可让非DDL事务绕过阻塞继续执行 - 避免在高峰期执行DDL;如需紧急上线,先在从库停掉非核心读流量(报表、统计任务),释放MDL争用资源
从库报错Error_code: 1032或1062,SQL线程停止
这已不是“卡顿”,而是同步中断。常见于RBR模式下:主库ALTER TABLE ADD COLUMN后紧接着UPDATE,若表无主键,从库回放时因隐式row_id不一致导致Can't find record(1032);或主库INSERT IGNORE与从库已有数据冲突引发Duplicate entry(1062)。
实操建议:
- 跳过错误仅作临时恢复:
STOP SLAVE; SET GLOBAL sql_slave_skip_counter = 1; START SLAVE;,但必须立刻补数据一致性校验 - 根治方法是补主键:
ALTER TABLE t ADD id BIGINT AUTO_INCREMENT PRIMARY KEY FIRST(MySQL 8.0.30+支持INVISIBLE主键,业务无感) - DDL前后避免混合写操作:比如
ALTER TABLE t ADD c1 INT后立刻UPDATE t SET c1=1,应加SLEEP(0.1)或分两个binlog event提交
如何验证DDL是否真成了瓶颈?
别只盯Seconds_Behind_Master——它在DDL执行中常显示为0或负数,完全失真。真实延迟得靠打点比对。
实操建议:
- 主库执行:
INSERT INTO heartbeat(ts, event) VALUES (UNIX_TIMESTAMP(), 'ddl_start'); - 紧接执行DDL,完成后立刻插第二条:
INSERT INTO heartbeat(ts, event) VALUES (UNIX_TIMESTAMP(), 'ddl_end'); - 从库查这两条记录的
ts值,与当前UNIX_TIMESTAMP()对比,差值才是DDL在从库的实际落地延迟 - 更准的方式是GTID比对:
SELECT @@global.gtid_executed;(主库) vsSELECT Retrieved_Gtid_Set, Executed_Gtid_Set FROM performance_schema.replication_connection_status;(从库)
DDL引发的卡顿,本质是单线程回放模型和MDL机制共同作用的结果。只要从库还在跑读请求、没关查询缓存、没调大innodb_buffer_pool_size,哪怕开了并行复制,DDL依然可能成为那个“最后一根稻草”。


















