2014-07-22 39 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實例,這會比較慢,但我們知道它非常穩定。