admin 管理员组

文章数量: 1086019


2024年4月29日发(作者:os系统盘制作)

mysql出现大量sleep进程的原因与解决方案

展开全文

今天。用 mysqladmin -uroot -p`cat /XX/XX/mysql_passwd`

processlist 查看了一下mysqld的进程,发现有大量的sleep链接没

有关闭。

造成睡眠连接过多的原因?

1. 使用了太多持久连接(个人觉得,在高并发系统中,不适合

使用持久连接)

2. 程序中,没有及时关闭MySQL连接

3. 数据库查询不够优化,过度耗时。

当然,更根本的方法,还是从以上三点排查之:

1. 程序中,不使用持久链接,即使用mysql_connect而不是

pconnect。

2. 程序执行完毕,应该显式调用mysql_close

3. 只能逐步分析系统的SQL查询,找到查询过慢的SQL,优化之

解决过程:

1...................................

wait_timeout值设置:

检查mysql 配置的问题,sleep的关闭时间是8个小时,默认值

(show variables like 'wait_timeout';)

以下是默认值.

(也可以在/etc/中查看wait_timeout)

对于这个值:wait_timeout过大有弊端,其体现就是MySQL里

大量的SLEEP进程无法及时释放,拖累系统性能,不过也不能把这个

值设置的过小,否则可能会遭遇到“MySQL has gone away”之类的

问题(你可以在程序里时不时mysql_ping一下,以便服务器知道你还

活着,重新计算wait_timeout时间)

这里一个容易把人搞蒙的地方是如果查询时使用的是show

variables的话,会发现设置好像并没有生效,这是因为单纯使用

show variables的话就等同于使用的是show session variables,查

询的是会话变量,只有使用show global variables,查询的才是全局

变量。如果仅仅想修改会话变量的话,可以使用类似set

wait_timeout=10;或者set session wait_timeout=10;这样的语法。

这个方法只是临时性的,如果服务器重启后,wait_timeout的值

又会变成28800。

所以如果业务允许的情况下,可以修改配置文件。

2....

在使用PHP连接mysql的时候,尽量不要使用pconnect的方

式。

使用mysql_pconnect的方式,即使你的调用 mysql_close()也是

无法释放数据库连接的,那么mysql中的死连接的数量就会越来越多

了,所以不要使用持久链接,而使用mysql_connect短链接(特别高

并发系统框架中,都避免使用持久链接)

3......

. 及时使用mysql_close()关闭连接,程序中,没有及时关闭

mysql连接

4................

根据慢查询日志对SQL语句进行优化

5................

通过shell来强制杀死sleep进程:

以下是在服务器上测试过的代码,行得通:

#!/bin/bash

while :

do

n=`/usr/local/mysql/bin/mysqladmin

processlist | grep -i sleep | wc -l`

date=`date +%Y%m%d[%H:%M:%S]`

echo $n

if [ "$n" -gt 1 ]

then

-uroot

-pXXXXXX

for i in `/usr/local/mysql/bin/mysqladmin -uroot -pXXXXX

processlist | grep -i sleep | awk '{print $2}'`

do

/usr/local/mysql/bin/mysqladmin -uroot -pXXXXXX kill $i

done

# echo "sleep is too many i killed it" >>

/tmp/

# echo "$date : $n" >> /tmp/

fi

sleep 5

done

以下是网上参考资料摘要:

【减少MySQL的Sleep进程有效方法】

经常遇到很多朋友问到,他的MySQL中有很多Sleep进程,严重

占用MySQL的资源,现在分析一下出现这种现象的原因和解决办法:

1,通常来说,MySQL出现大量Sleep进程是因为采用的PHP的

MySQL长链接数据库方式,即使用了mysql_pconnect来打开链接数

据库,解决办法就是使用“短”链接,即mysql_connect函数。

2,在使用mysql_connect短链接方式打开数据库,每个页面在

打开数据库后,执行SQL完成,当页面脚本结束的时候,这个MySQL

连接会自动关闭并且释放内存。但仍然出现大量Sleep进程,可以看

看网站是否存在以下几个方面的问题。

A,硬盘上存在大量的静态文件,或者WEB服务器负荷太重,在

处理HTTP请求响应变得太慢,这样也有可能导致出现大量Sleep进

程,解决方法适当调整WEB服务参数和文件,一味的静态或者缓存化

网页内容并不是灵丹妙药。

B,在网页脚本中,有些计算和应用可能非常耗时,比如在0秒的

时候打开数据库执行完一段SQL代码后,网页脚本随即花了20秒钟

进行一段复杂的运算,或者 是require了一个庞大的PHP文件(比如

含有几千个违规关键字的过滤函数),哪么这个时候在MySQL后台看

到的进程中,这个20秒的过程 MySQL并没有做任何事情了,一直处

于Sleep状态,直到这个页面执行完毕或者达到wait_timeout值(被

强行关闭),优化网页脚本,尽量让 程序快速运行,或者在执行这段

耗时的运行过程中,执行mysql_close把当前MySQL链接强行关闭。

C,在采集站中,MySQL中大量的Sleep进程这类现象尤其明显

(比如很多网友问道DeDeCMS的MySQL中出现大量Sleep),因

为大部的采 集器页面在运行过程中,事先打开了一个MySQL链接

(可能是为了验证用户权限等),然后开始使用file_get_contents之

类的操作去获取一 个远程的网页内容,如果这个远程的站点访问速度

太慢,比如花了10秒时间才把网页取回,哪么当前采集脚本程序就一

直阻塞在这里,并且MySQL啥事也没 干,一直处于Sleep状态。解

决方法同上,在发出file_get_contents采集远程网页的时候,使用

mysql_close强行关闭 MySQL的连接,等采集完成在适当需要的时候

再重新mysql_connect即可。

总的说来,MySQL是一个非常高效快速的数据库,要让他发挥到

最大的性能,同时也不要过量的去掘取他的优势所在,适当的分表

(超过10G的表,在打开和关闭以前更新的时候效率明显下降很多),

尽可能的优化SQL都可以做到事半功倍的。

通过分析,发现我的业务的问题和上面的B、C问题类似,但问题

真的没有完全一样的,这个要根据自己的业务分析。我得问题最后定

位在一个后台的服务出问题了,有个验证服务,每次登录都会去验证,

但此服务失败了,导致页面响应超时,我想应该是进程中断了,最终

导致mysql无法正常关闭,从而产生了大量的sleep,严重消耗mysql

服务器资源(主要是cpu, 内存),并可能导致mysql崩溃。

解决问题的方法很多:恢复业务;kill掉sleep的进程,修改

sleep时间为60秒,60秒后sleep的链接会自动释放掉的;重启

mysql(慎用)


本文标签: 进程 大量 连接 关闭 使用