Heim  >  Artikel  >  Datenbank  >  mysql中有大量sleep进程的原因与解决办法_MySQL

mysql中有大量sleep进程的原因与解决办法_MySQL

WBOY
WBOYOriginal
2016-06-01 13:32:221618Durchsuche

bitsCN.com

mysql中有大量sleep进程的原因与解决办法

 

mysql服务器中有大量的sleep进程,本文分析下mysql出现大sleep进程原因分析与解决方法。

 

可能的原因:

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

我是用排除法去定位问题,对于此原因,1和3通过分析,发现根本不满足

 

此处先排除是mysql 配置的问题,sleep的关闭时间是8个小时,默认值(show variables like 'wait_timeout';),并且服务器配置都是运维人员维护,我们的运维还是很出色的

 

排除1:

 

我的业务,php链接mysql并没有使用持久链接 mysql_pconnect,高并发系统框架中,都不会用持久链接的

 

排除3:

 

数据库查询不够优化?自己写的,不能够。如果真的有不够不够优化的sql,可以开启mysql慢查询日志查看,并优化之;还有一点就是我的这个业务通过看数据库昨日、今日两天的访问情况,读写都不是很多,表的数据量只有二百多万条,而且已经线上正常运营了很久,假如有不够优化的查询,早就挂了。

 

那问题只有可能是 2 程序中,没有及时关闭mysql连接, 造成这个问题的原因很多,也很难分析。一般只要是框架里,都会即时关闭mysql链接的(mysql_close),页面访问完,mysql链接必然会自动关闭。

 

例子:

[php] <?php  define(&#39;MAX_SLEEP_TIME&#39;, 120);    $hostname = "localhost";  $username = "root";  $password = "password";    $connect = mysql_connect($hostname, $username, $password);  $result = mysql_query("SHOW PROCESSLIST", $connect);  while ($proc = mysql_fetch_assoc($result)) {  if ($proc["Command"] == "Sleep" && $proc["Time"] > MAX_SLEEP_TIME) {  @mysql_query("KILL " . $proc["Id"], $connect);  }  } //by www.jbxue.com  mysql_close($connect);  ?>

将当中的$password 改成你实际的数据库密码,sleep连接的时间也可以修改,然后加入计划任务就可以了。比如用 crontab -e 命令加入:

[html] */2 * * * * php /usr/local/sbin/kill-mysql-sleep-proc.php  

就可以每隔 2 分钟检查并清除一次数据库中的sleep连接了

 

如果你没有修改过MySQL的配置,缺省情况下,wait_timeout的初始值是28800

 

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

[html] # vi /etc/my.cnf  [mysqld]  wait_timeout=10  # /etc/init.d/mysql restart  

不过这个方法太生硬了,线上服务重启无论如何都应该尽可能避免,看看如何在MySQL命令行里通过SET来设置:

[html] mysql> set global wait_timeout=10;  mysql> show global variables like &#39;%timeout&#39;;  +----------------------------+-------+  | Variable_name | Value |  +----------------------------+-------+  | wait_timeout | 10 |  +----------------------------+-------+  


bitsCN.com
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn