解决MySQL sleep连接太多

 

执行show processlist;后打印出大量状态为sleep的连接,可能会有两三百个, 这些都是客户端和

数据库通信后没有释放的。大量的连接会严重拖慢系统速度,阻塞新的MySQL连接建立,

甚至造成MySQL报错, 无法响应。

问题产生的根源有以下3种情况

1.使用了太多持久连接

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

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

 

最根本的办法是从以上3种情况排查

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

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

3.只能逐步分析系统的SQL查询,开启慢查询日志,找出低效的SQL语句,然后优化

这是从研发角度排查,如果不方便在代码方面变更, 又想解决问题,

那么就要依靠mysql本身的超时功能解决,命令行键入

mysql> show global variables like “%timeout%”;

+—————————-+———-+

| Variable_name | Value |

+—————————-+———-+

| connect_timeout | 10 |

| delayed_insert_timeout | 300 |

| innodb_lock_wait_timeout | 50 |

| innodb_rollback_on_timeout | OFF |

| interactive_timeout | 28800 |

| lock_wait_timeout | 31536000 |

| net_read_timeout | 30 |

| net_write_timeout | 60 |

| slave_net_timeout | 3600 |

| wait_timeout | 28800 |

+—————————-+———-+

10 rows in set (0.00 sec)

通过 wait_timeout 和 interactive_timeout的值28800发现超时时间是8小时

我们可以减小wait_timeout和interactive_timeout的值,处理超时断开,比如

900秒,即15分钟

set global wait_timeout = 900;

set global interactive_timeout=900;

但是这个配置再重启后就会失效了。

我们可以在配置文件my.cnf中添加

[mysqld]

wait_timeout = 900

interactive_timeout = 900

保存退出,重启MySQL即可生效

 

另一种办法是编写shell脚本强行断开sleep连接

脚本如下:

#!/bin/sh

user=user

passwd=passwd

host=127.0.0.1

while :

do

n=`mysqladmin processlist -u$user -p$passwd -h$host | grep -i sleep | wc -l`

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

echo $n

if [ “$n” -gt 50 ]

then

for i in `mysqladmin processlist -u$user -p$passwd -h$host | grep -i sleep | awk ‘{print $2}’`

do mysqladmin -u$user -p$passwd -h$host kill $i

done

echo “sleep is too many ,and killed” >> /tmp/sleep.log

echo “$date : $n” >> /tmp/sleep.log

else

exit 0

fi

sleep 1

done

保存为cls_sleep.sh,结合任务计划,就可以定期清除sleep连接了。

Leave a Reply