1

最近、Web サーバーの 1 つを PHP 5.3 (Debian Squeeze パッケージ、libmysqlclient と APC を使用) から PHP 5.4 (Debian Wheezy、Dotdeb パッケージ、mysqlnd、Opcache、APCu を使用) にアップグレードしました。ほぼ 1 日正常に動作した後、すべての要求で「mysql サーバーがなくなりました」というエラーが発生しました。同じ MySQL サーバーを使用して libmysqlclient で PHP 5.3 を実行している同じ負荷の他のすべてのサーバーでは、まったく問題はありませんでした。私たちが使用するすべてのサーバーで:

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) の問題についてはわかっていますが、実行時間の長いクエリを含むバッチ スクリプトのコンテキストでのみです。通常、Web サーバーは約 300 ミリ秒で応答するため、ここではタイムアウトは問題になりません。

サーバーをロードバランシングから外したときは本当におかしくなったので、もう負荷はありませんでしたが、まだ 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 サーバーがなくなった」問題をデバッグする方法を知っていますか?

4

1 に答える 1

0

「mysql サーバーがなくなった」というエラーが発生する理由はおそらくわかりました。MySQL サーバーwait_timeoutでは、60 秒未満である 30 秒を構成しましたmax_execution_time。そのため、特定の条件下では、MySQL から結果セットを読み取るときに 30 秒以上かかるように見えるため、サーバーからデータを取得しようとしている間にサーバーが接続を閉じます。これは、次の質問につながります。

  1. mysql から結果セットを読み取るループ中に、どの関数がそれほど多くの時間を消費しますか?

  2. 60 秒後にスクリプトを中止する必要があるapache2ctl graceful場合でも、Apache プロセスを再起動しないのはなぜですか?max_execution_time

両方の質問に対する答えは APCu のバグだと思います。ぶら下がっている Apache チャイルドを見ると、FUTEX_WAITstrace から得られるからです。

[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

OK、pthread_rwlock は APCu でのロックに使用されます。ロック メカニズムの問題は、ここで見られることの非常に良い説明です。つまり、MySQL の結果セットを介してループ内で APCu を読み書きするコードが確実にあるということです。これはロックに関する問題です (これは過去に 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 監視スクリプトが「PHP 致命的なエラー: 134217728 バイトの許容メモリ サイズが使い果たされました (割り当てを試行しました) 78 bytes)」というエラーが発生し、47 行目で apcu_cache_info() を呼び出すと、クラッシュが発生しました。そのため、スクリプトが大量のメモリを消費する理由を調べる必要があります。AFAIR id は、メモリの断片化を計算するためのすべてのデータを読み取ります。おそらくその部分を削除する必要があります...

しかし、過去に APC で多くの問題が発生しました。APCu/Opcache に切り替えたのは、最新の APC と PHP 5.4.30 でセグメント障害が発生したためであり、上記の問題は現在 1 年間未解決です。yacでの最近のアクティビティを確認できてうれしく思います。おそらく、ロックレスの方がより安定したオプションです。監視スクリプトから問題を取り除いても解決できない場合は、ローカルの memcached インスタンスに切り替えます。速度は遅くなりますが、非常に安定していることがわかっています。

于 2014-07-25T08:40:12.100 に答える