赞
踩
在使用MySQL过程,想必都有遇到过CPU突然过高,或者达到100%的情况。
数据库执行查询或数据修改操作时,系统需要执行大量的逻辑读操作,其中逻辑IO包含执行查询所需访问表的数据行数。所以系统需要消耗大量的CPU资源以维护从存储系统读取到内存中的数据一致性。
应用负载(QPS)高:
特征:数据库QPS高,查询比较简单,执行效率高,优化余地小。
表现:没有出现慢查询,或者慢查询不是主要原因,且QPS和CPU使用率曲线变化吻合。
常见场景:该状况常见于应用优化过的在线事务交易系统(例如订单系统)、高读取率的热门Web网站应用、第三方压力工具测试(例如Sysbench)等。
慢SQL导致查询成本高(查询访问表数据行数多):
特征:实例的QPS不高,查询执行效率低、执行时需要扫描大量表数据、优化余地大。 表现:存在慢查询,QPS和CPU使用率曲线变化不吻合。
原因分析:由于查询执行效率低,为获得预期的结果需要访问大量的数据导致平均逻辑IO高,因此在QPS并不高的情况下(例如网站访问量不大),也会导致实例的CPU使用率偏高。
大量行锁冲突、行锁等待
对数据库CPU进行升级
数据库查询语句较多可考虑增加读库
可使用缓存查询的尽量使用缓存处理如使用Redis
对于查询数据比较静态、查询重复度高、查询结果集小于1MB的应用,考虑开启查询缓存(Query Cache)。
定期归档历史数据、采用分库分表或者分区的方式减小查询访问的数据量
尽量优化查询,减少查询的执行成本,提高应用可扩展性。
定位效率低的查询、优化查询的执行效率、降低查询执行的成本。
通过以下方式定位效率低的查询:
执行以下SQL语句,查看当前执行的查询语句。
mysql> SHOW FULL PROCESSLIST\G
*************************** 1. row ***************************
Id: 1
User: system user
Host:
db: NULL
Command: Connect
Time: 1030455
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 2
User: system user
Host:
db: NULL
Command: Connect
Time: 1004
State: Has read all relay log; waiting for the slave
I/O thread to update it
Info: NULL
如果没有FULL关键字, 则仅显示字段 SHOW PROCESSLIST中每个语句的前 100 个字符 。
查询时间长、运行状态为
Sending data(该线程正在读取和处理 SELECT语句的行,并将数据发送到客户端。由于在此状态期间发生的操作往往会执行大量磁盘访问(读取),因此它通常是给定查询生命周期内运行时间最长的状态)、
Copying to tmp table(服务器正在复制到内存中的临时表)、
Copying to tmp table on disk(服务器正在复制到磁盘上的临时表。临时结果集变得太大。因此,线程将临时表从内存中更改为基于磁盘的格式以节省内存)、
Sorting result(对于SELECT语句,这类似于Creating sort index,但对于非临时表)
的查询会话可能均包含性能问题。
通过explain 查看执行计划优化语句解决。
解决方案参考链接:
Lock wait timeout exceeded; try restarting transaction解决
参考连接:
https://dev.mysql.com/doc/refman/5.7/en/show-processlist.html
https://dev.mysql.com/doc/refman/5.7/en/general-thread-states.html
往者不可谏,来者犹可追
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。