龙叔 发表于 2024-11-26 08:48:52

MySql CPU激增原因小结

QPS激增会导致CPU占用升高



分析

可以使用监控工具,查看CPU利用率曲线图和QPS曲线图进行对比。如果CPU曲线图波动情况跟QPS曲线图波动情况基本保持一致,可以明确明确CPU升高时QPS上升导致。反之,CPU曲线图对比QPS曲线图有不同步的峰值抖动,则说明在QPS未明显激增的情况下,CPU占用过高,则大概率跟慢SQL相关,可进行后续慢SQL的排查。
备注:如果没有监控工具协助分析的情况下,可以使用show global status like ‘Questions’ 和show global status like 'Uptime’查询,将两者相除得到就是QPS值。
show global status like 'Questions';
show global status like 'Uptime';
解决QPS激增:


[*]判断是否为实际业务激增导致,如果是实际业务激增导致,则可以通过资源扩充,满足业务激增的业务需求;
[*]找到具体激增的查询所对应的应用系统的接口,进行限流控制,以保护数据库并发访问量;
[*]应用采用读写分离,降低单点访问压力;
[*]查看sql是否存在循环插入或者更新的情况,改为批量操作,减少执行次数。

慢SQL会导致CPU升高

分析

通过show processlist查看当前MySQL线程运行情况,主要通过 Time 连接时间和State当前SQL所处的状态来分析慢SQL,一般情况下如果存在Sending data说明该查询较慢,可以将info中的SQL复制出来通过explain查看详细的执行计划进行分析。
show processlist;可通过MySql自带的慢SQL日志功能分析:
通过root登录数据库开启慢SQL查询日志,set global slow_query_log = ‘ON’,并设置慢SQL过滤时间set global long_query_time = 1(超过1秒视为慢SQL),指定慢SQL日志文件存放路径set global slow_query_log_file = ‘/var/lib/mysql/test_1116.log’。通过持续观察该慢SQL记录日志文件,查找出具体的慢SQL复制出来通过explain查看详细的执行计划进行分析。

解决慢SQL:


[*]紧急处理可以先通过杀死对应线程(kill process id),缓解问题;
[*]无索引或者索引失效情况下,新建有效索引或者优化SQL语句;
[*]SQL中有大量聚合操作:简化SQL,将逻辑提炼到业务代码中;聚合操作异步或者预处理;
[*]SQL返回的数据过多,改为分页查询;
[*]读写较多锁竞争激烈,分库分表或读写分离。

大量空闲连接会导致CPU升高

show full processlist;
分析      

通过 show full processlist 查看Comand 有大量的Sleep,再根据Time查看装填时间是否很长,如果存在大量长时间睡眠线程占用数据库连接,会导致数据库的吞吐量下降,进而导致阻塞也会引发CPU飘高的现象。

解决:


[*]修改MySql配置文件中的 wait_timeout 空闲等待时间,值越小则相对空闲线程就会越少,不过需要重启MySql才会生效;
[*]通过 set global wait_timeout = XX 方式热修改该参数。

MySql 问题排查常用命令


Sql执行计划,进行sql执行分析

explain + sql;
explain select * from user;
查看数据库当前执行线程状态

show full processlist;其中重点字段包括Comand 、Time 、State、Info,可以查看当前所有连接线程中命令、持续时间、状态、对应的SQL信息。

查询当前运行的所有事物

select * from information_schema.INNODB_TRX ;在执行结果中可以看到是否有表锁等待或者死锁,如果有死锁发生,可以通过下面的命令来杀掉当前运行的事务:KILL trx_mysql_thread_id 。

查看当前出现的锁

select * from information_schema.INNODB_LOCKS;在改结果中可以看到锁的类型、所属事务ID、锁级别、锁模式等信息。

查看死锁

SELECT
        b.trx_state,
        e.state,
        e.time,
        d.state AS block_state,
        d.time AS block_time,
        a.requesting_trx_id,
        a.requested_lock_id,
        b.trx_query,
        b.trx_mysql_thread_id,
        a.blocking_trx_id,
        a.blocking_lock_id,
        c.trx_query AS block_trx_query,
        c.trx_mysql_thread_id AS block_trx_mysql_tread_id
FROM
        information_schema.INNODB_LOCK_WAITS a
        LEFT JOIN information_schema.INNODB_TRX b ON a.requesting_trx_id = b.trx_id
        LEFT JOIN information_schema.INNODB_TRX c ON a.blocking_trx_id = c.trx_id
        LEFT JOIN information_schema.PROCESSLIST d ON c.trx_mysql_thread_id = d.id
        LEFT JOIN information_schema.PROCESSLIST e ON b.trx_mysql_thread_id = e.id
ORDER BY
        a.requesting_trx_id;
查看InnoDB状态

SHOW ENGINE INNODB STATUS;到此这篇关于MySql CPU激增原因小结的文章就介绍到这了,更多相关MySql CPU激增原因内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

来源:https://www.jb51.net/database/331040f68.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: MySql CPU激增原因小结