在MySQL中有很多空闲连接(没有持久参数)是正常的吗?

但是我们没有使用任何持久连接。 为什么有很多空闲的连接? 我们注意到使用'show processlist'命令,时间约为4000-8000秒。 这些连接看起来总是“睡眠”。 我们在fast-cgi模式下使用带有PHP的Nginx,并使用PDO库。 有什么build议么?

这听起来像一个客户端没有正确closures它的连接,所以服务器让他们挂起,直到他们超时。 如果一个客户端只是打开一个连接,然后运行一个查询,然后放弃连接,它不会被closures(即使客户端扔掉把手后不能再访问它)。 我的理解是,Web服务器应该在页面完成时closures这些连接。 看起来这没有发生。 至于为什么,我不知道。

服务器上的默认超时设置是6小时,这意味着在Web服务器上,这可以轻松地build立多达数千个连接,等待超时。

嗯,这取决于。

当然DBMS不会自己发明这些连接。 虽然创build到mysql的连接的开销很低,但在创build连接和发起查询之间,以及查询完成和结果被完全轮询之间仍然存在差距,然后在脚本closures之前还有一段距离断开连接。 如果您的代码在需要之前打开连接,并且/或者在closures连接之前等待时间过长,这些将更加明显。

然而,在没有持续连接的情况下, 基于web的软件不应该将连接打开超过几秒钟。 如果您启用了mysql复制,那么这将显示为自启动以来运行的线程。

什么

SHOW FULL PROCESSLIST 

(从mysql shell)显示?

  • 在您的php.iniconfiguration文件中禁用持续的MySQL查询。
  • 编辑你的/etc/my.cnf文件并设置一些额外的限制。

set-variable = long_query_time = 120 set-variable = wait_timeout = 28000 set-variable = connect_timeout = 25

我注意到你标记fastcgi。 我怀疑你的问题。

PHP(假设你是这样做的)只会在解释器退出并清理开始时终止连接,这意味着连接保持打开状态,直到垃圾收集为止。 FastCGI通常不会“终止”,因为它作为一项服务运行,这就是为什么你经历这些漫长的睡眠时间。

解决这个问题的最好方法是在代码的最后声明一个mysql_close()。 无论如何,最好的做法是自己清理! 但作为一个kludge解决方法,你可以在mysql中设置一个wait_timeout来销毁连接。