如何查询MySQL的CPU使用率突然变高

一、紧急定位:找出消耗CPU的MySQL线程

首先要快速找到是哪些SQL或连接在消耗CPU,这一步能帮你快速锁定问题。

1. 登录MySQL,查看当前运行的线程
sql 复制代码
-- 查看所有活跃线程,按CPU使用时间排序(最耗CPU的排在前面)
SHOW FULL PROCESSLIST;

-- 更详细的查询(推荐),包含执行时间、锁等待等关键信息
SELECT 
    id,
    user,
    host,
    db,
    command,
    time,
    state,
    LEFT(info, 500) AS sql_text, -- 显示SQL语句前500个字符
    EXECUTION_TIME,
    LOCK_TIME
FROM INFORMATION_SCHEMA.PROCESSLIST 
WHERE command != 'Sleep' -- 排除休眠连接
  AND info IS NOT NULL   -- 排除无SQL的线程
ORDER BY time DESC;      -- 按执行时间降序

关键字段解读

  • time:SQL执行的秒数(长时间运行的SQL优先排查)
  • state:线程状态(如Sending dataSorting resultUpdating等,代表SQL执行阶段)
  • sql_text:具体执行的SQL语句(核心排查对象)
2. 查看MySQL全局状态和CPU相关指标
sql 复制代码
-- 查看MySQL自启动以来的统计信息(重点关注CPU相关)
SHOW GLOBAL STATUS LIKE '%CPU%';
SHOW GLOBAL STATUS LIKE 'Threads%'; -- 线程数(过多会导致CPU高)
SHOW GLOBAL STATUS LIKE 'Queries';  -- 总查询数
SHOW GLOBAL STATUS LIKE 'Slow_queries'; -- 慢查询数
3. 临时处理:终止耗CPU的线程(紧急情况)

如果发现某个SQL长时间运行且消耗大量CPU,可临时终止:

sql 复制代码
-- 替换为实际的线程ID(从PROCESSLIST中获取)
KILL [线程ID];

二、深入分析:找出CPU高的根本原因

定位到耗CPU的SQL后,需要分析为什么这些SQL会消耗大量CPU,常见原因包括:索引缺失、SQL写法差、配置不合理、锁竞争等。

1. 检查慢查询日志(最核心的排查手段)

慢查询日志会记录执行时间超过long_query_time的SQL,是排查CPU高的核心工具。

(1)开启慢查询日志(临时生效,无需重启)
sql 复制代码
-- 设置慢查询阈值(如1秒,执行超过1秒的SQL会被记录)
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
-- 记录未使用索引的SQL(即使执行时间短,无索引也可能导致CPU高)
SET GLOBAL log_queries_not_using_indexes = ON;
-- 查看慢查询日志路径
SHOW VARIABLES LIKE 'slow_query_log_file';
(2)分析慢查询日志

使用mysqldumpslow工具(MySQL自带)分析慢查询日志:

bash 复制代码
# 查看慢查询日志路径
mysql -uroot -p -e "SHOW VARIABLES LIKE 'slow_query_log_file'"

# 分析慢查询日志(替换为实际路径)
mysqldumpslow -s t -t 10 /var/lib/mysql/xxx-slow.log

参数说明:

  • -s t:按执行时间排序
  • -t 10:显示前10条最慢的SQL
  • -s c:按执行次数排序(高频低耗的SQL也可能导致CPU高)
2. 分析耗CPU SQL的执行计划

对找到的耗CPU SQL,使用EXPLAIN分析执行计划,看是否使用了索引、是否全表扫描:

sql 复制代码
-- 替换为实际的耗CPU SQL
EXPLAIN SELECT * FROM table_name WHERE condition;

-- 更详细的执行计划(包含执行成本)
EXPLAIN ANALYZE SELECT * FROM table_name WHERE condition;

重点关注

  • type列:如果是ALL(全表扫描),说明未使用索引,是CPU高的常见原因
  • key列:显示使用的索引,如果为NULL,说明未使用索引
  • rows列:预估扫描的行数,行数越多,CPU消耗越大
3. 检查MySQL配置是否合理

不合理的配置也会导致CPU高,重点检查以下参数:

