2014-07-22 38 views
1

我们最近从PHP 5.3(Debian Squeeze软件包,使用libmysqlclient和APC)将其中一个web服务器升级到了PHP 5.4(Debian Wheezy,Dotdeb软件包,使用mysqlnd,Opcache和APCu)。在工作了将近一天之后,我们遇到了“mysql服务器已经消失”的每个请求错误。具有相同负载的所有其他服务器仍然使用相同的MySQL服务器运行PHP 5.3并使用libmysqlclient完全没有问题。在我们使用的所有服务器上:“mysql server has gone away”的错误(php 5.4,mysqlnd)

max_execution_time = 60 
default_socket_timeout = 60 

在我们的PHP 5.3服务器上,我们没有更改任何mysql/my.cnf超时。我们知道有关read_timeout(mysql),wait_timeout(mysql),default_socket_timeout(php)和max_execution_time(php)的问题,但仅限于具有长时间运行查询的批处理脚本的上下文。我们的网络服务器通常在300ms内响应,所以这些超时应该不是问题。

当我们从负载平衡中移除服务器时,它变得非常奇怪,所以没有负载了,但我们仍然有180个繁忙的Apache进程。即使apache2ctl graceful没有改变任何东西,甚至小时后apache2ctl status说:

     Apache Server Status for localhost 

    Server Version: Apache/2.2.22 (Debian) 
    Server Built: Jun 16 2014 03:51:14 
    __________________________________________________________________ 

    Current Time: Tuesday, 22-Jul-2014 10:17:44 CEST 
    Restart Time: Monday, 21-Jul-2014 18:43:37 CEST 
    Parent Server Generation: 26 
    Server uptime: 15 hours 34 minutes 6 seconds 
    Total accesses: 596973 - Total Traffic: 1.6 GB 
    CPU Usage: u6288.72 s463.96 cu.01 cs0 - 12% CPU load 
    10.7 requests/sec - 30.8 kB/second - 2962 B/request 
    176 requests currently being processed, 99 idle workers 

GGGGGG_GGGGGGGGG_GG_GGGGGGGGGGGGGGGGGGGG_GGGGGG_GGGGGGGG_GGGGGGG 
GGGGGGGGGG_G_GGGGGGGG_G_GG__GGGGGG_GGGGG_GGG___GG_GGGGGGGG_G_GGG 
GGGGGGGGGGGG_G_GG__GG_GGG_GGGGGGGGG__GGG_GGG_G_G_GG_G_GGGGGGGGGG 
GGG_GGG_GG_GGG_GG_G_GGG_______________.___._W___________________ 
____.___________.______......................................... 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
................................................................ 
.... 

    Scoreboard Key: 
    "_" Waiting for Connection, "S" Starting up, "R" Reading Request, 
    "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup, 
    "C" Closing connection, "L" Logging, "G" Gracefully finishing, 
    "I" Idle cleanup of worker, "." Open slot with no current process 

只有apache2ctl restart解决了问题,一切好起来的工作。 MySQL错误是我们迄今发现的唯一“有用的”错误消息。

它可能是一个问题与mysqlnd,opcache或apcu和PHP 5.4.30?是否有任何已知的问题可能导致我们所经历的行为?

或者你有一个想法如何调试“MySQL服务器已经消失”的问题?

回答

0

我们可能发现为什么会出现“mysql server has gone away”错误:在MySQL服务器上,我们配置了一个30秒的wait_timeout,这个时间小于60秒max_execution_time。因此,在某些情况下,当我们从MySQL读取结果集时,似乎需要30秒以上的时间,因此服务器关闭连接,但仍然试图从服务器获取数据。这导致我们接下来的问题:

  1. 什么函数消耗这么多时间,而我们正在循环读取从mysql的结果集?

  2. 为什么apache2ctl graceful不重启Apache进程,即使max_execution_time应该在60秒后中止脚本?

我认为这两个问题的答案都是APCu中的一个错误。因为如果我看悬Apache的孩子的,我得到FUTEX_WAIT从strace的:

[pid 28354] futex(0x7f3a8c3d2094, FUTEX_WAIT, 69, NULL <unfinished ...> 

如果我用gdb似乎在pthread_rwlock_wrlock()挂看这样的过程中,我得到的是:

0x00007f3adcd18abd in pthread_rwlock_wrlock() from /lib/x86_64-linux-gnu/libpthread.so.0 

好的,pthread_rwlock用于在APCu中进行锁定,锁定机制的问题对于我们在这里看到的内容是一个很好的解释,因为我们肯定有代码可以通过MySQL结果集读取/写入循环内部的APCu,并且if锁定存在问题(过去,APC也是一个问题),可能需要30和< 60秒,所以MySQL错误就是我们所看到的。在这种情况之后,APCu发生了一些错误,所以php脚本不能被max_execution_time中止,并且不会再被apache2ctl graceful重新启动。

在APCu问题跟踪我能找到非常类似的问题: https://github.com/krakjoe/apcu/issues/19

但我们发现另一条线索。崩溃总是发生,当APCu中有大约70k个密钥时,并且它不依赖于apc.shm_size,但我们发现APCu monitoring script产生“PHP致命错误:允许的内存大小为134217728字节已耗尽(试图分配78个字节)在我们看到崩溃的同时在第47行调用apcu_cache_info()时发生错误。所以我们必须考察脚本为什么会消耗这么多的内存,AFAIR ID读取的所有数据用于计算内存碎片,也许我们应该删除该部分...

但是我们在APC中遇到了很多问题过去,我们转而使用APCu/Opcache只是因为我们遇到了最新的APC和PHP 5.4.30的seg故障,而且上面提到的问题现在已经开放了一年。我们很高兴看到yac最近的活动,也许无锁是一个更稳定的选择。如果我们无法通过从监视脚本中移除问题来修复问题,那么我们将切换到本地memcached实例,这会比较慢,但我们知道它非常稳定。