应组合使用performance_schema.data_locks高频采样与INNODB_METRICS瞬时指标,配合应用埋点和MySQL 8.0+等待事件监控,才能准确捕获每秒行锁请求峰值;单靠InnoDB_row_lock_waits等累计值无法反映突发争用。

直接看 InnoDB_row_lock_waits 和 InnoDB_row_lock_time_avg 不行
这两个状态变量只反映累计值和平均值,无法体现“每秒峰值”——你看到的是自实例启动以来的总锁等待次数和平均等待毫秒数,对突发性行锁争用毫无感知。生产环境真正要盯的是瞬时压力,比如某条 SQL 在 1 秒内触发了 800 次行锁等待,而平均下来可能才 2 次/秒,完全掩盖问题。
用 performance_schema.data_locks + 定期采样算实时锁请求数
MySQL 5.7+ 开启 performance_schema 后,data_locks 表会记录当前所有活跃行锁(包括事务 ID、锁模式、锁定的表/索引/主键值)。虽然它不直接计数“请求”,但你可以通过高频轮询(如每 100ms 查一次)并统计新增锁记录数量,逼近真实请求速率。
- 必须先启用:设置
performance_schema= ON,并确认performance_schema_data_locks_enabled= ON(5.7.30+ 默认开) - 只查行锁:过滤
LOCK_DATA IS NOT NULL AND LOCK_MODE IN ('X', 'S', 'X,GAP', 'S,GAP'),排除表锁和意向锁 - 避免全表扫:加
WHERE ENGINE = 'InnoDB',且建议限定到关键业务库表(用OBJECT_SCHEMA+OBJECT_NAME) - 采样频率别太高:低于 200ms 容易拖慢 performance_schema 本身;高于 500ms 会漏掉尖峰
information_schema.INNODB_METRICS 的 lock_row_lock_current_waits 是瞬时值但不等于请求量
这个指标反映当前正在等待行锁的线程数,是真正的瞬时快照,但它只告诉你“此刻卡住了几个”,不是“这一秒发起了多少次锁请求”。不过它可以和 lock_row_lock_waits(累计等待次数)配合使用:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 每秒执行:
SELECT COUNT(*) FROM performance_schema.events_statements_history_long WHERE EVENT_NAME LIKE '%lock%' AND TIMER_START > UNIX_TIMESTAMP(NOW(6)) * 1000000000 - 1000000000;(粗略定位锁相关语句频次) - 更准的做法:开启
events_statements_history_long并配置consumers,然后按SQL_TEXT聚合LOCK_TIME非零的语句,观察单位时间内的出现频次 - 注意:
INNODB_METRICS中的lock_row_lock_waits是累计值,需用两次查询差值除以时间间隔来估算速率,但精度受限于采集周期抖动
真正能落地的每秒行锁请求峰值监控方案
靠单个 SQL 或内置指标很难干净实现,推荐组合方式:
- 在关键业务节点(如订单创建、库存扣减)的 SQL 前后埋点,用
SELECT CONNECTION_ID()+SELECT @@innodb_row_lock_waits快照,计算该事务内是否触发新锁等待(需应用层配合) - 用 pt-stalk 或自定义脚本每 200ms 执行:
SELECT COUNT(*) FROM performance_schema.data_locks WHERE LOCK_DATA IS NOT NULL AND OBJECT_SCHEMA = 'your_db' AND OBJECT_NAME = 'your_table';,再滑动窗口求最大 delta/0.2s - 把
SHOW ENGINE INNODB STATUS\G中的ROW OPERATIONS部分(含0 queries inside InnoDB, 0 queries in queue)作为辅助参考,它虽非精确计数,但突增时往往对应锁尖峰 - 最稳的路子:升级到 MySQL 8.0.30+,启用
wait/lock/metadata/sql/mdl和wait/synch/mutex/innodb/...等 instrument,再结合events_waits_summary_global_by_event_name查wait/lock/table/sql/handler类事件的COUNT_STAR每秒变化
行锁请求峰值本质是并发写入行为的副作用,监控只是表象;真正要压住它,得看是不是用了无主键 UPDATE、非唯一索引 WHERE、或长事务没提交——这些比数字本身更值得盯。

















