mysql清理死链接_对MySQL的死连接Sleep的进程的来源研究[转]

本文介绍了MySQL中处理死链接的方法,包括通过查询`SHOW PROCESSLIST`找出长时间睡眠的进程并使用`KILL`命令终止。此外,讨论了`wait_timeout`和`interactive_timeout`参数对连接超时的影响,以及如何通过设置这些参数防止过多的死链接。还提到了PHP中不当使用`pconnect`可能导致的死链接问题,建议在适当的时候调用`mysql_close()`。同时,给出了修改MySQL配置文件以调整连接超时时间的建议。
摘要由CSDN通过智能技术生成

当前的连接数:

mysql> show status like '%Threads_connected%';

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

| Variable_name     | Value |

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

| Threads_connected | 27    |

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

1 row in set (0.00 sec)

最大连接数:

show variables like '%max_connections%';

set GLOBAL max_connections=800;

flush privileges

也可以修改/etc/my.cnf中的max_connections:

max_connections = 1000

关于php应该在何时调用mysql_close()以及pconnect方式和传统方式有何种区别。

以前我一直认为,当php的页面执行结束时,会自动释放掉一切。相信很多人都跟我想的一样,但事实证明并不是这样。比如session就不会随着页面执行完毕而释放。

php的垃圾回收机制,其实只针对于php本身。对于mysql,php没权利去自动去释放它的东西。如果你在页面执行完毕前不调用mysql_close(),那么mysql那边是不会关闭这个连接的。如果你用的是pconnect方式,那么即使你在页面执行完毕前调用mysql_close(),也无法令mysql关闭这个连接。

也许在负载低的情况下,你感受不到有何不妥。但是,一旦负载很高,就回出现很多的死链接,于是得杀掉它们,现象:

在php中使用pconnect方式建立连接,然后到mysql客户端下执行show processlist;如果你的负载到一定程度的话,你可以看到很多sleep的进程,这些进程就是人们常说的sleep连接,它们会一直保持sleep,直到my.cnf里面设置的wait_timeout这个参数值的时间到了,mysql才会自己杀死它。在杀死它的时候,mysql还会在error-log里面记录一条Aborted connection xxx to db: 'xxx' user: 'xxx' host: 'xxx'的日志,用google翻译一下,会得到一个相当强悍的解释"胎死腹中的连接"!

那么造成sleep的原因,有三个,下面是mysql手册给出的解释:

1.客户端程序在退出之前没有调用mysql_close().[写程序的疏忽,或者数据库的db类库没有自动关闭每次的连接。。。]

2.客户端sleep的时间在wait_timeout或interactive_timeout规定的秒内没有发出任何请求到服务器. [类似常连,类似于不完整的tcp ip协议构造,服务端一直认为客户端仍然存在(有可能客户端已经断掉了)]

3.客户端程序在结束之前向服务器发送了请求还没得到返回结果就结束掉了. [参看:tcp ip协议的三次握手]

网上有一个哥们写了一个,如下:

define('MAX_SLEEP_TIME', 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);

}

}

mysql_close($connect);

?>

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

*/2 * * * * php /usr/local/sbin/kill-mysql-sleep-proc.php就可以每隔 2 分钟检查并清除一次数据库中的sleep连接了。

我结合自己的实际改写如下:

require_once 'services/UserServices*.class.php';

define('MAX_SLEEP_TIME', 120);//注意调试的时候这儿只能修改120,而不能再重新定义,常量一旦定义好,就不能被重新定义了。PHP预先定义了几个常量,并提供了一种机制在运行时自己定义。常量和变量基本上是一样的,不同的是:常量必须用DEFINE函数定义,常量一旦定义好,就不能被重新定义了。

$scoreServ = new TMService ( );

$sql = "SHOW PROCESSLIST";

$proc = $scoreServ*->query($sql);

foreach($proc as $oneproc)

{

if ($oneproc["Command"] == "Sleep" && $oneproc["Time"] >= MAX_SLEEP_TIME)

{

$query = "KILL " . $oneproc["Id"];

echo $query."\n";

@$scoreServ*->query($query);

}

}

?>

crontab 加入:

*/2 * * * * /usr/local/php/bin/php /usr/local/tads/htdocs/*/src/crontable/killmysqlsleepproc.php

通过修改mysql的设置也可以做到,配置如下:

max_connections:

允许的同时客户数量。负载过大时,你将经常看到 too many connections 错误。已达到最大链接数,所以会出现这种情况。 我们服务器数值是200。

wait_timeout

服务器在关闭连接之前在一个连接上等待行动的秒数,默认数值是28800,即如果没有事情发生,服务器在 8个小时候关闭连接。防止sleep过多而导致出现too many connections。

如果你的sleep进程数在同一时间内过多,再加上其他状态的连接,总数超过了max_connections的值,那mysql除了root用户外,就无法再继续处理任何请求、无法与任何请求建立连接或者直接down了。所以,这个问题在大负载的情况下还是相当严重的。如果发现你的mysql有很多sleep连接存在,首先要检查你的程序是否使用的是pconnect的方式,其次,检查在页面执行完毕前是否及时调用了mysql_close()。

还有一个办法,你可以在my.cnf里面加上wait_timeout和interactive_timeout,把他们的值设的小一些,默认情

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值