直接看innodb_row_lock_waits和innodb_row_lock_time_avg即可快速判断行锁争用是否严重:前者为启动以来总等待次数,需结合qps看增长趋势;后者为平均等待时间,若持续>5ms且innodb_row_lock_current_waits长期>0,表明存在阻塞型锁竞争。

直接看 Innodb_row_lock_waits 和 Innodb_row_lock_time_avg 这两个值,就能快速判断是否存在严重行锁争用。 其他参数只是辅助定位,不是核心指标。
怎么看 Innodb_row_lock_waits 是否异常
这个值代表自 MySQL 启动以来发生的行锁等待总次数。它本身没有绝对“安全阈值”,但要结合业务节奏看:
- 如果每小时增长几百次,而系统 QPS 很低(比如
- 如果值长期为 0,不代表没锁问题——可能锁被瞬间获取、没进入等待队列;也可能当前负载极低,掩盖了潜在风险
- 重启后该值归零,所以不能只看当前值,得用监控工具(如 Prometheus + mysqld_exporter)记录趋势,观察单位时间增量
为什么 Innodb_row_lock_time_avg 比总量更重要
平均等待时间反映的是锁等待的“痛苦程度”。Innodb_row_lock_time 是累计毫秒数,容易被单次长等待拉高,而 Innodb_row_lock_time_avg 能暴露真实瓶颈:
- 若
Innodb_row_lock_time_avg> 500ms,基本可断定存在阻塞型锁竞争,用户请求已明显卡顿 - 若该值稳定在 1–2ms,即使
Innodb_row_lock_waits较高(如每秒 10+ 次),也可能是短平快的并发更新,影响有限 - 注意:这个平均值是全局统计,不区分表或语句。真要定位到具体哪条 SQL 或哪个表,必须查
information_schema.INNODB_TRX和INNODB_LOCK_WAITS
别只盯着 Innodb_row_lock_current_waits 看实时值
这个值表示“此刻正在等待锁的事务数量”,但它瞬时性太强,容易误判:
- 它可能在 0 和 3 之间跳变,看不出趋势;一次采集为 0 不代表没问题,可能刚释放完
- 它不体现等待时长——5 个事务各等 10ms,和 1 个事务等 500ms,值都是 1,但后者危害大得多
- 真正该关注的是“等待是否堆积”:持续 >0 且伴随
Innodb_row_lock_time_avg上升,才值得介入 - 如果它长期 >0,同时
INNODB_TRX中看到 trx_state = 'LOCK WAIT' 的事务长时间不结束,大概率是死锁未被自动检测,或事务卡在应用层没提交
最常被忽略的一点:这些状态变量只反映 InnoDB 行锁行为,完全不涉及 MyISAM 表锁、元数据锁(MDL)、或者外键触发的隐式锁。一旦出现阻塞但 Innodb_row_lock_* 没变化,就得立刻切去查 SHOW PROCESSLIST 和 performance_schema.metadata_locks。











