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性能监控体系,你可以照着这个思路来排查问题:
实战:一个完整的监控脚本
最后,分享一个我常用的监控脚本。每次排查问题,我都会先跑一遍这个:
-- 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