MySQL CPU占用过高的排查指南

 更新时间:2025年08月05日 09:09:12   作者:明湖起风了  
使用关系数据库MySQL版时,如果您的CPU使用率很高或接近100%,会导致数据读写处理缓慢、连接缓慢、删除出现报错等,从而影响业务正常运行,所以本文给大家介绍了MySQL CPU占用过高的排查指南,需要的朋友可以参考下

MySQL CPU 占用过高时,排查具体占用资源的表需结合系统监控、数据库分析工具和 SQL 诊断命令。

一、快速定位问题根源​

确认 MySQL 进程占用 CPU

  • 使用 tophtop 命令查看系统进程,确认是否为 mysqld 进程导致 CPU 飙升。
  • 若 MySQL 进程持续占用 90% 以上 CPU,需深入分析数据库内部操作。

区分负载类型:QPS 激增 vs. 慢查询

  • QPS 激增​:对比 CPU 曲线与 QPS(每秒查询量)曲线是否同步波动。若同步,说明高并发导致 CPU 压力。
    • 计算 QPS:
SHOW GLOBAL STATUS LIKE 'Questions';  -- 获取总查询量
SHOW GLOBAL STATUS LIKE 'Uptime';     -- 获取运行时间(秒)
-- QPS = Questions / Uptime
  • 慢查询为主​:若 CPU 飙高而 QPS 未明显上升,大概率是慢 SQL 或锁竞争导致。

二、定位高资源消耗的表​

​方法 1:实时分析活跃线程​

通过 SHOW FULL PROCESSLIST 或系统表查询当前执行的 SQL 及操作的表:

-- 查看所有活跃线程(非 Sleep 状态)
SELECT * FROM information_schema.PROCESSLIST 
WHERE COMMAND != 'Sleep' AND TIME > 10  -- 筛选执行时间>10秒的线程
ORDER BY TIME DESC;
  • 关键字段​:
    • STATE:若为 Sending dataSorting resultCreating tmp table,表示可能涉及全表扫描或复杂计算。
    • INFO:显示正在执行的 SQL,从中提取操作的表名。

​方法 2:分析慢查询日志​

  • 开启慢查询日志​:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;  -- 记录超过1秒的查询
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';
  • 使用工具分析日志​:
    • ​**pt-query-digest(Percona Toolkit)​**​:
pt-query-digest /var/log/mysql/slow.log --limit 10  -- 输出消耗最高的前10个查询
  • 输出结果关注点​:
    • Table:被频繁操作的表名。
    • Rows_examined:扫描行数过大(如百万级)的表。
    • Query_time:单次执行耗时长的 SQL。

​方法 3:通过 Performance Schema 定位表级操作​

-- 查看消耗 CPU 最高的 SQL 及其操作的表
SELECT 
  DIGEST_TEXT AS query,
  SCHEMA_NAME AS db,
  COUNT_STAR AS exec_count,
  SUM_TIMER_WAIT/1e9 AS total_time_sec,
  SUM_ROWS_EXAMINED AS rows_examined
