In general the error:
Error: 2006 (
CR_SERVER_GONE_ERROR
) — MySQL server has gone away
means that the client couldn’t send a question to the server.
mysql
import
In your specific case while importing the database file via mysql
, this most likely mean that some of the queries in the SQL file are too large to import and they couldn’t be executed on the server, therefore client fails on the first occurred error.
So you’ve the following possibilities:
-
Add force option (
-f
) formysql
to proceed and execute rest of the queries.This is useful if the database has some large queries related to cache which aren’t relevant anyway.
-
Increase
max_allowed_packet
andwait_timeout
in your server config (e.g.~/.my.cnf
). -
Dump the database using
--skip-extended-insert
option to break down the large queries. Then import it again. -
Try applying
--max-allowed-packet
option formysql
.
Common reasons
In general this error could mean several things, such as:
-
a query to the server is incorrect or too large,
Solution: Increase
max_allowed_packet
variable.-
Make sure the variable is under
[mysqld]
section, not[mysql]
. -
Don’t afraid to use large numbers for testing (like
1G
). -
Don’t forget to restart the MySQL/MariaDB server.
-
Double check the value was set properly by:
mysql -sve "SELECT @@max_allowed_packet" # or: mysql -sve "SHOW VARIABLES LIKE 'max_allowed_packet'"
-
-
You got a timeout from the TCP/IP connection on the client side.
Solution: Increase
wait_timeout
variable. -
You tried to run a query after the connection to the server has been closed.
Solution: A logic error in the application should be corrected.
-
Host name lookups failed (e.g. DNS server issue), or server has been started with
--skip-networking
option.Another possibility is that your firewall blocks the MySQL port (e.g. 3306 by default).
-
The running thread has been killed, so retry again.
-
You have encountered a bug where the server died while executing the query.
-
A client running on a different host does not have the necessary privileges to connect.
-
And many more, so learn more at: B.5.2.9 MySQL server has gone away.
Debugging
Here are few expert-level debug ideas:
-
Check the logs, e.g.
sudo tail -f $(mysql -Nse "SELECT @@GLOBAL.log_error")
-
Test your connection via
mysql
,telnet
or ping functions (e.g.mysql_ping
in PHP). -
Use
tcpdump
to sniff the MySQL communication (won’t work for socket connection), e.g.:sudo tcpdump -i lo0 -s 1500 -nl -w- port mysql | strings
-
On Linux, use
strace
. On BSD/Mac usedtrace
/dtruss
, e.g.sudo dtruss -a -fn mysqld 2>&1
See: Getting started with DTracing MySQL
Learn more how to debug MySQL server or client at: 26.5 Debugging and Porting MySQL.
For reference, check the source code in sql-common/client.c
file responsible for throwing the CR_SERVER_GONE_ERROR
error for the client command.
MYSQL_TRACE(SEND_COMMAND, mysql, (command, header_length, arg_length, header, arg));
if (net_write_command(net,(uchar) command, header, header_length,
arg, arg_length))
{
set_mysql_error(mysql, CR_SERVER_GONE_ERROR, unknown_sqlstate);
goto end;
}
Эта ошибка означает, что MySQL сервер запущен, но он отказывает вам в соединении. Это может произойти по нескольким причинам. Самых основных и часто встречающихся причин три: сервер перегружен, и у вас истекло время ожидания ответа, ваш клиент отправил слишком большой пакет или сервер был не до конца проинициализирован.
В этой небольшой статье мы рассмотрим более подробно, почему возникает ошибка 2006: MySQL server has gone away, а также — как её исправить.
Такую ошибку вы можете увидеть во время подключения к базе данных с помощью PHP, консольного клиента или, например, в PhpMyAdmin:
1. Истекло время ожидания
Как я уже писал выше, одной из причин может быть таймаут ожидания соединения. Возможно, сервер баз данных перегружен и не успевает обрабатывать все соединения. Вы можете подключиться к серверу с помощью консольного клиента, если вам это удастся, и попытаться выполнить какой-либо запрос, чтобы понять, действительно ли запросы выполняются слишком долго. Если это так, можно оптимизировать производительность MySQL с помощью скрипта MySQLTuner.
В большинстве случаев надо увеличить размер пула движка InnoDB с помощью параметра innodb_buffer_pool_size. Какое значение лучше поставить, можно узнать с помощью указанного выше скрипта. Например, 800 мегабайт:
sudo vi /etc/mysql/my.cnf
innodb_buffer_pool_size=800M
Есть и другой путь решения этой проблемы. Если такая скорость обработки запросов считается нормальной, можно увеличить время ожидания ответа от сервера. Для этого измените значение параметра wait_timeout. Это время в секундах, на протяжении которого надо ждать ответа от сервера. Например:
wait_timeout=600
После любых изменений не забудьте перезапустить MySQL сервер:
sudo systemctl restart mysql
или:
sudo systemctl restart mariadb
2. Слишком большой пакет
Если ваш клиент MySQL создаёт слишком большие пакеты с запросами к серверу, это тоже может стать причиной такой ошибки. Максимально доступный размер пакета можно увеличить с помощью параметра max_allowed_packet. Например:
sudo vi /etc/mysql/my.cnf
max_allowed_packet=128M
Обратите внимание, что если вы из своей программы отправляете большие пакеты, то, скорее всего, вы делаете что-то не так. Не надо генерировать запросы к MySQL с помощью циклов for. SQL — это отдельный язык программирования, который многое может сделать сам, без необходимости писать очень длинные запросы.
3. Сервер неверно проинициализирован
Такая проблема может возникать при разворачивании контейнера MySQL или MariaDB в Docker. Дело в том, что на первоначальную инициализацию контейнера нужно много времени: около нескольких минут. Если вы не дадите контейнеру завершить инициализацию, а остановите его и потом снова запустите, то база данных будет всегда возвращать такую ошибку.
Вам нужно полностью удалить данные контейнера с базой данных. Например, с помощью docker-compose:
docker-compose down
или вручную:
docker rm mysql-container
Здесь mysql-container — это имя контейнера с базой данных. А затем надо удалить хранилище (volume) с некорректно проинициализированной базой. Сначала посмотрите список всех хранилищ:
docker volume ls
Затем удалите нужное:
docker volume rm имя_хранилища
После этого можете снова запускать инициализацию приложения, только на этот раз дождитесь, пока сервер баз данных сообщит, что он готов, и вы сможете к нему подключиться.
Выводы
В этой небольшой статье мы рассмотрели, что значит ошибка MySQL Server has gone away, а также как её исправить на сервере или в контейнере Docker. Вы знаете ещё другие причины и решения этой проблемы? Пишите в комментариях!
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .
Об авторе
Основатель и администратор сайта losst.ru, увлекаюсь открытым программным обеспечением и операционной системой Linux. В качестве основной ОС сейчас использую Ubuntu. Кроме Linux, интересуюсь всем, что связано с информационными технологиями и современной наукой.
Рассмотрим, как исправить ошибку MySQL server has gone away (error 2006), которая появляется при обращении к сервису MySQL.
Наиболее распространение причины ошибки MySQL server has gone away:
- Слишком большой размер пакета в запросе к MySQL (по умолчанию максимальный размер — 16 Мб);
- Закончилась свободная оперативная память (RAM) на сервере MySQL (проверить свободную память в Linux можно с помощью команды free –h)
- Неактивное соединение между вашим приложением и MySQL (по умолчанию сессия разрывается через 8 часов).
Основатель и администратор сайта losst.ru, увлекаюсь открытым программным обеспечением и операционной системой Linux. В качестве основной ОС сейчас использую Ubuntu. Кроме Linux, интересуюсь всем, что связано с информационными технологиями и современной наукой.