MySQL进程CPU飙升到900%,怎么处理

首先,说明一下问题:CPU飙升200% 以上是生产容易发生的场景

场景:1:MySQL进程飙升900%

大家在使用MySQL过程,想必都有遇到过CPU突然过高,或者达到200%以上的情况。

数据库执行查询或数据修改操作时,系统需要消耗大量的CPU资源维护从存储系统、内存数据中的一致性。

并发量大并且大量SQL性能低的情况下,比如字段是没有建立索引,则会导致快速CPU飙升,如果还开启了慢日志记录,会导致性能更加恶化。生产上有MYSQL 飙升900% 的恶劣情况。

场景2:Java进程飙升900%

一般来说Java 进程不做大量 CPU 运算,正常情况下,CPU 应该在 100~200% 之间,

但是,一旦高并发场景,要么走到了死循环,要么就是在做大量的 GC,  容易出现这种 CPU 飙升的情况,CPU飙升900%,是完全有可能的。

其他场景:其他的类似进程飙升900%的场景

比如Redis、Nginx等等。

陈某提示:大家介绍场景的时候,就说自己主要涉及了两个场景, Java进程飙升900%、MySQL进程飙升900%两种场景,其实,这两个场景就足够讲半天了, 其他的,使用规避技巧规避一下就行。

场景一:MySQL进程CPU飙升到900%,怎么处理?

定位过程:

  • 使用top 命令观察,确定是mysqld导致还是其他原因。

  • 如果是mysqld导致的,show processlist,查看session情况,确定是不是有消耗资源的sql在运行。

  • 找出消耗高的 sql,看看执行计划是否准确, index 是否缺失,或者实在是数据量太大造成。

处理过程:

  • kill 掉这些线程(同时观察 cpu 使用率是否下降), 一般来说,肯定要 kill 掉这些线程(同时观察 cpu 使用率是否下降),等进行相应的调整(比如说加索引、改 sql、改内存参数)之后,再重新跑这些 SQL。

  • 进行相应的调整(比如说加索引、改 sql、改内存参数)

    index 是否缺失,如果是,则  建立索引。也有可能是每个 sql 消耗资源并不多,但是突然之间,有大量的 session 连进来导致 cpu 飙升,这种情况就需要跟应用一起来分析为何连接数会激增,再做出相应的调整,比如说限制连接数等;

  • 优化的过程,往往不是一步完成的,而是一步一步,执行一项优化措辞,再观察,再优化。

场景1的真实案例:MySQL数据库优化的真实案例

陈某提示:以下案例,来自互联网。大家参考一下,准备一个自己的案例。

本问题亲身经历过。

之前开发同事编写的SQL语句,就导致过线上CPU过高,MySQL的CPU使用率达到900%+,通过优化最后降低到70%~80%。下面说说个人在这个过程中的排查思路。

首先,我们要对问题定位而不是盲目的开启什么 慢日志,在并发量大并且大量SQL性能低的情况下,开启慢日志无意是将MySQL推向崩溃的边缘。

当时遇到这个情况,分析了当前的数据量、索引情况、缓存使用情况。目测数据量不大,也就几百万条而已。接下来就去定位索引、缓存问题。

  1. 经过询问,发现很多查询都是走MySQL,没有用到缓存。

  2. 既然没有用到缓存,则是大量请求全部查询MySQL导致。通过下面的命令查

