32、MySQL性能监控:SHOW STATUS、SHOW PROCESSLIST、information_schema查询、性能模式

做数据库开发这些年,我踩过最大的坑,就是上线前没做性能监控。你想想看,一个查询在测试环境跑得飞快,一上生产就慢得像蜗牛。为什么?因为数据量不一样,并发不一样,索引使用情况也不一样。

所以今天咱们聊聊MySQL性能监控的四个核心手段。说白了,就是给数据库装个仪表盘,随时知道它跑得怎么样。

SHOW STATUS:数据库的体检报告

我个人习惯,连上MySQL第一件事就是跑SHOW STATUS。这命令就像体检报告,告诉你数据库当前的各种指标。

-- 查看所有状态变量
SHOW STATUS;

-- 查看特定指标
SHOW STATUS LIKE 'Threads%';
SHOW STATUS LIKE 'Connections%';
SHOW STATUS LIKE 'Innodb_%';

常用的几个关键指标:

状态变量 含义 关注点
Threads_connected 当前连接数 超过max_connections的80%要警惕
Threads_running 正在执行的线程数 持续偏高说明有慢查询
Questions 累计查询次数 监控QPS变化趋势
Innodb_rows_read InnoDB读取行数 突然暴增说明索引失效
Slow_queries 慢查询次数 超过0就说明有问题
我的小技巧:SHOW GLOBAL STATUS看全局累计值,用SHOW SESSION STATUS看当前会话。我一般写个脚本每5秒采集一次,记录到日志里,方便事后分析。

SHOW PROCESSLIST:抓住正在捣乱的查询

数据库突然变慢怎么办?别慌,先看看谁在搞事情。SHOW PROCESSLIST就是抓现行用的。

-- 查看所有连接
SHOW FULL PROCESSLIST;

-- 常见状态说明
-- Sleep: 空闲连接
-- Query: 正在执行查询
-- Locked: 被锁住了
-- Sending data: 正在传输数据(可能很慢)

我曾经遇到一个线上事故,数据库CPU飙到100%。一查PROCESSLIST,发现有个查询跑了20分钟还没结束。嗯,就是它了。

-- 杀掉问题连接(慎用!)
KILL 12345;  -- 12345是线程ID
警告:KILL操作要谨慎。我曾经在生产环境误杀了一个重要事务,导致数据回滚,被DBA骂了一下午。建议先确认这个连接在做什么,再决定是否杀掉。

information_schema:数据库的元数据宝库

information_schema是MySQL自带的元数据库,里面存着所有数据库、表、列、索引的信息。说白了,就是数据库的「户口本」。

-- 查看所有表的大小
SELECT 
    table_schema AS '数据库',
    table_name AS '表名',
    round(((data_length + index_length) / 1024 / 1024), 2) AS '大小(MB)'
FROM information_schema.tables
ORDER BY (data_length + index_length) DESC;

-- 查看索引使用情况
SELECT 
    table_schema,
    table_name,
    index_name,
    cardinality,
    seq_in_index
FROM information_schema.statistics
WHERE table_schema = 'your_database';

我最常用的是查表大小。有一次客户说数据库空间不够了,我一查发现有个日志表占了50GB,里面全是半年前的数据。直接清掉,空间立马释放。

-- 查看哪些表没有主键(性能杀手)
SELECT 
    table_schema,
    table_name
FROM information_schema.tables
WHERE table_schema NOT IN ('mysql', 'information_schema', 'performance_schema')
  AND table_type = 'BASE TABLE'
  AND table_name NOT IN (
      SELECT table_name 
      FROM information_schema.table_constraints 
      WHERE constraint_type = 'PRIMARY KEY'
  );

性能模式(Performance Schema):深度诊断利器

性能模式是MySQL 5.5以后引入的,说白了就是数据库内部的「黑匣子」。它能记录每个SQL的执行时间、锁等待、IO操作等详细信息。

-- 检查性能模式是否开启
SHOW VARIABLES LIKE 'performance_schema';

-- 查看等待事件统计
SELECT * 
FROM performance_schema.events_waits_summary_global_by_event_name
WHERE COUNT_STAR > 0
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;

-- 查看最慢的SQL(需要先开启statement记录)
SELECT 
    digest_text,
    count_star,
    avg_timer_wait / 1000000000 AS avg_ms,
    sum_timer_wait / 1000000000 AS total_ms
FROM performance_schema.events_statements_summary_by_digest
ORDER BY sum_timer_wait DESC
LIMIT 10;
核心思路:性能模式虽然强大,但开启后会消耗5%-10%的性能。我建议只在排查问题时临时开启,平时关掉。用UPDATE performance_schema.setup_consumers SET ENABLED = 'YES'来按需开启。

知识体系总览

下面这张图是我自己总结的MySQL性能监控体系,你可以照着这个思路来排查问题:

MySQL性能监控体系 SHOW STATUS 全局状态变量 连接数、QPS 线程状态 InnoDB指标 SHOW PROCESSLIST 当前连接列表 查询状态 锁等待 KILL操作 information_schema 元数据查询 表大小统计 索引分析 无主键检测 性能模式 事件统计 SQL分析 锁等待 IO监控 排查流程 1. SHOW STATUS → 发现异常指标 2. SHOW PROCESSLIST → 定位问题连接 3. information_schema → 分析表/索引 4. Performance Schema → 深度诊断

实战:一个完整的监控脚本

最后,分享一个我常用的监控脚本。每次排查问题,我都会先跑一遍这个:

-- 1. 看整体状态
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Threads_running';
SHOW GLOBAL STATUS LIKE 'Slow_queries';

-- 2. 看当前连接
SHOW FULL PROCESSLIST;

-- 3. 看表大小
SELECT table_schema, table_name, 
       round(((data_length + index_length) / 1024 / 1024), 2) AS size_mb
FROM information_schema.tables
ORDER BY size_mb DESC
LIMIT 10;

-- 4. 看慢查询(如果开启了慢查询日志)
SHOW VARIABLES LIKE 'slow_query_log';
SHOW VARIABLES LIKE 'long_query_time';
避坑指南:我曾经在生产环境直接跑SHOW FULL PROCESSLIST,结果因为连接太多,把数据库搞挂了。后来我改成用SELECT * FROM information_schema.processlist,这个查询更轻量,不会锁住系统表。

好了,这四种监控手段你掌握了吗?下次数据库出问题,别急着重启,先按这个流程查一遍。很多时候,问题就出在某个慢查询或者锁等待上。


公众号:蓝海资料掘金营,微信deep3321