Внезапная ошибка сервера MySQL исчезла на сайте PHP

Сегодня один из моих сайтов начал показывать

Error Number: 2006
MySQL server has gone away

Это клиентский сайт с низким трафиком, работающий под управлением Apache 2.2.9 (Debian), PHP 5.2.6-1+lenny3 (с использованием фреймворка CodeIgniter 1.7.1) и MySQL 5.0.51a. Я, очевидно, повторно исследовал ошибку, но все возможные решения подразумевают, что происходят большие запросы, которые могут истечь по тайм-ауту и ​​сбросить соединение или превысить лимит пакетов. Однако это не так, это небольшая база данных, обрабатываемая простейшими запросами. Чтобы быть уверенным в этом, я сделал несколько запросов, чтобы вернуть одну строку, все та же ошибка.

Учетные данные базы данных в порядке, я даже могу войти прямо в mysql, выполнить некоторые запросы сайта и мгновенно получить нужные данные. Есть несколько других сайтов на том же сервере и соединения с базой данных, сайты гораздо большего размера, и все они не имеют проблем.

Я старался:

  • Перезапуск MySQL
  • Перезагрузка всего сервера
  • Ищем ошибки в логах (как Apache, так и MySQL, нет)
  • Проверка прав пользователя БД
  • Изменение mysql.connect_timeout и default_socket_timeout в PHP
  • Изменение max_allowed_packet в MySQL
  • Чтение официальной документации, форума и всего в SO, что говорит "сервер MySQL ушел"

Новое:

  • Отключение постоянных соединений в PHP
  • Изменение wait_timeout и connect_timeout в MySQL

Обновление:

Кажется, это связано со временем выполнения моего скрипта: он извлекает некоторую информацию с помощью PHP-клиента Facebook, и сегодня этот вызов, похоже, случайно не работает, поэтому у меня либо нет данных из Facebook, либо ошибка MySQL. Но, к моему удивлению, ни одно из приведенных решений, похоже, не имеет отношения к тайм-ауту.

Есть идеи? Спасибо за уделенное время!


person lima    schedule 10.12.2009    source источник
comment
Находятся ли Apache и MySQL на одном компьютере? Если вы создадите простую страницу PHP, которая запускает простой запрос (например, SELECT VERSION();), это сработает?   -  person Eric J.    schedule 11.12.2009
comment
@Eric J: Да, и, что удивительно для меня, да и для второго тоже, похоже, это проблема, связанная с фреймворком.   -  person lima    schedule 11.12.2009
comment
Есть ли шанс, что вы могли бы опубликовать сгенерированный вывод запроса? Я предполагаю, что это происходит через CodeIgniter. Вы случайно не используете InnoDB или экзотическую кодовую страницу?   -  person pestilence669    schedule 11.12.2009
comment
@Pestilence Да, я мог бы, но это просто несколько строк без особых церемоний. Я использую MyISAM и UTF-8 для всех баз данных/таблиц.   -  person lima    schedule 11.12.2009


Ответы (4)


Как я уже говорил в своем обновлении, я пришел к выводу, что проблема с MySQL возникает, когда ссылка на Facebook занимает больше времени, чем максимальное время соединения с БД. Ни одно из предложений не могло обойти это ограничение, поэтому я решил обойти его и переподключаться каждый раз, когда предполагал, что ссылка может исчезнуть.

Поэтому после каждого звонка в Facebook я использовал следующий код:

$this->load->database();
$this->db->reconnect();

Это конкретное решение при использовании CodeIgniter, и, насколько мне известно, функция db->reconnect() доступна только с версии 1.7.2, поэтому я обновил ее, чтобы она работала.

Спасибо всем за ваши ответы!

person lima    schedule 11.12.2009
comment
привет, я столкнулся с такой проблемой, и решение заключается в изменении архитектуры вашего веб-сайта, вы никогда не можете гарантировать, что facebook ответит в определенное время, а значения/данные, взятые из facebook, никогда не будут обновлены. что мы сделали, так это выполнили отдельную работу по хронированию для получения данных из facebook. - person ianace; 02.04.2012
comment
У меня такая же проблема, и это не работает, что-нибудь изменилось с 2009 года? - person W.Doch; 21.04.2016
comment
У меня здесь награда в 500 баллов, и мне интересно, считаете ли вы, что ваш опыт связан и может ли помочь: stackoverflow.com/q/53469793/ 470749 - person Ryan; 27.01.2019

