同步任务延迟从 3 分钟涨到 3 小时,show processlist 里 12 个线程全在等,状态是 Waiting for table metadata lock。乍看像缓存或者权限的锅,追下去往往不是。

SELECT * FROM performance_schema.metadata_locks
WHERE lock_status = 'PENDING';
SELECT id, time, state FROM information_schema.processlist
WHERE command = 'Sleep' ORDER BY time DESC LIMIT 10;

追下去是这么回事:源库有人执行了一条 alter table 加索引,拿不到元数据锁就一直排队,后面所有同步查询跟着堵住。同步程序是单线程串行,一张表卡住整条链路停摆。排队越久,积压的 binlog 越多,恢复时还要再追一轮。

「同步延迟堆积」相关的日志我一般连着看前后五分钟,单看一条报错经常判断不出是哪一步失败。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。

具体做法是,先在 performance_schema.metadata_locks 里找出持锁的会话;确认 DDL 能不能挪到低峰 能挪就挪;同步任务改成按表分队列 一张表堵住不影响其他表;给同步查询设 max_execution_time 避免无限等待。

验收就看一点,延迟曲线在十分钟内回落到 5 分钟以内 队列里的积压逐步消化完。

作者 9823189