Prometheus需通过mysql_exporter启用--collect.info_schema.innodb_trx才能暴露mysql_info_schema_innodb_trx_seconds指标,该指标表示事务已运行秒数;须用max()、count()等聚合查询长事务,避免仅看平均值,并配置多级告警及关联thread_id定位问题。

Prometheus 本身不直接暴露长事务时长指标,必须通过 exporter + 自定义查询组合实现,否则查不到真实运行秒数。
mysql_exporter 需启用 info_schema 指标采集
默认安装的 mysqld_exporter 不会抓取 INFORMATION_SCHEMA.INNODB_TRX 数据,必须显式开启:
启动时加参数 --collect.info_schema.innodb_trx,或在配置文件中设置 collect[] = ["info_schema_innodb_trx"]。
没开这个,Prometheus 就永远看不到 mysql_info_schema_innodb_trx_seconds 这类指标。
- 确认是否生效:访问
http://<exporter-host>:9104/metrics</exporter-host>,搜索mysql_info_schema_innodb_trx_seconds是否存在 - 该指标本质是
TIMESTAMPDIFF(SECOND, trx_started, NOW())的结果,单位为秒,已预计算好 - 若用 Docker 部署,需在
command中补全参数,单纯挂载 config 文件不够
用 PromQL 查最长/超阈值的长事务
原始指标 mysql_info_schema_innodb_trx_seconds 是按线程维度暴露的,要监控就得聚合或过滤:
- 当前最长事务:
max(mysql_info_schema_innodb_trx_seconds) - 运行超 60 秒的事务数:
count(mysql_info_schema_innodb_trx_seconds > 60) - 单个事务持续恶化趋势:
rate(mysql_info_schema_innodb_trx_seconds[5m])(慎用,意义有限) - 关联线程 ID 便于定位:指标带标签
{thread_id="12345"},可和mysql_global_status_threads_connected联查
Grafana 面板里别只看平均值
用 avg_over_time(mysql_info_schema_innodb_trx_seconds[1h]) 会掩盖问题——一个 3 小时未提交的事务,和 100 个 2 秒事务,平均才 0.1 秒。
- 真正有用的是分位数:
histogram_quantile(0.99, sum(rate(mysql_info_schema_innodb_trx_seconds_bucket[1h])) by (le)) - 或者直接画出 topK:用 Grafana 的 “Top N” 功能展示
mysql_info_schema_innodb_trx_seconds值最大的 5 个线程 - 搭配
mysql_info_schema_innodb_trx_state标签(如state="RUNNING"或state="LOCK WAIT")做条件筛选
告警规则必须设多级阈值
单一“>60s”告警容易误报,也容易漏掉缓慢爬升的事务。实际部署建议:
- 一级预警:
count(mysql_info_schema_innodb_trx_seconds > 30) > 3(短时并发长事务) - 二级严重:
max(mysql_info_schema_innodb_trx_seconds) > 300(单事务超 5 分钟) - 三级紧急:
count(mysql_info_schema_innodb_trx_seconds > 600) > 0(任何超 10 分钟的事务都得立刻介入) - 注意:告警消息里必须包含
{{ $labels.thread_id }}和{{ $value }},否则运维没法快速连上去查INFORMATION_SCHEMA.INNODB_TRX
最常被忽略的一点:即使指标采集正常,mysql_info_schema_innodb_trx_seconds 只反映“当前时刻”的运行时长,它不会记录事务从哪条 SQL 开始、有没有锁等待、是否被阻塞。真要根因分析,还得靠 SHOW ENGINE INNODB STATUS 或 performance_schema.data_locks 补充验证。


