Вероятно, это время ожидания соединения, влияющее на ваши постоянные соединения в PHP. Я видел их все время. Параметр тайм-аута находится в самой MySQL.

Ваши варианты включают: - не использовать постоянные соединения - отключение тайм-аута простоя на сервере MySQL - перехват ошибки

Я всегда оборачиваю переподключение в свой собственный класс PDO, поэтому я даже не могу вспомнить, переподключается ли PHP или нет. В любом случае это легко исправить. По запросу поймать и переподключиться.

Я «генерировал» эту ошибку в прошлом с помощью InnoDB. Если вы используете этот движок, каков результат SHOW ENGINE INNODB STATUS после сбоя?

person pestilence669    schedule 10.12.2009
comment
Отключение постоянных подключений не имело никакого значения, но отключение тайм-аута простоя (обнуление MySQL wait_timeout и connect_timeout, верно?), кажется, решает проблему. Однако я боюсь, что это может иметь негативные последствия, такие как бесконечные процессы MySQL, я прав? Кроме того, что вы подразумеваете под ловушкой ошибки? Я ничего не делал с кодом, и данные БД не менялись, это ночная проблема, и это странно. Спасибо! - person lima; 11.12.2009
comment
Хорошо, проблема все еще существует, но я нашел закономерность. Я обновлю вопрос. - person lima; 11.12.2009
comment
Обнуление тайм-аутов mysql может иметь негативные последствия для глючных сетей. Гм, перехват ошибки потребует небольшого количества пользовательских настроек в обработчиках БД для вашего фреймворка... или гигантского catch(), подключитесь и повторите попытку. Странно, что отключение постоянных подключений не помогло. - person pestilence669; 11.12.2009
comment
На самом деле ... вы используете репликацию на этом сервере MySQL? - person pestilence669; 11.12.2009
comment
Нет, я сделал один раз только для переноса сервера. Я обновил вопрос, теперь виновник кажется более ясным. - person lima; 11.12.2009

Так как другие сайты работают, то можно предположить, что это связано с вашим сайтом (а не с сервером). В официальных документах упоминается, что это может произойти, если вы попытаетесь выполнить запросы после закрытия соединения с сервером. Есть ли в CodeIgniter хуки, которые что-то делают ближе к концу запроса, когда соединение с базой данных может быть закрыто?

person Christian P.    schedule 10.12.2009
comment
Нет, у меня нет хуков ни в CodeIgniter, ни в БД - person lima; 11.12.2009

Вы упомянули, что это ночная задача и что вы получаете данные Facebook и т. д. Процесс выполняется в течение длительного времени?

Недавно у меня был сценарий, который перемещает данные из одного кластера в другой, преобразует форматы и т. д. Этот сценарий работает круглосуточно и без выходных, перемещая эти данные. Я обнаружил, что с постоянными подключениями или без них библиотеки MySQL все равно выпадают через несколько минут (иногда 5 минут, иногда дольше).

Единственный способ, который я нашел, чтобы обойти это для моего случая, - это установить проверку времени в моей оболочке и проверить, сколько времени прошло с момента последнего повторного подключения перед выполнением запроса. Я настроил его так, чтобы он проверял, прошло ли больше 2 минут, и если да, то чтобы восстановить соединение, убедившись, что для флага «new_link» (4-й параметр) в mysql_connect установлено значение false.

С тех пор, как я изменил это, у меня больше никогда не было той же ошибки.

person Lucas    schedule 10.12.2009
comment
Спасибо за ваш вклад, Лукас, но произошло недоразумение, я имел в виду, что проблема возникла в одночасье, то есть она была внезапной без видимой причины. Сама задача (извлечение данных и базы данных) выполняется почти при каждой загрузке страницы из-за Facebook TOS. - person lima; 11.12.2009
comment
Вы получаете сообщение об ошибке мгновенно, т.е. как только вы просматриваете страницу? или это случаи, когда он терпит неудачу после того, как скрипт работает определенное время? - person Lucas; 11.12.2009
comment
Он может выйти из строя сразу или в середине скрипта, в зависимости от причины ошибки. Это подробно описано в моем ответе сейчас :) - person lima; 11.12.2009