MySQL грешка – ‘MySQL server has gone away’

Помощен център

MySQL грешка – ‘MySQL server has gone away’

В статията ще разгледаме и друга подобна грешка - Lost connection to server during query.

Най-честата причина за грешка MySQL server has gone away е, че времето за изчакване (time out) на сървъра е изтекло и сървъра е затворил връзката. В този случай обикновено получавате един от следните два кода за грешки (кой точно зависи от операционната система):

CR_SERVER_GONE_ERROR - Клиентът не можа да изпрати въпрос на сървъра.

CR_SERVER_LOST - Клиентът не получи грешка при писане на сървъра, но не получи пълен отговор (или някакъв отговор) на въпроса.

По подразбиране сървърът затваря връзката след осем часа, ако нищо не се е случило. Можете да промените лимита от време като зададете друга стойност на променливата wait_timeout при стартиране на mysqld.

Ако свързването се управлява от скрипт, просто трябва да изпратите заявката отново, за да извърши автоматично повторно свързване. Това предполага, че имате активирано автоматично повторно свързване в клиента (опцията е активирана по подразбиране за mysql CLI клиент).

Често срещани причини за грешка 'MySQL server has gone away'

  • Вие (или администраторът на базата данни) сте убили текущия процес с kill или mysqladmin kill команда.

  • Опитали сте да изпълните заявка, след като сървъра е затворил връзката. Това показва логическа грешка в приложението, която трябва да бъде коригирана.

  • Клиентско приложение, изпълнявано на различен хост, няма необходимите права за свързване към MySQL сървъра от този хост.

  • Има време за изчакване на TCP/IP връзката от страна на клиента. Това може да се случи, ако сте използвали командите: mysqloptions (..., MYSQLOPTREADTIMEOUT, ...) или mysql_options (..., MYSQL_OPT_WRITE_TIMEOUT, ...). В този случай увеличаването на времето може да помогне за решаването на проблема.

  • Има време на изчакване от страна на сървъра и автоматичното свързване в клиента е деактивирано (флагът за повторно свързване в структурата на MYSQL е равен на 0).

  • Използвате клиент на Windows и сървърa е прекъснал връзката (вероятно поради изтичането на wait_timeout), преди командата да е била издадена. Проблемът в Windows е, че в някои случаи MySQL не получава грешка от операционната система, когато пише в TCP/IP връзката към сървъра, а вместо това получава грешката, когато се опитва да прочете отговора от връзката. Решението за това е да направим mysql_ping() на връзката, ако е имало дълго време от последната заявка (което се прави от Connector/ODBC) или да зададете wait_timeout на mysqld сървъра толкова високо, че на практика никога да не изтича.

  • Можете също така да получите тези грешки, ако изпратите заявка на сървъра, която е некоректна или твърде голяма. Ако mysqld получи пакет, който е твърде голям или е неправилно изпратен, сървъра приема, че нещо се е объркало с клиента и затваря връзката.

  • Ако имате нужда от големи заявки (например, ако работите с големи колони BLOB), можете да увеличите ограничението за заявки, като зададете променливата max_allowed_packet на сървъра, която има стойност по подразбиране 4MB. Може да се наложи да увеличите максималния размер на пакета от страна и на клиента.

  • Инструментът INSERT или REPLACE, който вмъква много редове, също може да причини тези грешки. Всяко едно от тези изявления изпраща една заявка към сървъра, независимо от броя на редовете, които трябва да бъдат вмъкнати. По този начин често можете да избегнете грешката, като намалите броя на изпратените редове за всяка INSERT или REPLACE заявка.

  • Възможно е също така да видите тази грешка, ако резолването на хост име се провали (например, ако DNS сървърa, на който разчита MySQL сървърa или мрежата не е достъпен). Това е така, защото MySQL зависи от DNS, но няма начин да разбере дали неймсървъра работи - от гледна точка на MySQL проблемът не се различава от всяко друго времево изчакване в мрежата.

  • Възможно е също да видите MySQL server has gone away ако MySQL е стартиран с опцията --skip-networking.

  • Друг проблем в мрежата, който може да причини тази грешка, възниква, ако MySQL портът (по подразбиране 3306) е блокиран от вашата защитна стена, като по този начин се прекъсват всички връзки към MySQL сървъра.

  • Можете също така да срещнете тази грешка поради приложения, които стартират child процеси, всеки от които се опитва да използва една и съща връзка към MySQL сървъра. Това може да се избегне, като се използва отделна връзка за всеки child процес.

  • Получили сте повреда (bug), при която сървърът е умрял, докато е изпълнявал заявката.

  • Можете да проверите дали сървърът на MySQL е умрял и е бил рестартиран, като с командата mysqladmin и проверите времето за работа без прекъсване на сървъра (uptime). Ако връзката на клиента е нарушена, защото MySQL е умрял и се е рестартирал, трябва да се концентрирате върху откриването на причината. Започнете, като проверите дали изпълнението на същата заявка отново ще убие сървъра.

  • Можете да получите повече информация за изгубените връзки, като стартирате mysqld с променливата на системната система log_error_verbosity, зададена на стойност 3. Това регистрира някои от съобщенията за прекъсване на връзката във файла hostname.err.

Създаване отчет за грешки

Ако искате да създадете отчет за грешки относно този проблем, уверете се, че сте включили следната информация:

  • Посочете дали MySQL сървърът е умрял. Можете да намерите информация за това в лога за грешки на MySQL сървъра.

  • Ако конкретна заявка убива mysqld и участващите таблици са били проверени с CHECK TABLE, преди да изпълните заявката, можете ли да предоставите възпроизводим тест?

  • Каква е стойността на системната променлива wait_timeout в MySQL сървъра? (mysqladmin variables ви дава стойността на тази променлива.)

  • Опитали ли сте да стартирате MySQL с активиран лог на заявки, за да определите дали проблемната заявка се записва в този лог?