必须监控 innodb_lock_waits_total 指标(源自 performance_schema.data_lock_waits),配合 rate() 或 increase() 计算锁等待频次;MySQL 8.0+ 需启用 performance_schema 并配置 mysqld_exporter 开启 --collect.perf-schema.data-lock-waits,同时注意权限、性能开销及多维度关联分析。

生产环境 MySQL 的锁等待频率必须监控,否则事务堆积、连接打满、响应延迟会悄无声息地恶化,直到业务报障才暴露——这时往往已错过黄金处理窗口。
mysql_table_lock_waits 指标为什么不能直接用
这个指标在 mysqld_exporter 中默认不采集,因为它依赖 SHOW STATUS LIKE 'Table_locks_waited',而该状态变量在 MySQL 8.0+ 中已被弃用(仅保留兼容性输出,值恒为 0)。真实锁等待必须从 InnoDB 层抓取。
- MySQL 5.7 及更早版本:可用
mysql_global_status_table_locks_waited,但只反映表级锁,无法覆盖主流的行锁场景 - MySQL 8.0+:必须启用
performance_schema并开启events_waits_history_long或data_lock_waits表,否则mysqld_exporter根本拿不到有效数据 -
mysqld_exporterv0.12.1+ 默认只采集information_schema.INNODB_METRICS中的lock_row_lock_time_avg类指标,但它们是“平均耗时”,不是“发生频次”
真正可落地的锁等待频次指标:innodb_lock_waits_total
这是 mysqld_exporter 从 performance_schema.data_lock_waits 表中导出的计数器,单位是「自 exporter 启动以来发生的锁等待事件总数」,配合 rate() 函数就能算出每秒频率。
- 确保 MySQL 已启用:
SET GLOBAL performance_schema = ON;,且data_lock_waits表存在(MySQL 8.0.1+) - 确认
mysqld_exporter启动时加了--collect.perf-schema.data-lock-waits参数(v0.12.1 默认不启用) - PromQL 示例:
rate(mysql_perf_schema_data_lock_waits_total[5m]),表示过去 5 分钟平均每秒锁等待次数 - 注意:该指标是瞬时上升沿计数,若 exporter 重启会导致归零,需搭配
increase()+ 长时间窗口做告警(如increase(mysql_perf_schema_data_lock_waits_total[1h]) > 100)
Grafana 仪表盘里怎么避免误读
直接画 rate(mysql_perf_schema_data_lock_waits_total[5m]) 曲线容易被噪声干扰——比如某次批量更新触发几十次锁等待,曲线尖刺很高,但实际业务无感;而持续每秒 2–3 次的稳定等待,反而预示长事务或索引缺失,更危险。
- 建议叠加两个视图:①
rate(...[5m])折线图(看趋势);②histogram_quantile(0.95, sum(rate(mysql_perf_schema_data_lock_waits_total_bucket[5m])) by (le))(看 P95 延迟分布,需配合mysqld_exporter的直方图指标) - 不要只盯单个实例,用
sum by (instance) (rate(mysql_perf_schema_data_lock_waits_total[5m]))聚合所有 MySQL 实例,快速定位哪台最异常 - 关联查询
mysql_info_schema_processlist_command和mysql_info_schema_processlist_state,当锁等待突增时,自动下钻到State="Locked"或Command="Sleep"但Time > 60的可疑连接
容易被忽略的权限与性能开销
启用 data_lock_waits 采集不是零成本。它依赖 performance_schema 的活跃采样,若未合理限流,可能拖慢高并发 OLTP 场景。
- MySQL 端必须授予 exporter 用户:
SELECT权限在performance_schema.*,且需显式执行GRANT SELECT ON performance_schema.data_lock_waits TO 'exporter'@'%'; - 为降低开销,建议关闭其他冗余采集项,例如禁用
--no-collect.perf-schema.events-statements-history-long - 如果发现
mysqld_exporter抓取超时(scrape_timeout),优先调大 Prometheus 的scrape_timeout: 30s,而不是降低采集频率——锁问题本身就需要高频捕捉
真正难的不是配置这组指标,而是把「每秒 0.3 次锁等待」和「某个未提交事务卡在应用层 22 分钟」对应起来。这需要你在 Grafana 里把锁等待曲线、事务活跃时间、应用日志时间戳三者对齐,否则再准的数字也只是孤岛。


















