2014-10-29 52 views
4

我在WAMP堆栈上本地托管一个网站。我最近通过将array(PDO::ATTR_PERSISTENT => true)添加到PDO构造函数选项参数中,将PHP连接切换为持久性。我注意到了响应时间的巨大下降(hooray!)。MySQL持续PHP连接“飘走”错误

当机器醒来时,缺点似乎是一个消失的错误。这在更改连接样式之前从未发生过。

缓存连接是否可能关闭,但会继续返回?是否可以重置一个PDO连接或通过一个catch块内的PHP重置连接池?

回答

1

我已经戒了这个局面了几天,并根据在网络上类似的问题的普遍性,这似乎是PDO防止持续连接的有效的管理不足。

答案显而易见的问题:

  • PHP 5.4.22
  • 在php.ini驱动程序设置的持久连接打开
  • 会话限制无界(设置为-1)
  • 池限制不受约束(设为-1)

我可以通过执行以下操作来重新创建问题:

在MySQL数据库上发出以下语句。

set @@GLOBAL.interactive_timeout := 10; 
set @@GLOBAL.wait_timeout := 10; 

发出一些针对服务器的请求来生成一些缓存的连接。你可以看到相比,通过与非持久性连接这样的线程数增加:

echo $conn->getAttribute(PDO::ATTR_SERVER_INFO); 

等待至少10秒,并开始发出更多的请求。你应该开始接收'消失'的消息。

问题是SQL关闭了连接,随后调用PDO构造函数返回这些关闭的连接而没有重新连接它们。

这是PDO不足的地方。无法强制连接打开,甚至无法检测状态。

我目前正在解决这个越来越方式(当然一个黑客位的)被发出这些MySQL的语句

set @@GLOBAL.interactive_timeout := 86400; 

set @@GLOBAL.wait_timeout := 86400; 

These variables are set to 28800sec (8 hours) by default。请注意,您将希望重新启动Apache以清除缓存的连接,或者在池中的所有连接都已经循环之前(我不知道如何/何时发生这种情况),您将不会注意到有什么区别。我选择了24小时86400,我每天都在这台机器上,所以这应该覆盖基本需求。

在此更新之后,我让我的机器至少坐了12个小时,这是我开始“离开消息”之前坐的时间。它看起来像问题解决。

我一直在想,虽然我不能强制打开连接,但可能会从池中删除不良连接。我没有尝试过,但稍微优雅的解决方案可能是检测'消失'消息,然后将对象设置为NULL,告诉PHP销毁资源。如果数据库逻辑做了这样的一些尝试(如果发生更严重的错误,则必须有一个限制),这可能有助于将这些错误降到最低。

0

是的,如果连接关闭,您将需要重新连接。

http://brady.lucidgene.com/2013/04/handling-pdo-lost-mysql-connection-error/

+0

我的问题是,如果连接需要重新连接。我问是否缓存的连接可能会超时,然后被允许坐在池中导致关闭或其他有问题的连接返回。引用的帖子并没有真正解决潜在的问题。我收到消息的查询是不起眼的,应该立即返回,所以我怀疑这个问题不是一个超时问题,而是如何管理连接问题。 – gph 2014-10-29 01:57:23

+0

是的,PDO不主动检查空闲连接上的连接状态。我不知道有任何数据库接口。它只会在连接被唤醒时检查它。一般来说,除非您已考虑所有问题,否则应避免使用持久连接。 – winmutt 2014-10-29 02:03:23