Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > 查询MySQL CPU使用率变高

查询MySQL的CPU使用率突然变高的几种方法

作者:会飞的土拨鼠呀

本文详细介绍了如何排查和解决MySQL CPU使用率突然变高的问题,包括紧急定位、深入分析和长期监控三个阶段,紧急定位阶段通过查看当前运行的线程和MySQL全局状态,快速锁定耗CPU的SQL或连接,需要的朋友可以参考下

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

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

1. 登录MySQL,查看当前运行的线程

-- 查看所有活跃线程,按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;      -- 按执行时间降序

关键字段解读

2. 查看MySQL全局状态和CPU相关指标

-- 查看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,可临时终止:

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

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

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

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

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

(1)开启慢查询日志(临时生效,无需重启)

-- 设置慢查询阈值(如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自带)分析慢查询日志:

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

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

参数说明:

2. 分析耗CPU SQL的执行计划

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

-- 替换为实际的耗CPU SQL
EXPLAIN SELECT * FROM table_name WHERE condition;

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

重点关注

3. 检查MySQL配置是否合理

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

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

# 查看上下文切换次数(数值过高说明有问题)
vmstat 1
# 查看MySQL进程的线程数
pstree -p 1972827 | wc -l

磁盘IO:磁盘IO高会导致MySQL等待,间接拉高CPU(如swap使用、磁盘满)

# 查看磁盘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高问题复发

开启慢查询日志(永久生效)
修改my.cnf/my.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

使用监控工具

定期优化

总结

  1. 紧急排查:通过SHOW FULL PROCESSLIST定位耗CPU的MySQL线程和SQL,紧急情况下可KILL长时间运行的线程。
  2. 核心分析:开启慢查询日志,用mysqldumpslowEXPLAIN分析SQL执行计划,重点排查无索引、全表扫描、高频查询等问题。
  3. 长期优化:优化SQL和索引、调整MySQL配置、开启监控,避免CPU高问题复发。

以上就是查询MySQL的CPU使用率突然变高的几种方法的详细内容,更多关于查询MySQL CPU使用率变高的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文