Перейти к содержимому

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 -10
dmesg | grep -i "killed process" | tail -5
uptime # сервер базы недавно перезапускался?

Перезапуск базы выглядит для сайта точно так же. Если ошибка пришла один раз и у всех сразу, причину ищут в журнале сервера базы, а не в коде скрипта.

Ищем гигантские запросы в своём коде:

// вставка тысяч строк одним запросом упирается в предел размера пакета
foreach (array_chunk($rows, 200) as $chunk) {
// порции по двести строк проходят при любых разумных настройках
}
// то же касается длинных значений: описание товара на мегабайт в одном поле

Держим соединение живым в долгих скриптах:

// после долгой операции без запросов соединение может быть уже разорвано
$connection = \Bitrix\Main\Application::getConnection();
if (!$connection->isConnected()) {
$connection->connect(); // переподключение перед следующей записью
}

Долгие операции без обращений к базе - типичный случай обмена. Скрипт разбирает файл десять минут, потом пробует записать результат, а соединение уже закрыто по времени простоя.

Причины

  1. Запрос больше предела размера пакета примерно 35% случаев

    ПризнакОшибка приходит на вставке или обновлении больших объёмов данных, всегда в одном месте.

    ПроверкаСравниваем предел размера пакета с объёмом, который отправляет скрипт за один запрос.

    Что делатьРазбиваем запись на порции и поднимаем предел до разумного значения на стороне сервера базы.

  2. Долгая операция без обращений к базе примерно 25% случаев

    ПризнакПадает обмен, импорт или ночное задание, причём в середине работы, а не в начале.

    ПроверкаСмотрим время простоя соединения и продолжительность участка скрипта без запросов.

    Что делатьПереподключаемся перед записью после долгой паузы либо разбиваем работу на короткие шаги.

  3. Сервер базы перезапустился или был убит примерно 20% случаев

    ПризнакОшибка пришла разом на всём сайте и больше не повторяется до следующего раза.

    ПроверкаЧитаем журнал сервера базы и записи ядра об убитых процессах, смотрим время работы сервера.

    Что делатьРазбираем причину падения: нехватка памяти, перезапуск по расписанию, обновление пакета базы.

  4. Соединение разорвано посредником примерно 12% случаев

    ПризнакБаза вынесена на отдельный узел, ошибка приходит только на долгих запросах.

    ПроверкаПроверяем пределы времени жизни соединения на балансировщике и в сетевом оборудовании.

    Что делатьСогласуем пределы всех участников: сеть не должна рвать соединение раньше самой базы.

  5. Скрипт работает дольше, чем живёт его соединение примерно 8% случаев

    ПризнакОшибка только в консольных заданиях и агентах, в веб-запросах её нет вовсе.

    ПроверкаСравниваем время выполнения задания с временем простоя соединения в настройках базы.

    Что делатьПереподключаемся периодически внутри длинного цикла и не держим одно соединение часами.

Если ничего не помогло

Смотрим, где именно оборвалось выполнение. Сообщение приходит из слоя работы с базой, а виновата почти всегда конкретная операция: массовая вставка, длинное значение поля или пауза в несколько минут.

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

Разбиваем обмен на шаги. Пошаговый обмен с учётной системой не только обходит эту ошибку, но и делает всю выгрузку восстановимой: упавший шаг повторяется, а не запускается заново с самого начала.

Частые вопросы

Почему ошибка приходит только при обмене с 1С?

Обмен отправляет самые большие запросы и делает самые долгие паузы между ними. Он задевает оба предела - размер пакета и время простоя соединения - там, где обычные страницы даже близко к ним не подходят.

Насколько поднимать предел размера пакета?

До разумных десятков мегабайт, но вместе с разбиением записи на порции. Один только поднятый предел лечит симптом до следующего роста каталога, а порции работают при любом объёме.

Нужно ли переподключаться вручную в скриптах?

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

Как отличить перезапуск базы от ошибки в коде?

По журналу сервера базы и времени его работы: перезапуск виден там сразу. Если ошибка пришла разом на всех страницах и не повторяется, дело почти наверняка не в коде.

Помогает ли увеличение времени простоя соединения?

Помогает, но не бесплатно: висящие соединения занимают память и приближают предел их количества. Правильнее сокращать паузы в скрипте и переподключаться там, где пауза неизбежна.

Смежное

Первоисточник