您的位置:首页 > 数据库 > MySQL

mysql show processlist分析

2016-03-31 17:20 671 查看

现场描述:

公司项目遇到一个问题:数据库内存溢出,通过netstat发现大量的本地连接,因为服务器在外网启动后几秒钟就崩死,后来把3306墙了以后,再换64位mysql,勉强起来了。经过一些排查,怀疑与数据库连接有关。因为通过客户量计算,数据库连接数没有netstat里面显示的多。

数据库错误日志:Out of memory (Needed 6707872 bytes)

查看方法:



错误讲解:

数据库操作一般会封装成一个类,提供创建/断开连接、运行语句等方法。

比较业余的用法是:用的时候,把连接类实例化一个临时变量,创建一个新连接,用完不断开连接,直接销毁。

反复这么做,MySQL就会创建一堆线程维护连接,每个连接都要占用些内存的。因此,要么MySQL内存溢出、要么系统TCP通信资源被耗尽(有兴趣的同事可以搜索下,64位window系统到底多少,据说单机最大4096)。

解决方案:

为了避免这个问题,可以用以下方式:

数据库操作类设置为全局变量,这样可以节省连接;

为了不耽误事,添加CheckConnect(),每次用之前check一下,或者定期check,如果断了就连接,上层调用GetConnect()拿连接,不用关心细节,只要执行结果;

在析构函数中,如果连接还在就调用DisConnect()销毁连接——保姆功能。

相关说明:

在CMD窗口运行这个,然后去C盘慢慢看conn_info.txt吧,如果同一个IP的sleep好多,那估计有人要检讨下了(微笑)。

netstat -ano | findstr 3306 > c:/conn_info.txt

对于Netstat各种状态不熟悉的,可以看下这个:图解netstat打印出的各种状态

注意:

对于Windows系统,一个TCP连接断开后,不会立即释放资源。因为需要大量的I/O操作,还要清理虚拟缓存,太频繁就会导致内存碎片。所以它会积压一段时间(大概是20分钟左右),批量销毁资源。

因此,是否能到达系统最大的TCP连接数还不一定。主要影响因素:TCP连接创建的频率(1个连接/秒和100连接/秒肯定不一样),系统版本(是32位,还是64位),MySQL连接多久释放(默认超级大,28800秒,8小时!!!)



参考资料:

SHOW PROCESSLIST in MySQL command: sleep

MySQL数据库连接超时(wait_timeout)问题的处理

MySQL里的wait_timeout

MySql Proccesslist filled with “Sleep” Entries leading to “To many Connections”?

MySQL 5.0 Reference Manual-14.2.2 InnoDB Startup Options and System Variables

5.1.4 Server System Variables

mysql show processlist分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息