threads_running 是判断瞬时负载最可靠的指标,它反映当前正在执行sql的线程数,持续>10需警惕,>30可能已出现排队或锁等待;配合 show full processlist 可定位卡住查询,而 slow_queries 等累计值不能单独作为实时负载依据。

Threads_running 是判断瞬时负载最可靠的指标
别盯着 Threads_connected 看——它只告诉你连了多少人,不反映真实压力。Threads_running 才是当前真正正在执行 SQL 的线程数,数值持续 > 10 就得警惕,> 30 很可能已出现排队或锁等待。
- 执行
SHOW STATUS LIKE 'Threads_running';,取值是瞬时快照,不是累计值 - 配合
SHOW PROCESSLIST;查看具体哪些线程卡在State为Sending data、Copying to tmp table或Locked - 注意:如果启用了查询缓存(MySQL 5.7 及更早),
Threads_running不包含缓存命中返回的线程,但该机制在 MySQL 8.0+ 已移除
用 SHOW PROCESSLIST 快速定位“卡住”的查询
SHOW PROCESSLIST; 返回的是当前所有连接的状态快照,但默认只显示前 100 行,且截断长 SQL —— 容易漏掉真凶。
- 务必用
SHOW FULL PROCESSLIST;,避免Info字段被省略 - 重点关注
Time> 60 秒且State非Sleep的行;State为Updating或Writing to net通常意味着结果集大或网络慢 - 若看到大量
Waiting for table metadata lock,说明有 DDL 正在阻塞,不是慢查询本身的问题 - 在高并发下,这个命令本身会短暂加锁,频繁执行(如每秒一次)可能加剧负载
performance_schema.events_statements_summary_by_digest 只统计已完成语句
很多人误以为查 performance_schema.events_statements_summary_by_digest 能看到“当前正在跑的慢 SQL”,其实它只记录已执行完毕的语句摘要——正在跑的、没结束的,不会出现在这里。
- 它按 digest 分组统计,
avg_timer_wait是平均执行时间(单位秒),但前提是语句已返回 - 存储过程内未显式提交事务时,整个过程可能被合并为一条 digest,导致单次调用耗时被低估
- 启用前提:对应 instrument 必须开启,例如
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME = 'statement/sql/select'; - 真正想抓“此刻最耗时的活 SQL”,还是得靠
SHOW FULL PROCESSLIST;+Time列排序
不要指望 SHOW STATUS 提供 CPU 或内存数据
SHOW STATUS 里没有 CPU_usage、Memory_used_mb 这类字段——这不是遗漏,是设计如此。它只暴露 MySQL 内部逻辑计数器,不采集 OS 层资源。
- 查 CPU:用
top -p $(pgrep mysqld)或ps aux --sort=-%cpu | grep mysqld - 查内存:
ps aux --sort=-%mem | grep mysqld,或看Innodb_buffer_pool_pages_free和Innodb_buffer_pool_pages_total推算缓冲池使用率 - MySQL 8.0+ 可查
performance_schema.memory_summary_global_by_event_name,但需提前开启 memory instruments,且仅反映 MySQL 自己分配的内存,不含 OS 缓存 - 把
Slow_queries突增当成“现在很慢”的依据?错——它只是累计值,可能是凌晨批量 job 刚结束留下的痕迹
Threads_running 高 + SHOW FULL PROCESSLIST 里一堆长时间 State 非 Sleep 的线程 + 系统层 top 显示 mysqld CPU 持续 > 80%,这三者同时成立,才算确认真负载过高。单独看任一指标都容易误判。











