Траблшутинг ошибки MySQL server has gone away: max_allowed_packet и wait_timeout
- Клиентские приложения получают исключение
SQLSTATE[HY000] [2006] MySQL server has gone away. - Разрыв соединений во время вставки больших объемов данных (BLOB, длинные дампы SQL).
- Фоновые воркеры (Celery, Laravel Queue, Cron) падают при попытке отправить запрос после простоя.
- В error.log фиксируются сообщения
Got an error reading communication packets.
1. Увеличение лимита размера сетевого пакета
Добавьте в /etc/mysql/my.cnf в секции [mysqld] и [mysqldump]:
[mysqld]
max_allowed_packet = 128M
net_buffer_length = 32K
[mysqldump]
max_allowed_packet = 128MПримените параметр динамически без перезагрузки:
SET GLOBAL max_allowed_packet = 134217728;2. Тюнинг таймаутов удержания соединений
Увеличьте время жизни неактивных соединений в my.cnf:
[mysqld]
# Таймаут простоя для неинтерактивных соединений (сек)
wait_timeout = 28800
# Таймаут простоя для интерактивных клиентов (mysql-cli)
interactive_timeout = 28800
# Таймауты чтения/записи сетевых сокетов
net_read_timeout = 120
net_write_timeout = 120SET GLOBAL wait_timeout = 28800;
SET GLOBAL interactive_timeout = 28800;3. Проверка сетевых сбросов TCP на уровне ядра Linux
sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.ipv4.tcp_keepalive_intvl=15
sysctl -w net.ipv4.tcp_keepalive_probes=5 Частые вопросы (FAQ)
Почему воркеры очередей регулярно получают ошибку 2006?
Воркер держит соединение к БД открытым в пуле, пока ждет задачи. Если время ожидания превышает wait_timeout, MySQL принудительно закрывает сокет. Решение — пинговать соединение перед выполнением запроса (auto-reconnect) или поднять wait_timeout.
Как отследить, какой именно запрос превысил max_allowed_packet?
Включите log_error_verbosity = 3 в MySQL 8.0 — сервер запишет подробную информацию об IP клиента, размере полученного пакета и прерванном соединении в системный error.log.