it编程 > 数据库 > Mysql

MySQL CPU飙高排查的全流程指南

3人参与 2026-03-20 Mysql

当 mysql 出现 cpu 持续飙高 时,问题往往不只存在于数据库本身,而可能涉及:

本文提供一套 工程化三阶段排查方法

主机层定位 → 系统层分析 → mysql 内部根因

目标是精准回答三个问题:

  1. cpu 被谁消耗?
  2. 为什么消耗?
  3. 如何优化?

第一阶段:确认问题范围(定位 cpu 消耗主体)

目标:明确 是谁在消耗 cpu

1.1 查看主机整体 cpu 负载

命令

top -c 

cpu 行解读

%cpu(s): 10.4 us, 2.6 sy, 0.0 ni, 86.5 id, 0.1 wa, 0.0 hi, 0.4 si, 0.0 st 
字段含义判断
us用户态 cpu高 → sql 计算密集
sy内核态 cpu高 → 系统调用频繁
wai/o 等待高 → 磁盘瓶颈
id空闲低 → cpu 真正繁忙

经验判断

load average 判断

load average: 8.2, 7.9, 6.5 

规则:

load > cpu 核心数 = 系统过载

示例:

1.2 定位 mysql 进程 pid

ps -ef | grep mysqld
# 或
pidof mysqld

记录 pid,例如:

12345 

1.3 查看 mysql 内部线程 cpu(关键步骤)

mysql = 多线程模型
一个连接 ≈ 一个线程。

top -h -p 12345 -d 1 

场景分析

✅ 场景 a:单线程 100%

含义:

单条慢 sql

行动:

✅ 场景 b:大量线程均高

含义:

并发过高 / 连接风暴

行动:

✅ 场景 c:线程不高但整体 cpu 高

可能原因:

1.4 区分用户态与内核态 cpu

pidstat -p 12345 -u -h 1 5 
字段含义
%usrsql 计算
%system内核消耗
%cpu总占用

第二阶段:系统层面排查

确认 mysqld 占 cpu 后,需要排除 操作系统导致的性能下降

2.1 上下文切换检查

vmstat 1 5 

重点字段:

字段含义
cs上下文切换
in中断次数

判断:

原因:

进一步:

pidstat -w -p 12345 1 5 

关注:

2.2 内存与 swap 检查

free -m
vmstat 1 5

关键字段:

字段含义
siswap in
soswap out

⚠️ si/so != 0 = 严重问题

影响:

优化:

2.3 网络连接检查

netstat -an | grep established | wc -l
netstat -an | grep time_wait | wc -l
ss -ant | grep :3306 | wc -l

判断:

现象含义
established 高连接池失效
time_wait 高短连接风暴

优化:

2.4 磁盘 i/o 与 cpu 关联

iostat -x -k 1 5 

关注:

字段判断
%util接近100% = 饱和
await>10ms = 慢盘

若同时:

➡ cpu 是被动等待。

2.5 numa 架构检查

numactl --hardware
dmesg | grep -i numa

问题:

cpu 与内存跨节点访问

建议:

numactl --interleave=all /usr/sbin/mysqld 

2.6 硬中断检查

watch -n 1 'cat /proc/interrupts | grep -e "cpu|eth|nvme|sda"' 

如果某 cpu 中断暴涨:

➡ irq 未均衡

解决:

irqbalance 

第一、二阶段总结

检查项命令异常
cputopus/wa 高
线程top -h单线程100%
上下文vmstatcs 高
swapvmstatsi/so>0
网络sstime_wait 多
numanumactl未绑定

第三阶段:mysql 层面排查(核心阶段)

当系统层无异常:

问题几乎一定在 sql 或 mysql 内部机制

3.1 实时会话分析(抓现行)

select id, user, host, db, command, time, state, info
from information_schema.processlist
where command != 'sleep'
order by time desc
limit 20;

state 含义

状态含义
sending data全表扫描
sorting result排序
creating tmp table临时表
waiting for lock锁竞争
purgingundo 清理

os 线程关联(8.0)

通过:

performance_schema.threads 

关联:

3.2 慢查询分析(历史问题)

开启:

set global slow_query_log='on';
set global long_query_time=0.1;
set global log_queries_not_using_indexes='on';

mysqldumpslow

mysqldumpslow -s t -t 10 slow.log 

pt-query-digest(推荐)

pt-query-digest slow.log 

关注:

3.3 状态指标分析

线程

show status like 'threads_running'; 

规则:

threads_running ≤ cpu 核心数

临时表

show status like 'created_tmp%'; 

磁盘临时表高 → sql 或 tmp_table_size 问题。

buffer pool 命中率

计算:

1 - reads / read_requests 

目标:

≥ 99%

3.4 锁与事务分析

show engine innodb status\g 

关注:

大量 spin/wait → 锁竞争。

select * from sys.innodb_lock_waits; 

检查:

3.5 执行计划分析(最终定位)

explain format=json select ...

关键字段:

字段危险信号
typeall
keynull
rows极大
extrausing filesort
extrausing temporary

常见索引失效

  1. 违反最左前缀
  2. 函数计算
  3. 隐式类型转换
  4. %abc 模糊查询

3.6 performance schema 深度分析

select event_name, count_star, sum_timer_wait
from performance_schema.events_statements_summary_by_global_by_event_name
order by sum_timer_wait desc
limit 10;

实时:

select *
from sys.session
order by current_statement_latency desc;

第三阶段决策表

现象原因方案
单 sql 慢全表扫描建索引
多 sql 快并发高限流
tmp 表高排序调内存
buffer miss内存小调 bp
锁等待长事务拆事务
purging写入多调 purge

推荐排查顺序(实战经验)

① show processlist
        ↓
② threads_running
        ↓
③ slow log
        ↓
④ explain

以上就是mysql cpu飙高排查的全流程指南的详细内容,更多关于mysql cpu飙高排查的资料请关注代码网其它相关文章!

(0)

您想发表意见!!点此发布评论

推荐阅读

MySQL创建、删除索引的操作代码

03-20

MySQL root用户密码忘记的两种情况及解决方案

03-20

MySQL单表约束超详细实战用法(主键 / 非空 / 唯一 / 默认)

03-20

MySql报错:unblock with mysqladmin flush-hosts的解决方案

03-19

Mysql大数据量分页优化过程

03-19

MySQL 审计级别配置实现步骤

03-19

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论