FROM performance_schema.events_statements_summary_by_digest 
ORDER BY total_time_sec DESC 
LIMIT 10;
  • 关键信息​:
    • query 字段可直接看到 SQL 操作的表(如 SELECT * FROM orders)。
    • exec_count 该SQL模式被执行的次数
    • ​total_time_sec 该SQL模式所有执行的总耗时(单位:皮秒,除以1e9转换为秒;例如:SUM_TIMER_WAIT=1234567890000 → 1.23456789秒;识别最耗时的SQL模式
    • rows_examined 该SQL模式所有执行中检查的总行数;​例如​:1000000(表示这个SQL模式总共扫描了100万行)​,用于识别全表扫描或索引效率低下的查询

​方法 4:检查表大小与索引状态​

查询表空间占用​:

SELECT 
  TABLE_NAME,
  ROUND((DATA_LENGTH + INDEX_LENGTH)/1024/1024, 2) AS size_mb,
  TABLE_ROWS
FROM information_schema.TABLES 
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY size_mb DESC;
  • 大表(GB 级)​​ 更容易因全表扫描导致 CPU 飙升。
  • 小表但高扫描频次​:可能索引缺失或统计信息过期。

检查索引有效性​:

-- 查看表的索引情况
SHOW INDEX FROM your_table;
  • Cardinality(基数)远小于实际行数,说明索引可能失效,需更新统计信息:
ANALYZE TABLE your_table;

​三、针对性优化措施​

紧急处理​:

终止高消耗线程:

KILL <thread_id>;  -- 从 PROCESSLIST 获取 thread_id

索引优化​:

  • 为高频查询的 WHEREJOINORDER BY 字段添加索引。
  • 避免索引失效:
    • 禁止对索引列使用函数(如 WHERE DATE(create_time) = ...)。
    • 避免隐式类型转换(如字符串字段用数字查询)。

SQL 重写​:

  • 拆分复杂查询(如将子查询改为 JOIN)。
  • 减少 SELECT *,仅返回必要字段。
  • 分页查询优化:用 WHERE id > last_id LIMIT n 替代 OFFSET

配置调整​:

增加临时表大小,避免磁盘临时表:

tmp_table_size = 256M
max_heap_table_size = 256M

调整 InnoDB 缓冲池(通常设为物理内存的 70%):

innodb_buffer_pool_size = 8G

架构扩展​:

  • 读写分离:将查询分流到只读副本。
  • 分库分表:对亿级大表按业务拆分。

排查工具推荐​

工具类型推荐工具用途
系统监控top, htop, vmstat定位进程及线程级 CPU 占用
SQL 分析pt-query-digest, EXPLAIN分析慢查询及执行计划
实时诊断SHOW PROCESSLIST, sys.schema查看活跃线程与资源消耗
可视化监控Prometheus + Grafana, PMM长期追踪性能指标(QPS/CPU/锁)

注意​

  • 锁竞争问题​:若 SHOW PROCESSLIST 显示大量线程状态为 Waiting for table lock,需检查长事务或死锁(information_schema.INNODB_TRX)。
  • 外部因素​:备份任务、批量数据维护也可能导致 CPU 短暂飙高,需结合操作日志排查。

以上就是MySQL CPU占用过高的排查指南的详细内容,更多关于MySQL CPU占用过高的资料请关注脚本之家其它相关文章!

相关文章

  • 详解MySQL 8.0 之不可见索引

    详解MySQL 8.0 之不可见索引

    这篇文章主要介绍了MySQL 8.0 之不可见索引的相关资料,帮助大家更好的理解和学习新版本的MySQL,感兴趣的朋友可以了解下
    2020-10-10
  • Mysql使用函数json_extract处理Json类型数据的方法实例

    Mysql使用函数json_extract处理Json类型数据的方法实例

    在日常业务开发中通常mysql数据库中某个字段会需要存储json格式字符串,下面这篇文章主要给大家介绍了关于Mysql使用函数json_extract处理Json类型数据的相关资料,需要的朋友可以参考下
    2022-09-09
  • mysql最左前缀法则导致索引失效的解决

    mysql最左前缀法则导致索引失效的解决

    最左前缀是在使用innodb存储引擎索引时,需要遵守的法则,本文主要介绍了mysql最左前缀法则导致索引失效的解决,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • mysql中使用replace替换某字段的部分内容

    mysql中使用replace替换某字段的部分内容

    这篇文章主要介绍了mysql中使用replace替换某字段的部分内容的方法,需要的朋友可以参考下
    2014-11-11
  • 深入理解MySQL中的主键、超键、候选键、外键

    深入理解MySQL中的主键、超键、候选键、外键

    文详细介绍了MySQL数据库中的四种关键键类型:主键、超键、候选键和外键,并探讨了它们在数据库设计和管理中的作用,感兴趣的可以了解一下
    2024-09-09
  • windows 10 下mysql-8.0.17-winx64的安装方法图解

    windows 10 下mysql-8.0.17-winx64的安装方法图解

    这篇文章主要介绍了windows 10 mysql-8.0.17-winx64的方法,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • MySQL分区表的使用

    MySQL分区表的使用

    本文详细介绍了在MySQL中创建分区表的方法和注意事项,包括Range和List两种常见分区类型的具体操作流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-10-10
  • MySQL/MariaDB中如何支持全部的Unicode

    MySQL/MariaDB中如何支持全部的Unicode

    MySQL/MariaDB中,utf8字符集并不是对Unicode的真正实现,那么MySQL/MariaDB中如何支持全部的Unicode,感兴趣的朋友可以了解一下
    2021-08-08
  • MySQL数据库wait_timeout参数详细介绍

    MySQL数据库wait_timeout参数详细介绍

    这篇文章主要介绍了MySQL数据库wait_timeout参数详细介绍的相关资料,wait_timeout是MySQL中用于控制非交互式连接等待时间的系统变量,影响服务器资源管理和安全性,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-12-12
  • MySQL安装配置以及安装失败解决过程

    MySQL安装配置以及安装失败解决过程

    我们在下载完MYSQL时,安装可能会遇到或大或小的问题,下面这篇文章主要给大家介绍了关于MySQL安装配置以及安装失败解决的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-04-04

最新评论