SHOW VARIABLES LIKE 'sync_binlog';
SET GLOBAL sync_binlog = 100;
SHOW GLOBAL STATUS LIKE 'Innodb_row_lock_time';

压测时单事务持锁时间 12 毫秒,把 sync_binlog 从 0 改成 1 之后涨到 92 毫秒,同一批行的等待队列明显变长。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。

追下去是这么回事:每次提交都要等 binlog 刷到磁盘,这段时间事务还没完全结束,锁也没释放。并发写越多,刷盘排队越明显。锁的持有时间被 IO 拉长,冲突窗口跟着变大。

这次卡住的地方就在「提交刷盘持锁」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。

把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。

处理上按这个顺序:先确认延迟是不是集中在提交阶段;写入密集的库可以把 sync_binlog 设成 100 或 0 换取吞吐;主库要求强一致就保留 1 用更好的磁盘顶上去;对比调整前后 Innodb_row_lock_time 的变化。

确认没问题再收工,单事务持锁时间回到 10 毫秒级 锁等待队列变短 压测吞吐上升。

作者 9823189