但是我们没有使用任何持久连接。为什么有很多空闲连接?我们通过使用“show processlist”命令注意到了这一点,时间大约为 4000-8000 秒。这些连接看起来总是处于“睡眠”状态。我们在 fast-cgi 模式下使用 Nginx 和 PHP,并使用 PDO 库。有什么建议吗?
答案1
这听起来像是客户端没有正确关闭连接,所以服务器让它们一直挂起直到超时。如果客户端只是打开一个连接,然后运行查询,然后放弃连接,那么不是关闭(即使客户端在丢弃句柄后无法再访问它)。我的理解是,Web 服务器应该在页面完成时关闭这些连接。看起来这并没有发生。至于为什么,我不知道。
服务器上的默认超时设置是 6 小时,这意味着在 Web 服务器上很容易建立多达数千个等待超时的连接。
答案2
- 在 php.ini 配置文件中禁用持久 MySQL 查询。
- 编辑您的 /etc/my.cnf 文件并设置一些额外的限制。
设置变量 = long_query_time=120 设置变量 = wait_timeout=28000 设置变量 = connect_timeout=25
答案3
嗯,这得看情况。
当然,DBMS 不会自行发明这些连接。虽然创建与 mysql 的连接开销很低,但在创建连接和触发查询之间、查询完成和结果完全轮询之间以及脚本关闭连接之前仍会存在差距。如果您的代码在需要之前打开连接,和/或在关闭连接之前等待太久,这些差距将更加明显。
然而,由于缺乏持久连接,没有基于网络的软件应该保持连接打开超过几秒钟。如果您启用了 mysql 复制,那么这将显示为自启动以来运行的线程。
什么是
SHOW FULL PROCESSLIST
(从 mysql shell)显示?
答案4
我注意到您标记了 fastcgi。我怀疑那是您的问题。
PHP(假设您使用 PHP 执行此操作)仅在解释器退出并开始清理后才终止连接,这意味着连接将保持打开状态并处于空闲状态直到垃圾收集为止。FastCGI 通常不会“终止”,因为它作为服务运行,这就是您经历这些长时间睡眠的原因。
解决此问题的最佳方法是在代码末尾明确声明 mysql_close()。无论如何,最好的做法是自己清理!但作为一种临时解决方法,您可以在 mysql 中设置 wait_timeout 来破坏连接。