作者:Struggle大飞哥 | 来源:互联网 | 2023-08-17 19:58
篇首语:本文由编程笔记#小编为大家整理,主要介绍了Mysql中Sleep进程连接数过多问题解决相关的知识,希望对你有一定的参考价值。
- 连接数查看
进入mysql命令行,输入“show processlist;”命令后,Command列出现一大堆Sleep睡眠状态的连接进程。如下图:
mysql连接进程Sleep睡眠状态过多将影响MySQL系统资源,主要是CPU、内存。超过配置的最大连接数,新的客户端连接将无法连接,mysql将无法提供服务,Web系统无法访问、崩塌。
- 造成连接数过多原因
1)、常见是程序中没有关闭DB连接,客户端在退出前没有调用mysql_close()函数。这是写程序的疏忽。
2)、DB查询复杂,优化不够,造成查询耗时长。
3)、使用过多持久连接。不适合高并发场景系统中。
- 解决方法
批量删除 sleep 进程状态的连接数。
1)、一种直接在MySQL命令控制台操作:mysql> show processlist;
mysql> SELECT concat(‘KILL ‘,id,‘;‘) FROM information_schema.processlist WHERE user=‘user1‘;
mysql> select concat(‘KILL ‘,id,‘;‘) from information_schema.processlist where user=‘user1‘ into outfile ‘/tmp/a.txt‘;
mysql> source /tmp/a.txt;
其中上面user1用户是“show processlist;” 命令下,User列对应最多的Sleep进程连接状态的用户。
注:如上面导出为指定文件路径报“ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement”错误。
是由于MySQL在文件的导入、导出有个默认的文件路径。通过“show variables like ‘%secure%‘;”命令查看默认导入、导出文件路径。
从上面可看出默认路径为“/var/lib/mysql-files/”;所以改下导出文件路径:
然后在执行“source /var/lib/mysql-files/a.txt;”命令,接下来是出现一堆“Query OK, 0 rows affected (0.00 sec)”,执行成功。
2)、另一种是写Shell脚步方法,配合设置cron定时任务
#!/bin/sh
while :
do
sleep_num=`mysqladmin processlist -u user -ppassword -h 10.10.10.100 | grep -ie sleep |wc -l`
date=`date +%Y%m%d[%H:%M:%S]`
echo $sleep_num
if [ "$sleep_num" -gt 100 ];then
for i in `mysqladmin processlist -u user -ppassword -h 10.10.10.100 | grep -ie sleep | awk ‘{print $2}‘`
do
mysqladmin -u user -ppassword -h 10.10.10.100 kill $i
done
echo "sleep is too many more than 100, killed it " >> /tmp/sleep.log
echo "$date : $sleep_num" >> /tmp/sleep.log
fi
sleep 1
done
接下来设置个cron定时任务,设置多长时间跑一次。
- 修改配置
上面方法比较繁琐,写脚本、配置定时任务,而且这种以暴制暴方法可能会导致数据奔溃,不可取。更好的方法应该是让MySQL自己决定这些Sleep睡眠状态连接的命运,实施会更简单,有效。
MySQL配置项中有一项 wait_timeout 配置项,表示Sleep睡眠状态连接数超时时长。超过设置的时长,MySQL自动终止连接。
输入“show global variables like ‘%timeout%‘;” 命令查看:
当前关于睡眠状态连接数超时时长,默认超时时长 wait_timeout 为28800秒,还有一个相关的 interactive_timeout 配置。
wait_timeout 与 interactive_timeout 区别在于 wait_timeout 是MySQL服务器关闭非交互连接之前等待的秒数, interactive_timeout 是MySQL服务器关闭交互式连接前等待的秒数。
什么是交互连接,什么是非交互连接?
通过MySQL客户端连接DB的就是交互式的会话连接,通过JDBC程序连接DB的就是非交互式的会话连接。
接下来修改 wait_timeout、interactive_timeout 全局变量。要配合这两块一起修改才有效。设置DB连接超时时长为3600秒,如下:set global wait_timeout=3600;
set global interactive_timeout=3600;