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

 更新时间:2025年12月16日 08:24:43   作者:会飞的土拨鼠呀  
本文详细介绍了如何排查和解决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;      -- 按执行时间降序

关键字段解读

  • time:SQL执行的秒数(长时间运行的SQL优先排查)
  • state:线程状态(如Sending dataSorting resultUpdating等,代表SQL执行阶段)
  • sql_text:具体执行的SQL语句(核心排查对象)

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

参数说明:

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

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

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

-- 替换为实际的耗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高,重点检查以下参数:

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

使用监控工具

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

定期优化

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

总结

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

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

相关文章

  • 数据库中如何通过创建新表来备份操作示例代码

    数据库中如何通过创建新表来备份操作示例代码

    数据库备份是指在特定时间点保存数据库中数据的过程,备份数据通常存储在不同的物理介质上,比如硬盘、磁带或云端存储设备,以防止数据丢失或损坏,这篇文章主要介绍了数据库中如何通过创建新表来备份操作的相关资料,需要的朋友可以参考下
    2025-07-07
  • mysql 8.0.22 安装配置方法图文教程

    mysql 8.0.22 安装配置方法图文教程

    这篇文章主要为大家详细介绍了mysql 8.0.22 安装配置方法图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-10-10
  • mysql 5.5 开启慢日志slow log的方法(log_slow_queries)

    mysql 5.5 开启慢日志slow log的方法(log_slow_queries)

    MySQL中提供了一个慢查询的日志记录功能,可以把查询SQL语句时间大于多少秒的语句写入慢查询日志,日常维护中可以通过慢查询日志的记录信息快速准确地判断问题所在
    2016-05-05
  • 一文带你彻底了解MySQL事务机制

    一文带你彻底了解MySQL事务机制

    一个事情由n个单元组成,这n个单元在执行过程中,要么同时成功,要么同时失败,这就把n个单元放在了一个事务之中,这篇文章主要给大家详细介绍MySQL的事务机制,感兴趣的同学欢迎阅读本文
    2023-06-06
  • 详解Navicat远程连接mysql很慢

    详解Navicat远程连接mysql很慢

    这篇文章主要介绍了详解Navicat远程连接mysql很慢(以及数据库连接报错"Too many connections")解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • MySQL表的操作之创建查看删除和修改

    MySQL表的操作之创建查看删除和修改

    这篇文章主要给大家介绍了关于MySQL表的操作之创建查看删除和修改的相关资料,MySQL是最常用的数据库,在数据库操作中基本都是增删改查操作,简称CRUD,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-01-01
  • MySQL 查询过滤之WHERE 子句与运算符实战技巧

    MySQL 查询过滤之WHERE 子句与运算符实战技巧

    本文将系统讲解WHERE子句的用法及常用运算符(算术、比较)的规则与实战技巧,帮你掌握数据筛选的精髓,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • 将MySQL数据库移植为PostgreSQL

    将MySQL数据库移植为PostgreSQL

    PostgreSQL 作为功能最强劲的开源 OO 数据库,仿佛一直不为国内用户所熟识。而我个人也仅是因为工作的缘故接触到这款超经典的数据库,并深为之折服。
    2009-07-07
  • Mysql行锁和表锁的实现示例

    Mysql行锁和表锁的实现示例

    行锁和表锁是两种常见的锁定机制,本文主要介绍了Mysql行锁和表锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • MySQL用户权限验证与管理方法详解

    MySQL用户权限验证与管理方法详解

    这篇文章主要介绍了MySQL用户权限验证与管理方法,结合实例形式详细分析了mysql针对用户权限的验证、查看、收回、修改等各种常用操作技巧,需要的朋友可以参考下
    2018-04-04

最新评论