Ошибка MySQL 2006: Server has gone away означает следующее – клиентом потеряно соединение с сервером MySQL или MariaDB. Причина часто скрывается в большом SQL-запросе или в дампе. Иногда такое происходит из-за перезапуска самого сервера или же во время проблем с самой сетью.
Но данная ошибка сама по себе далеко не всегда означает критические проблемы, такие как повреждение базы данных или поломку MySQL. Чаще всего ситуация намного проще и выглядит так: соединение закрыто, а в это время приложение или клиент пытается продолжить с ним взаимодействие. Как результат отказа от этого взаимодействия и выступает ошибка MySQL 2006: Server has gone away.
Что означает ошибка 2006 и когда она возникает
В этой ситуации код 2006 соответствует клиентской ошибке CR_SERVER_GONE_ERROR — MySQL server has gone away. Ошибка появляется только в том случае, когда клиент не может отправить запрос через существующее соединение с сервером MySQL.
Родственная ошибка 2013 (Lost connection to MySQL server during query) возникает, когда соединение теряется непосредственно во время выполнения запрос. Если говорить о практических ситуациях, то можно выделить несколько распространенных случаев появления кода 2006:
в ходе импорта объемного SQL-дампа;
во время выполнения большого INSERT, особенно с большим количеством строк;
в PHP-приложении после долгого простоя соединения;
в CLI-клиенте MySQL;
при работе с большими BLOB или другими объемными данными;
после перезапуска или падения mysqld/mariadbd;
при нестабильном удаленном подключении к базе.
Сложность ситуации в том, что универсальной настройки не существует, которая могла бы закрыть разом все перечисленные проблемы. Поэтому действовать в одной ситуации нужно так – вы сначала определяете причину такого поведения, а уже после подбираете самый эффективный способ устранения проблемы. Ключевая задача на этом этапе – понять, в какой именно момент происходит разрыв соединения.
Причина 1 — истек тайм-аут соединения
Это, пожалуй, самая популярная причина, когда сервер просто закрывает неактивное соединение из-за wait_timeout. С помощью этой переменной устанавливается определенное количество секунд, которое MySQL готов ждать активности от обычного клиентского соединения, прежде чем закрыть его.
В интерактивных подключениях обычно применяется связанная настройка interactive_timeout. Значения устанавливаются глобально и для отдельных сессий. Так если приложением было установлено соединение с MySQL, выполнило запрос, а затем долго ничего не делало, появляется ошибка.
Бывает и так, что соединение остается открытым дольше положенного времени. В таком случае сервер руководствуется установленным правилом, и просто закрывает соединение, когда оно превышает лимит по времени. После закрытия соединения приложение попытается использовать его снова, но результатом этой попытки будет появление MySQL server has gone away.
Поэтому идём в настройки и проверяем:
SHOW VARIABLES LIKE '%timeout%';Более точечно:
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';В MySQL 8.4 "wait_timeout" является динамической переменной, её глобальное значение можно изменить без перезапуска:
SET GLOBAL wait_timeout = 28800;
SET GLOBAL interactive_timeout = 28800;Есть один нюанс: изменение GLOBAL не переписывает уже установленное значение в существующих сессиях. Новые соединения получат новое глобальное значение.
Для постоянного изменения параметр добавляют в конфигурацию сервера:
[mysqld]
wait_timeout = 28800
interactive_timeout = 28800После изменения конфигурации MySQL/MariaDB перезапустите сервис.
И тут важно не допускать элементарную ошибку – многие пользователи выставляют максимальное значение. Просто, не задумываясь. Так делать не нужно, поскольку приложение может неправильно управлять соединениями, а увеличенный тайм-аутов будет всего лишь маскировать проблему. Всё это приведет к накоплению долго живущих соединений.
Для решения этой проблемы уместно использовать виртуальный сервер. Вся прелесть ситуации заключается в возможность контролировать конфигурацию MySQL/MariaDB на VPS собственноручно: параметры сервера не зависят от ограничений виртуального хостинга.
Если нужно узнать, какие option files использует именно установленный MySQL, можно проверить:
mysqld --verbose --help 2>/dev/null | grep -A 1 "Default options"Для MariaDB:
mariadbd --verbose --help 2>/dev/null | grep -A 1 "Default options"Перейдем к следующей причине.
Причина 2 — превышен max_allowed_packet
Иногда происходит так, что пользователь пытается выполнить импорт дампа или объемного SQL-запроса. Именно в этот момент появляется ошибка. Если это ваш случай, то в первую очередь рекомендуем проверить max_allowed_packet.
Всё дело в том, что этот параметр ограничивает максимальный размер одного пакета данных, который MySQL способен обработать. Проблема особенно актуальна для:
больших SQL-дампов;
огромных "INSERT";
больших "BLOB";
длинных строк;
массовой вставки большого количества данных одним запросом.
После появления ошибки обязательно проверьте значение командой:
SHOW VARIABLES LIKE 'max_allowed_packet';В MySQL 8.4 переменная динамическая:
SET GLOBAL max_allowed_packet = 134217728;Где "134217728" байт — 128 MiB.
В MySQL большой пакет данных – одна из наиболее частых причин появления MySQL 2006: Server has gone away. Что делать в такой ситуации? Увеличить лимит? Как вариант – да, но обязательно учитывайте объем доступной памяти и размер запроса. Запрос должен в полной мере соответствовать этим двум значениям.
Важный момент – MySQL указывает, что клиент может иметь собственный лимит max_allowed_packet; например, CLI-клиент получает значение через параметр командной строки. Это тот момент, который нужно держать в голове, изменяя глобальное значение.
При импорте дампа используйте:
mysql --max-allowed-packet=128M -u USER -p DATABASE < dump.sqlВо время подключения к удаленному серверу:
mysql -h SERVER_IP --max-allowed-packet=128M -u USER -p DATABASE < dump.sqlВ конфигурации сервера параметр задается в секции [mysqld]:
[mysqld]max_allowed_packet = 128MЧасто пользователи задаются вопросом – “какое значение лучше поставить?”. Универсальной рекомендации тут нет. Ориентируйтесь на конкретно вашу ситуацию. Например, в ваш дамп уместились запросы на 50 МБ, тогда лимит нужно выставить выше этого значения – 60 МБ. Просто ставите лимит выше дампа, но не устанавливаете максимальное значение.
Ошибочно считать, что max_allowed_packet – бесплатная настройка. Чересчур агрессивные значения при большом количестве одновременных подключений к росту потребления памяти. Что касается MariaDB, то здесь max_allowed_packet является динамической глобальной переменной, а максимальное значение – 1 GB. При изменении серверного значения MariaDB рекомендует учитывать значение на стороне клиента.
Причина 3 — процесс MySQL/MariaDB упал или был перезапущен
Если сервер прекратил работу, что привело к падению процесса MySQL/MariaDB, тоже появится ошибка MySQL 2006: Server has gone away. И вот тут нужно тщательно разбираться в причинах такого поведения. Обычно это:
нехватка ОЗУ;
OOM killer Linux;
ошибка самого сервера;
повреждение или проблема с конкретным запросом;
ручной перезапуск;
обновление пакетов;
аварийное завершение процесса.
Нет смысла проверять wait_timeout или max_allowed_packet. Первое, что вам нужно сделать в этой ситуации – убедиться, что сервер не падал. Когда сервер падает, старое соединение становится недействительным. Клиент, продолжающий его использовать для установки соединения, будет получать ошибку 2006.
В systemd посмотрите журнал:
sudo journalctl -u mysql --since "1 hour ago"В MariaDB:
sudo journalctl -u mariadb --since "1 hour ago"Проверяем сообщения ядра, связанные с нехваткой памяти:
sudo dmesg -T | grep -i -E 'oom|out of memory|killed process'Или:
sudo journalctl -k | grep -i -E 'oom|out of memory|killed process'Не будет лишним посмотреть error log MySQL/MariaDB. Многим удается найти причину именно здесь. Так mysqld из-за нехватки памяти просто падает, увеличивая max_allowed_packet, проблема не решается, более того – усугубляется. Сам корень проблемы не в одном параметре, а в недостатке ресурсов под текущую нагрузку.
Для виртуального сервера это важный момент: если серверу постоянно не хватает RAM, логичнее рассматривать тариф с большим объёмом оперативной памяти, чем бесконечно корректировать отдельные параметры MySQL.
Причина 4 — обрыв сети или ограничения инфраструктуры
Во время подключения к базе данных с другого сервера вы рискуете увидеть сообщение MySQL 2006: Server has gone away.
Особенно это актуально для архитектуры вида:
Приложение – интернет – firewall – VPS – MySQL
В этой ситуации MySQL работает нормально, но один из промежуточных компонентов закрывает простаивающее TCP-соединение. Соединение с БД просто может быть прервано одним из следующих участников:
firewall;
NAT;
сетевой сбой;
нестабильное удалённое подключение;
проблемы с DNS;
клиентские read/write timeout.
В документации MySQL отдельно упоминается TCP/IP timeout и сетевые проблемы среди возможных причин потери соединения. Когда база находится на другом сервере, полезно проверить подключение непосредственно с машины приложения:
mysql -h SERVER_IP -u USER -pСоединение периодически пропадает даже при небольших запросах? Увеличение max_allowed_packet не поможет — нужно искать проблему на сетевом уровне.
Как быстро определить, какая причина у вас
Симптом | Вероятная причина | Что проверить |
Ошибка появляется после долгого просто | wait_timeout / interactive_timeout | SHOW VARIABLES LIKE '%timeout%'; |
Ошибка возникает только на большом дампе | max_allowed_packet | Размер дампа, отдельного SQL-запроса и текущий лимит |
Ошибка появляется на большом INSERT | Слишком большой пакет | max_allowed_packet, размер запроса |
MySQL внезапно перестал отвечать | Падение/перезапуск сервер | journalctl, error log, uptime |
Сервер перезапускается при нагрузке | Нехватка RAM/OOM | dmesg, journalctl -k, мониторинг RAM |
Ошибка только при удаленном подключении | Сеть/firewall | TCP-соединение, firewall |
После повторного подключения всё работает | Разрыв старой сессии | Тайм-ауты и reconnect-логика |
Ошибка возникает постоянно на одном запрос | Проблемный/слишком большой запрос | Логи и размер SQL-запроса |
Не лишним будет проверить время работы самого MySQL:
SHOW GLOBAL STATUS LIKE 'Uptime';Если Uptime неожиданно маленький, сервер недавно перезапускался.
Как предотвратить ошибку в будущем
Универсальной методики нет, в случае появления ошибки нужно разбираться в конкретной ситуации. Но есть простые, однако очень эффективные рекомендации, воспользуйтесь ими, чтобы в будущем снизить риски или полностью исключить вероятность появления MySQL 2006: Server has gone away.
Добавить нормальную реконнект-логику
Приложение не должно считать открытое соединение вечным. После длительного простоя соединение могло быть закрыто сервером или инфраструктурой. В зависимости от используемого драйвера приложение должно уметь обнаружить разрыв и корректно установить новое соединение. MySQL также рекомендует проверять соединение, например через mysql_ping(), если между запросами проходит длительное время.
Контролировать оперативную память
Если MySQL регулярно перезапускается, сначала ищите причину в логах и состоянии RAM. Особенно важно следить за памятью при одновременном использовании:
большого InnoDB buffer pool;
большого количества соединений;
тяжелых запросов;
временных таблиц;
крупных импортов.
Не завышать max_allowed_packet
Увеличивать параметр нужно под конкретную задачу. Если проблема возникает при импорте дампа, сначала определите размер самых больших запросов. После этого установите разумный запас. 1 GB не является автоматически лучшим значением. Чем выше лимит, тем больше потенциальный объём памяти, который может потребоваться для обработки крупных пакетов. Настройку нужно рассматривать как компромисс между требованиями приложения и доступными ресурсами.
Не увеличивать тайм-ауты без необходимости
Если приложение держит соединения открытыми часами, увеличение wait_timeout может замаскировать проблему управления подключениями. Лучше настроить приложение так, чтобы оно:
закрывало ненужные соединения;
использовало connection pooling там, где это уместно;
корректно восстанавливало соединение;
не выполняло огромные операции одним запросом без необходимости.
Заключение
MySQL 2006 Server has gone away не равно поломка базы данных сломалась. В большинстве случаев это следствие конкретного события: сервер закрыл неактивное соединение, запрос оказался слишком большим, MySQL перезапустился либо соединение было потеряно по сети. В таких ситуациях нужно действовать точечно, сперва определяя причину проблемы, а уже после – работать над её устранением.
Оптимальный порядок диагностики выглядит так:
Определить момент ошибки.
Проверить тайм-ауты.
Проверить max_allowed_packet.
Посмотреть, не перезапускался ли MySQL.
Проверить RAM и OOM.
Проверить сеть.
Если выяснилось, что ошибка возникает из-за постоянной нехватки RAM под текущую базу и нагрузку, стоит рассмотреть VPS с большим объемом ресурсов. На виртуальном сервере от Leneex можно самостоятельно управлять конфигурацией MySQL/MariaDB и адаптировать параметры сервера под конкретное приложение, без типичных ограничений виртуального хостинга.