sql 复制代码
SHOW VARIABLES LIKE 'innodb_buffer_pool_size'; -- 缓冲池大小(过小会导致磁盘IO高,间接引发CPU高)
SHOW VARIABLES LIKE 'max_connections';         -- 最大连接数(过多会导致线程切换消耗CPU)
SHOW VARIABLES LIKE 'query_cache%';            -- 查询缓存(MySQL8.0已移除,开启后可能导致CPU高)
SHOW VARIABLES LIKE 'sort_buffer_size';        -- 排序缓冲区(过大导致内存不足,频繁换页)
SHOW VARIABLES LIKE 'join_buffer_size';        -- 连接缓冲区(同上)
4. 检查系统层面的资源竞争
  • CPU上下文切换 :MySQL线程过多会导致CPU频繁切换上下文,消耗CPU

    bash 复制代码
    # 查看上下文切换次数(数值过高说明有问题)
    vmstat 1
    # 查看MySQL进程的线程数
    pstree -p 1972827 | wc -l
  • 磁盘IO :磁盘IO高会导致MySQL等待,间接拉高CPU(如swap使用、磁盘满)

    bash 复制代码
    # 查看磁盘IO
    iostat -x 1
    # 查看swap使用情况
    free -h

三、常见原因及解决方案

常见原因 解决方案
无索引/索引失效 为查询字段添加合适的索引;检查索引是否因数据类型不匹配、函数操作失效
SQL写法差(如SELECT *) 优化SQL,只查询需要的字段;避免子查询、笛卡尔积;使用JOIN代替子查询
高频小查询 优化SQL执行次数;增加缓存(如Redis);使用批量操作
连接数过多 调整max_connections;排查应用侧是否有连接泄漏;使用连接池
配置不合理 调整innodb_buffer_pool_size(建议为物理内存的50%-70%);关闭查询缓存
锁竞争(行锁/表锁) 优化事务,缩短锁持有时间;避免长事务;使用行锁而非表锁
MySQL版本问题 升级到稳定版本(如5.7/8.0的最新小版本),修复已知的CPU高bug

四、长期监控:避免CPU高问题复发

  1. 开启慢查询日志(永久生效)

    修改my.cnf/my.ini

    ini 复制代码
    slow_query_log = ON
    slow_query_log_file = /var/lib/mysql/mysql-slow.log
    long_query_time = 1
    log_queries_not_using_indexes = ON

    重启MySQL生效:systemctl restart mysqld

  2. 使用监控工具

    • Percona Toolkit:pt-query-digest分析慢查询日志,pt-stalk捕获MySQL性能数据
    • Prometheus + Grafana:监控MySQL CPU、内存、QPS、慢查询等指标
    • MySQL自带工具:mysqladmin statusSHOW ENGINE INNODB STATUS
  3. 定期优化

    • 定期分析慢查询日志,优化SQL和索引
    • 定期维护表(ANALYZE TABLE更新统计信息,OPTIMIZE TABLE整理碎片)
    • 监控数据库增长,及时扩容或分库分表

总结

  1. 紧急排查 :通过SHOW FULL PROCESSLIST定位耗CPU的MySQL线程和SQL,紧急情况下可KILL长时间运行的线程。
  2. 核心分析 :开启慢查询日志,用mysqldumpslowEXPLAIN分析SQL执行计划,重点排查无索引、全表扫描、高频查询等问题。
  3. 长期优化:优化SQL和索引、调整MySQL配置、开启监控,避免CPU高问题复发。
相关推荐
想用offer打牌4 小时前
一站式了解数据库三大范式(库表设计基础)
数据库·后端·面试
甘露s4 小时前
MySQL深入之索引、存储引擎和SQL优化
数据库·sql·mysql
偶遇急雨洗心尘5 小时前
记录一次服务器迁移时,数据库版本不一致导致sql函数报错和系统redirect重定向丢失域名问题
运维·服务器·数据库·sql
Arva .5 小时前
MySQL 的存储引擎
数据库·mysql
Logic1015 小时前
《Mysql数据库应用》 第2版 郭文明 实验5 存储过程与函数的构建与使用核心操作与思路解析
数据库·sql·mysql·学习笔记·计算机网络技术·形考作业·国家开放大学
小二·5 小时前
MyBatis基础入门《十六》企业级插件实战:基于 MyBatis Interceptor 实现 SQL 审计、慢查询监控与数据脱敏
数据库·sql·mybatis
bing.shao5 小时前
Golang WaitGroup 踩坑
开发语言·数据库·golang
专注VB编程开发20年5 小时前
C#内存加载dll和EXE是不是差不多,主要是EXE有入口点
数据库·windows·microsoft·c#
小二·6 小时前
MyBatis基础入门《十二》批量操作优化:高效插入/更新万级数据,告别慢 SQL!
数据库·sql·mybatis