数据库导致服务器CPU过高怎么优化?

 我来答
猪八戒网
2023-06-06 · 百度认证:重庆猪八戒网络有限公司官方账号
猪八戒网
猪八戒网(zbj.com)创建于2006年,现已形成猪八戒网、天蓬网和线下八戒工场的“双平台+一社区”服务模式,是中国领先的人才共享平台。
向TA提问
展开全部

啥数据库呀?cpu几个?用到多少了?我见过的cpu过高有2种,

一种是很多命令在执行,

二种是是因为他们写的sql语句过滥造成的。

其他的我就不知道了。

mysql数据库导致cpu过高一般从执行状态分析:

执行状态分析

Sleep状态

通常代表资源未释放,如果是通过连接池,sleep状态应该恒定在一定数量范围内

实战范例:因前端数据输出时(特别是输出到用户终端)未及时关闭数据库连接,导致因网络连接速度产生大量sleep连接,在网速出现异常时,数据库toomanyconnections挂死。

简单解读,数据查询和执行通常只需要不到0.01秒,而网络输出通常需要1秒左右甚至更长,原本数据连接在0.01秒即可释放,但是因为前端程序未执行close操作,直接输出结果,那么在结果未展现在用户桌面前,该数据库连接一直维持在sleep状态!

Waitingfornet,readingfromnet,writingtonet

偶尔出现无妨

如大量出现,迅速检查数据库到前端的网络连接状态和流量

案例:因外挂程序,内网数据库大量读取,内网使用的百兆交换迅速爆满,导致大量连接阻塞在waitingfornet,数据库连接过多崩溃

Locked状态

有更新操作锁定

通常使用innodb可以很好的减少locked状态的产生,但是切记,更新操作要正确使用索引,即便是低频次更新操作也不能疏忽。如上影响结果集范例所示。

在myisam的时代,locked是很多高并发应用的噩梦。所以mysql官方也开始倾向于推荐innodb。

Copytotmptable

索引及现有结构无法涵盖查询条件,才会建立一个临时表来满足查询要求,产生巨大的恐怖的i/o压力。

很可怕的搜索语句会导致这样的情况,如果是数据分析,或者半夜的周期数据清理任务,偶尔出现,可以允许。频繁出现务必优化之。

Copytotmptable通常与连表查询有关,建议逐渐习惯不使用连表查询。

实战范例:

u某社区数据库阻塞,求救,经查,其服务器存在多个数据库应用和网站,其中一个不常用的小网站数据库产生了一个恐怖的copytotmptable操作,导致整个硬盘i/o和cpu压力超载。Kill掉该操作一切恢复。

Sendingdata

Sendingdata并不是发送数据,别被这个名字所欺骗,这是从物理磁盘获取数据的进程,如果你的影响结果集较多,那么就需要从不同的磁盘碎片去抽取数据,

偶尔出现该状态连接无碍。

回到上面影响结果集的问题,一般而言,如果sendingdata连接过多,通常是某查询的影响结果集过大,也就是查询的索引项不够优化。

如果出现大量相似的SQL语句出现在showproesslist列表中,并且都处于sendingdata状态,优化查询索引,记住用影响结果集的思路去思考。

Storingresulttoquerycache

出现这种状态,如果频繁出现,使用setprofiling分析,如果存在资源开销在SQL整体开销的比例过大(即便是非常小的开销,看比例),则说明querycache碎片较多

使用flushquerycache可即时清理,也可以做成定时任务

Querycache参数可适当酌情设置。

Freeingitems

理论上这玩意不会出现很多。偶尔出现无碍

如果大量出现,内存,硬盘可能已经出现问题。比如硬盘满或损坏。

i/o压力过大时,也可能出现Freeitems执行时间较长的情况。

Sortingfor

和Sendingdata类似,结果集过大,排序条件没有索引化,需要在内存里排序,甚至需要创建临时结构排序。

其他

排查方法:

>mysql-uroot-p#登陆数据库

>********#输入数据库密码

mysql>showprocesslist;

showprocesslist命令详解:

processlist命令的输出结果显示了有哪些线程在运行,可以帮助识别出有问题的查询语句。

+-----+-------------+--------------------+-------+---------+-------+----------------------------------+----------

|Id|User|Host|db|Command|Time|State|Info

+-----+-------------+--------------------+-------+---------+-------+----------------------------------+----------

|207|root|192.168.0.20:51718|mytest|Sleep|5||NULL

先简单说一下各列的含义和用途,第一列,id,不用说了吧,一个标识,你要kill一个语句的时候很有用。user列,显示单前用户,如果不是root,这个命令就只显示你权限范围内的sql语句。host列,显示这个语句是从哪个ip的哪个端口上发出的。呵呵,可以用来追踪出问题语句的用户。db列,显示这个进程目前连接的是哪个数据库。command列,显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)。time列,此这个状态持续的时间,单位是秒。state列,显示使用当前连接的sql语句的状态,很重要的列,后续会有所有的状态的描述,请注意,state只是语句执行中的某一个状态,一个sql语句,已查询为例,可能需要经过copyingtotmptable,Sortingresult,Sendingdata等状态才可以完成,info列,显示这个sql语句,因为长度有限,所以长的sql语句就显示不全,但是一个判断问题语句的重要依据。

常见问题:

一般是睡眠连接过多,严重消耗mysql服务器资源(主要是cpu,内存),并可能导致mysql崩溃。

解决办法:

mysql的配置my.ini文件中,有一项:

wait_timeout,即可设置睡眠连接超时秒数,如果某个连接超时,会被mysql自然终止。

wait_timeout过大有弊端,其体现就是MySQL里大量的SLEEP进程无法及时释放,拖累系统性能,不过也不能把这个指设置的过小,否则你可能会遭遇到“MySQLhasgoneaway”之类的问题,通常来说,我觉得把wait_timeout设置为10是个不错的选择,但某些情况下可能也会出问题,比如说有一个CRON脚本,其中两次SQL查询的间隔时间大于10秒的话,那么这个设置就有问题了(当然,这也不是不能解决的问题,你可以在程序里时不时mysql_ping一下,以便服务器知道你还活着,重新计算wait_timeout时间):

mysql>showglobalvariableslike'wait_timeout';

+----------------------------+-------+

|Variable_name|Value|

+----------------------------+-------+

|wait_timeout|120|

+----------------------------+-------+

mysql>setglobalwait_timeout=20;

至此,mysql占用cpu下降了

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式