MySql过程列表填充“睡眠”条目导致“连接太多”?

时间:2010-03-09 09:02:58

标签: php mysql

我想就php / mysql连接的长期问题向你提供帮助。

每次执行“SHOW PROCESSLIST”命令时,它都会向我显示从我们的5个Web服务器出现的与数据库服务器的大约400个空闲(状态:睡眠)连接。

这从来都不是一个问题(我没有找到快速的解决方案),直到最近流量数量增加,从那时起MySQL反复报告“到多个连接”的问题,即使这样的350多个连接都在“睡觉“状态。即使存在与同一服务器的睡眠连接,服务器也无法获得MySQL连接。

重新启动Apache服务器时,所有这些连接都会消失。

用于创建数据库连接的PHP代码使用普通的“mysql”模块,“mysqli”模块,PEAR :: DB和Zend Framework Db适配器。 (不同的项目)。没有项目使用持久连接。

提高连接限制是可能的,但似乎不是一个好的解决方案,因为它现在只有450个,而且一次只有20-100个“真实”连接。

我的问题:

为什么在睡眠状态下有这么多连接?我该如何预防呢?

- 更新:

一次运行的Apache请求数永远不会超过50个并发请求,所以我猜关闭连接有问题,或者apache保持端口打开而没有附加phpscript或者某些东西(?)

my.cnf万一有帮助:

innodb_buffer_pool_size = 1024M

max_allowed_packet = 5M
net_buffer_length = 8K

read_buffer_size = 2M
read_rnd_buffer_size = 8M

query_cache_size = 512M
myisam_sort_buffer_size = 128M

max_connections = 450
thread_cache = 50
key_buffer_size = 1280M
join_buffer_size = 16M

table_cache = 2048
sort_buffer_size = 64M
tmp_table_size = 512M
max_heap_table_size = 512M

thread_concurrency = 8

log-slow-queries = /daten/mysql-log/slow-log
long_query_time = 1
log_queries_not_using_indexes

innodb_additional_mem_pool_size = 64M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table

6 个答案:

答案 0 :(得分:61)

基本上,在以下情况下,您将获得处于睡眠状态的连接:

  • PHP脚本连接到MySQL
  • 执行了一些查询
  • 然后,PHP脚本做了一些需要时间的东西
    • 不断开与数据库的连接
  • 最后,PHP脚本结束
    • 表示它与MySQL服务器断开连接

因此,当您有许多保持连接的PHP进程而没有在数据库端实际执行任何操作时,通常会在休眠状态下结束许多进程。

一个基本的想法,所以:确保你没有运行太长时间的PHP进程 - 或者在他们不再需要访问数据库时强制他们断开连接。


另一件事,我经常看到服务器上有一些负载:

  • Apache的请求越来越多
    • 表示要生成的许多页面
  • 每个PHP脚本为了生成页面,都连接到数据库并进行一些查询
  • 随着数据库服务器上的负载增加,这些查询会花费越来越多的时间
  • 这意味着更多流程不断堆积

可以提供帮助的解决方案是减少查询所需的时间 - 优化最长的查询。

答案 1 :(得分:2)

在增加max_connections变量之前,您必须通过运行show processlist命令来检查您有多少个非交互式连接。

如果您有许多睡眠连接,则必须减小“ wait_timeout”变量的值,以等待一段时间后关闭非交互式连接。

  • 显示wait_timeout值:

SHOW SESSION VARIABLES类似于“ wait_timeout”;

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

|变量名|值|

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

| wait_timeout | 28800 |

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

该值以秒为单位,这意味着非交互式连接仍可长达8小时。

  • 要更改“ wait_timeout”变量的值,请执行以下操作:

SET会话wait_timeout = 600; 查询正常,受影响的0行(0.00秒)

10分钟后,如果睡眠连接仍在睡眠,则mysql或MariaDB断开该连接。

答案 2 :(得分:1)

增加最大连接数不能解决问题。

我们在服务器上遇到了同样的情况。这就是发生的情况

用户打开一个页面/视图,该页面/视图连接到数据库,查询数据库,仍然没有完成查询(查询),并且用户离开页面或移至其他页面。 因此,如果有更多的用户连接数据库并执行类似的操作,则打开的连接将保持打开状态,并保持连接数量增加。

您可以设置MySQL的Interactive_timeout,默认为28800(8小时)到1小时

SET interactive_timeout=3600

答案 3 :(得分:0)

所以我同时运行了300个PHP进程并且速度达到每秒60-90之间(我的进程涉及3x查询)。我将它提高到400,这下降到每秒40-50左右。我把它降到200,然后回到60到90之间!

因此,对于遇到此问题的任何人,我的建议是尝试运行 less 而不是更多,并查看它是否有所改进。将使用更少的内存和CPU,因此运行的进程将具有更强的能力,并且速度可能会提高。

答案 4 :(得分:0)

上述解决方案,例如运行查询

SET session wait_timeout=600;

仅在重新启动mysql之前有效。对于持久解决方案,请编辑mysql.conf并在[mysqld]之后添加:

wait_timeout=300
interactive_timeout = 300

您想要的秒数是300。

答案 5 :(得分:-1)

好吧,所以在尝试了每个解决方案以解决wordpress博客上的确切问题之后,我可能做了一些非常愚蠢或天才的事情......不知道为什么Mysql连接有所增加,我在我的标题中使用下面的PHP脚本来杀死所有正在进行的进程..

因此,我网站的每位访问者都有助于消除睡眠过程..

<?php
$result = mysql_query("SHOW processlist");
while ($myrow = mysql_fetch_assoc($result)) {
if ($myrow['Command'] == "Sleep") {
mysql_query("KILL {$myrow['Id']}");}
}
?>
相关问题