<think>好的,用户问的是当MySQLCPU使用率飙升至600%时,如何在Linux系统下定位具体的SQL语句。我需要一步步理清楚处理这个问题的流程,同时确保回答结构清晰,符合用户的要求。 首先,我要考虑用户可能的背景。用户可能是有一定数据库管理经验的系统管理员或开发人员,遇到性能问题需要快速定位原因。他们可能对MySQL和Linux的基本监控工具有一定了解,但需要具体的步骤指导。用户的需求是找到导致CPU的SQL语句,进而优化或调整。 接下来,我需要回忆常见的MySQL性能问题排查方法。通常,CPU可能由低效查询、锁争用、配置不当等引起。这里用户特别提到定位具体SQL,所以重点在如何找到消耗CPU资源的查询。 首先想到的是使用Linux的top或htop命令确认是否是mysqld进程占用CPU。这一步是基本确认,确保问题确实出在MySQL上,而不是其他进程。 然后,进入MySQL内部,查看当前运行的线程。使用SHOW PROCESSLIST命令,但可能不够详细,特别是对于突发的性能问题,可能需要更实时的监控。所以提到使用information_schema.processlist表来过滤正在执行中的查询,按时间降序排列,找出长时间运行的查询。 但用户可能需要更精确的方法,比如使用performance_schema或开启慢查询日志。不过开启慢查询日志可能需要提前配置,不一定在问题发生时已经开启。所以应该考虑如何实时抓取。 接下来,提到使用mysqladmin工具生成当前所有线程的堆栈,结合pt-pmp工具分析,这可能对不熟悉perf或gdb的用户来说有点复杂,但这是定位问题的有效方法之一。 然后,考虑使用Perf工具进行性能剖析,这需要一定的Linux工具知识,但可以定位到具体的函数调用,进而关联到SQL查询。 还有检查慢查询日志,但需要确认是否已开启,如果没有开启,临时设置可能会影响性能,需要权衡。同时,提到使用mysqldumpslow分析日志,这是常用的方法。 另外,提到检查锁等待情况,因为有时候锁等待也会导致CPU,但用户的问题更可能由查询引起,不过还是需要覆盖全面。 最后,总结步骤,并给出优化建议,比如索引、分页、缓存等,帮助用户解决问题后进一步处理。 需要确保步骤清晰,命令准确,并且考虑到用户可能的不同环境,比如是否安装了percona-toolkit,或者是否有权限运行perf等。同时,提醒用户在生产环境谨慎操作,避免影响线上服务。 可能的问题点:pt-pmp工具需要安装percona-toolkit,用户可能没有安装,是否需要提前说明?或者是否有替代方法?比如用gdb手动抓取堆栈,但可能比较复杂,所以还是建议使用pt-pmp,并提及安装方法。 另外,使用performance_schema需要确保启用,默认情况下可能没有开启,可能需要用户确认配置,但考虑到用户可能没有提前配置,所以重点放在processlist和慢查询日志上。 最后,确保所有命令正确,比如使用mysqladmin时可能需要正确的权限,提示用户使用正确的用户名和密码。 总结下来,步骤应该是:确认进程→查看活动线程→分析堆栈→性能工具剖析→检查慢查询→锁分析→优化建议。这样用户能一步步排查,找到问题SQL。</think>### MySQL CPU飙升至600%问题定位步骤 --- #### 一、确认进程占用 1. **查看CPU占用排名** ```bash top -c # 按P排序,确认`mysqld`进程是否占满CPU ``` --- #### 二、定位MySQL内部问题 2. **查看活跃线程** ```sql -- 登录MySQL SHOW FULL PROCESSLIST; -- 查看当前执行中的SQL ``` 3. **过滤执行时间长的查询** ```sql SELECT * FROM information_schema.processlist WHERE COMMAND != 'Sleep' AND TIME > 60 -- 单位:秒 ORDER BY TIME DESC; ``` --- #### 三、堆栈分析(紧急场景) 4. **抓取线程堆栈** ```bash mysqladmin -uroot -p debug # 生成线程堆栈到error log ``` ```bash pt-pmp # 使用Percona Toolkit聚合堆栈信息(需安装) ``` --- #### 四、性能剖析工具 5. **使用`perf`分析CPU消耗** ```bash perf top -p $(pgrep mysqld) # 实时监控MySQL进程函数调用 perf record -p $(pgrep mysqld) -g -- sleep 30 # 采样30秒生成报告 perf report # 查看热点函数 ``` --- #### 五、慢查询日志分析 6. **临时开启慢查询日志** ```sql SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; -- 记录执行超过1秒的SQL SET GLOBAL log_queries_not_using_indexes = ON; ``` 7. **分析慢日志** ```bash mysqldumpslow -s t /var/lib/mysql/slow.log # 按总耗时排序 ``` --- #### 六、锁等待排查 8. **检查锁阻塞** ```sql SELECT * FROM sys.innodb_lock_waits; -- 查看锁等待链(需启用`sys`库) ``` --- ### 频问题SQL特征 1. **全表扫描** ```sql EXPLAIN SELECT * FROM table WHERE unindexed_column = 'value'; ``` 2. **大结果集排序** ```sql SELECT * FROM logs ORDER BY create_time DESC LIMIT 100000,20; ``` 3. **复杂JOIN或子查询** ```sql SELECT a.* FROM users a JOIN orders b ON a.id = b.user_id WHERE b.amount > (SELECT AVG(amount) FROM orders); ``` --- ### 优化建议 1. **紧急处理** ```sql KILL [PROCESS_ID]; -- 终止消耗查询 ``` 2. **长期优化** - 添加缺失索引(尤其WHERE/ORDER BY/JOIN字段) - 重写分页查询(使用游标代替`LIMIT offset`) - 启用查询缓存或优化配置参数(`innodb_buffer_pool_size`) --- 通过以上步骤可逐层定位到具体SQL,建议优先检查未用索引的查询和复杂JOIN操作。生产环境操作前建议在测试环境验证。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值