SHOW STATUS 中真正有用的指标是 Threads_、Queries、Slow_queries、Aborted_、Bytes_received/sent 开头的几十个变量,需结合时间窗口对比变化率,并注意版本差异与计算公式。

SHOW STATUS 返回的值到底哪些有用
直接执行 SHOW STATUS 会返回几百行,但真正能反映运行状态的其实就几十个。重点盯住以 Threads_、Queries、Slow_queries、Aborted_、Bytes_received/sent 开头的指标——它们对应连接数、查询吞吐、慢查累积、异常断连和网络流量。
比如 Threads_connected 突然飙升,大概率是应用没正确复用连接;Aborted_clients 持续增长,说明客户端主动断连频繁(可能是超时或网络抖动);Slow_queries 不为零但 long_query_time 设得太高(比如 10 秒),实际慢查可能被漏掉。
实操建议:
- 用
SHOW STATUS LIKE 'Threads%'或SHOW STATUS LIKE 'Slow%'缩小范围,别扫全量 -
Queries是累计值,要看变化率:间隔 10 秒两次执行,差值除以时间才是 QPS - 注意区分
Threads_created和Threads_cached:前者高说明连接池配置不合理,后者为 0 且前者持续上升,线程创建开销已在拖慢性能
为什么 SHOW STATUS 的值有时“不动”或跳变很大
因为 SHOW STATUS 默认显示的是**自 MySQL 启动以来的累计值**,不是实时快照。如果服务跑了一年,Questions 可能是几亿,微小波动根本看不出来;而重启后所有值归零,又会突然“从零开始”。
更关键的是,某些状态变量只在特定条件下更新:比如 Handler_read_rnd_next 只在全表扫描时递增,索引扫描走 Handler_read_key;Innodb_buffer_pool_read_requests 和 Innodb_buffer_pool_reads 的比值才反映缓存命中率,单看一个没意义。
实操建议:
- 监控必须配合时间窗口对比,不能只看单次结果
- 对缓存类指标(如
Innodb_buffer_pool_hit_rate),优先用计算公式:(1 - Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests) * 100,MySQL 不直接提供这个百分比 -
Uptime必须一起查——它是计算每秒指标的分母,别忘了它本身也在增长
SHOW STATUS 和 performance_schema 能否互相替代
不能。两者定位完全不同:SHOW STATUS 是轻量级全局聚合视图,开销极低,适合快速巡检;performance_schema 是细粒度事件追踪系统,能查到某条 SQL 的锁等待链、某次磁盘 I/O 的调用栈,但默认很多消费者和仪器是关闭的,开启后有 5%~10% 性能损耗。
典型误用是:想查“哪个表被锁最多”,却只翻 SHOW STATUS,结果发现 Table_locks_waited 非零,但不知道是谁在锁、为什么锁——这必须进 performance_schema.events_waits_summary_by_instance 或 sys.innodb_lock_waits 查。
实操建议:
- 日常巡检用
SHOW STATUS,问题定位用performance_schema(先确认performance_schema已启用:SELECT @@performance_schema) - 别在生产环境长期开着所有
performance_schema仪器,按需打开,比如只开wait/lock/table/sql/handler和statement/sql/select -
SHOW STATUS查不到语句级耗时,也查不到内存分配细节,这些是硬边界
容易被忽略的兼容性坑:MySQL 5.7 vs 8.0 的 STATUS 差异
MySQL 8.0 废弃了大量旧状态变量,比如 Qcache_% 全没了(查询缓存彻底移除),Key_read_requests 这类 MyISAM 相关指标在禁用 MyISAM 引擎后恒为 0;同时新增了 Innodb_redo_log_enabled、Connection_control_failed_connections_threshold 等安全与日志相关变量。
最常踩的坑是脚本硬编码匹配 Qcache_hits,升级到 8.0 后直接查不到,导致监控告警失灵或解析报错。
实操建议:
- 检查 MySQL 版本再写监控逻辑:
SELECT VERSION() - 用
SHOW STATUS LIKE 'Innodb%'替代泛查,避免触碰已废弃字段 - 不要依赖变量名存在与否做判断,先
SELECT VARIABLE_NAME FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'xxx'确认
状态变量不是静态字典,它随版本演进悄悄变化。查之前,先确认你面对的是哪个 MySQL —— 这比记住所有变量名更重要。











