--max-lag监控从库的Seconds_Behind_Master(或MySQL 8.0.22+的replica_lag),默认仅检查第一个从库;需配合--check-slave-lag和--recursion-method才能覆盖全部从库,否则易误判。

pt-online-schema-change 的 --max-lag 参数到底监控谁的延迟
--max-lag 不是看主库写入延迟,而是持续轮询从库的 Seconds_Behind_Master(MySQL 8.0.22+ 对应 replica_lag)。它默认只检查第一个从库——哪怕你有 5 个从库,其余 4 个延迟到 300 秒,只要第一个是 0.2 秒,工具就照常跑,完全不感知。这在多从库、读写分离或异地容灾架构下极易误判,导致主从严重脱节。
为什么加字段时主从延迟会爆表,以及怎么让 --max-lag 真正生效
加字段本身不慢,但 pt-online-schema-change 在拷贝数据 + 维护触发器期间,会产生大量写入流量(INSERT/UPDATE/DELETE 到 _new 表),这些变更全走 binlog,从库 SQL 线程单线程回放容易堆积。若不干预,Seconds_Behind_Master 可能在几分钟内冲到几十秒甚至上百秒。
要让 --max-lag 真起作用,必须配齐三个参数:
-
--max-lag=1:设阈值(单位秒),建议生产环境 ≤ 2 -
--check-slave-lag:显式启用从库延迟检查(否则默认不查) -
--recursion-method=processlist或--recursion-method=hosts:让工具自动发现所有从库,而非只盯第一个
漏掉任一参数,--max-lag 就形同虚设。MySQL 8.0.22+ 更推荐用 --max-replica-lag 替代 --max-lag,语义更准,且兼容新术语。
延迟超限时 pt-osc 实际暂停逻辑和隐藏风险
它不会立刻中断迁移,而是进入“等待窗口”:
- 每秒检查一次从库延迟
- 直到连续
--max-lag-count次(默认 3 次)都 ≤--max-lag值,才恢复同步 - 原表 DML 不受影响,但对
_new表的同步操作(即触发器执行)被暂停
这时所有变更事件会堆积在触发器里。如果等待太久(比如从库卡住没恢复),堆积量过大,会导致后续触发器执行变慢,反过来拖慢原表写入——这是最隐蔽的雪球效应。一旦触发器延迟 > 1s,业务 INSERT/UPDATE 就可能明显变慢,而你根本看不到锁表,只觉得“数据库突然变卡了”。
从库延迟为 NULL 或 0 时 --max-lag 为什么会失效
常见于以下场景:
- 从库关闭了
log_bin(LOG_BIN=OFF),Seconds_Behind_Master恒为NULL - 复制曾被手动
STOP SLAVE,又没及时START,状态长期为0或NULL - MySQL 8.0.22+ 启用了
replica_parallel_workers > 0,但replica_lag计算逻辑与旧版不同,需确认监控项是否准确
此时 --max-lag 完全无法触发暂停。务必在执行前用 SHOW SLAVE STATUS\G 或 SELECT * FROM performance_schema.replication_connection_status 确认所有从库延迟值可读且合理。不可依赖“看起来没报错”就认为保护机制生效。

















