Возможные причины ошибки "сервер mysql ушел" (php 5.4, mysqlnd)

Недавно мы обновили один из наших веб-серверов с PHP 5.3 (пакет Debian Squeeze, используя libmysqlclient и APC) до PHP 5.4 (пакет Debian Wheezy, Dotdeb, используя mysqlnd, Opcache и APCu). После работы в течение почти одного дня мы сталкивались с ошибками "сервер mysql исчез" для каждого запроса. Все остальные серверы с той же нагрузкой, которые все еще работают с PHP 5.3 с libmysqlclient, используя тот же сервер MySQL, не имели никаких проблем. На всех серверах мы используем:

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), но только в контексте пакетных сценариев с долго выполняющимися запросами. Наши веб-серверы обычно отвечают примерно через 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 ушел"?

1 ответ

Решение

Вероятно, мы выяснили причину ошибки "сервер mysql ушел": на сервере MySQL мы настроили wait_timeout30 секунд, что составляет менее 60 секунд max_execution_time, Таким образом, при определенных условиях что-то занимает больше 30 секунд, пока мы читаем набор результатов из MySQL, поэтому сервер закрывает соединение, пока мы все еще пытаемся получить данные с сервера. Это приводит нас к следующим вопросам:

  1. Какая функция занимает так много времени, пока мы находимся в цикле, читая набор результатов из mysql?

  2. Почему apache2ctl graceful не перезапускать процессы Apache, даже когда max_execution_time следует отменить сценарии через 60 секунд?

Я думаю, что ответ на оба вопроса является ошибкой в ​​APCu. Потому что, если я посмотрю на висящих Apache childs, я получу 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, и проблемы с механизмом блокировки - действительно хорошее объяснение того, что мы видим здесь, в том, что у нас определенно есть код, который читает / записывает в APCu внутри циклов через наборы результатов MySQL, и если есть проблема с блокировкой (которая уже была проблемой для нас в прошлом и для APC), она может занять>30 и <60 секунд, поэтому мы видим ошибку MySQL. И после этой ситуации что-то с APCu идет не так, как надо, поэтому скрипт php не может быть прерван max_execution_time и не быть перезапущен apache2ctl graceful больше.

В трекере проблем APCu я мог найти очень похожие проблемы: https://github.com/krakjoe/apcu/issues/19

Но мы нашли еще один намек. Сбой всегда происходит, когда в APCu есть около 70 тыс. Ключей, и это не зависит от apc.shm_size, но мы обнаружили, что наш скрипт мониторинга APCu выдает " Неустранимая ошибка PHP: допустимый объем памяти 134217728 байт исчерпан (попытался выделить 78 bytes)"ошибки при вызове apcu_cache_info() в строке 47 в то же время, когда мы видим сбой. Таким образом, мы должны изучить сценарий, почему он потребляет так много памяти, AFAIR id считывает все данные для вычисления фрагментации памяти, возможно, нам следует удалить эту часть...

Но в прошлом у нас было много проблем с APC, мы перешли на APCu/Opcache только потому, что у нас возникли ошибки seg в последних версиях APC и PHP 5.4.30, а упомянутая выше проблема открыта уже год. Мы рады видеть недавнюю активность на yac, возможно, lockless - более стабильный вариант. Если мы не можем исправить, удалив проблемы из нашего скрипта мониторинга, мы переключимся на локальные экземпляры memcached, это будет медленнее, но мы знаем, что это очень стабильно.

Другие вопросы по тегам