MySQL server has gone away - причины по убыванию частоты
Скрипт обрывается сообщением о потерянном соединении с базой. Разбираем причины в порядке убывания частоты.
Как проверить
Смотрим пределы соединения:
SHOW VARIABLES LIKE 'max_allowed_packet'; -- предел размера одного запросаSHOW VARIABLES LIKE 'wait_timeout'; -- сколько соединение живёт без запросовSHOW VARIABLES LIKE 'interactive_timeout';-- значения ниже мегабайта и меньше минуты почти гарантируют эту ошибкуДве настройки объясняют большинство случаев. Первая ограничивает размер одного запроса, вторая - время простоя соединения; обмен с учётной системой умудряется задеть обе сразу.
Смотрим, что происходило с сервером базы:
grep -iE "restart|shutdown|oom|killed" /var/log/mysql/error.log | tail -10dmesg | grep -i "killed process" | tail -5uptime # сервер базы недавно перезапускался?Перезапуск базы выглядит для сайта точно так же. Если ошибка пришла один раз и у всех сразу, причину ищут в журнале сервера базы, а не в коде скрипта.
Ищем гигантские запросы в своём коде:
// вставка тысяч строк одним запросом упирается в предел размера пакетаforeach (array_chunk($rows, 200) as $chunk) { // порции по двести строк проходят при любых разумных настройках}// то же касается длинных значений: описание товара на мегабайт в одном полеДержим соединение живым в долгих скриптах:
// после долгой операции без запросов соединение может быть уже разорвано$connection = \Bitrix\Main\Application::getConnection();if (!$connection->isConnected()) { $connection->connect(); // переподключение перед следующей записью}Долгие операции без обращений к базе - типичный случай обмена. Скрипт разбирает файл десять минут, потом пробует записать результат, а соединение уже закрыто по времени простоя.
Причины
-
Запрос больше предела размера пакета примерно 35% случаев
ПризнакОшибка приходит на вставке или обновлении больших объёмов данных, всегда в одном месте.
ПроверкаСравниваем предел размера пакета с объёмом, который отправляет скрипт за один запрос.
Что делатьРазбиваем запись на порции и поднимаем предел до разумного значения на стороне сервера базы.
-
Долгая операция без обращений к базе примерно 25% случаев
ПризнакПадает обмен, импорт или ночное задание, причём в середине работы, а не в начале.
ПроверкаСмотрим время простоя соединения и продолжительность участка скрипта без запросов.
Что делатьПереподключаемся перед записью после долгой паузы либо разбиваем работу на короткие шаги.
-
Сервер базы перезапустился или был убит примерно 20% случаев
ПризнакОшибка пришла разом на всём сайте и больше не повторяется до следующего раза.
ПроверкаЧитаем журнал сервера базы и записи ядра об убитых процессах, смотрим время работы сервера.
Что делатьРазбираем причину падения: нехватка памяти, перезапуск по расписанию, обновление пакета базы.
-
Соединение разорвано посредником примерно 12% случаев
ПризнакБаза вынесена на отдельный узел, ошибка приходит только на долгих запросах.
ПроверкаПроверяем пределы времени жизни соединения на балансировщике и в сетевом оборудовании.
Что делатьСогласуем пределы всех участников: сеть не должна рвать соединение раньше самой базы.
-
Скрипт работает дольше, чем живёт его соединение примерно 8% случаев
ПризнакОшибка только в консольных заданиях и агентах, в веб-запросах её нет вовсе.
ПроверкаСравниваем время выполнения задания с временем простоя соединения в настройках базы.
Что делатьПереподключаемся периодически внутри длинного цикла и не держим одно соединение часами.
Если ничего не помогло
Смотрим, где именно оборвалось выполнение. Сообщение приходит из слоя работы с базой, а виновата почти всегда конкретная операция: массовая вставка, длинное значение поля или пауза в несколько минут.
Проверяем настройки на всех участниках сразу. У консольного и веб-окружения бывают разные файлы настроек, и предел, поднятый в одном месте, никак не влияет на скрипт, который запускается из другого.
Разбиваем обмен на шаги. Пошаговый обмен с учётной системой не только обходит эту ошибку, но и делает всю выгрузку восстановимой: упавший шаг повторяется, а не запускается заново с самого начала.
Частые вопросы
Почему ошибка приходит только при обмене с 1С?
Обмен отправляет самые большие запросы и делает самые долгие паузы между ними. Он задевает оба предела - размер пакета и время простоя соединения - там, где обычные страницы даже близко к ним не подходят.
Насколько поднимать предел размера пакета?
До разумных десятков мегабайт, но вместе с разбиением записи на порции. Один только поднятый предел лечит симптом до следующего роста каталога, а порции работают при любом объёме.
Нужно ли переподключаться вручную в скриптах?
В долгих заданиях - да, перед записью после длинной паузы. В обычном веб-запросе такой необходимости нет: он завершается быстрее, чем истекает время простоя соединения.
Как отличить перезапуск базы от ошибки в коде?
По журналу сервера базы и времени его работы: перезапуск виден там сразу. Если ошибка пришла разом на всех страницах и не повторяется, дело почти наверняка не в коде.
Помогает ли увеличение времени простоя соединения?
Помогает, но не бесплатно: висящие соединения занимают память и приближают предел их количества. Правильнее сокращать паузы в скрипте и переподключаться там, где пауза неизбежна.
Смежное
- Ошибки сервера - оглавление подтемы
- MySQL Query Error: причины по убыванию частоты - соседняя ошибка на самом запросе
- Сайт не подключается к базе: причины по убыванию частоты - когда соединения нет вовсе
- Долгий обмен с 1С: шаг, порции, таймауты - пошаговый обмен вместо одного прохода
- Массовая правка товаров: обновление свойств скриптом - запись порциями вместо одного запроса
- Illegal mix of collations: разные кодировки таблиц и соединения - соседняя ошибка на сравнении строк
- Инфраструктура - устройство сервера и окружения