Выберите продукт

MySQL: Got an error reading communication packets — причины, MTU и max_allowed_packet

Ошибка MySQL Got an error reading communication packets обычно связана с сетью, таймаутами или крупными пакетами. В статье — быстрый triage, проверка MTU/PMTUD и потерь, настройка max_allowed_packet, net_read_timeout и net_write_timeout, а также согласование wait_timeout с пулом и прокси.
MySQL: Got an error reading communication packets — причины, MTU и max_allowed_packet

Что означает “Got an error reading communication packets”

Сообщение Got an error reading communication packets появляется в логах MySQL/MariaDB, когда сервер ожидал данные от клиента по TCP-соединению, но чтение оборвалось: клиент закрыл соединение, сеть потеряла пакеты, промежуточный NAT/прокси «срезал» сессию по таймауту или сервер не дождался следующего фрагмента запроса/ответа.

Это не «ошибка SQL» в привычном смысле. Это симптом проблем на уровне транспорта (TCP) или параметров протокола (размеры пакетов и таймауты), поэтому лечится диагностикой «от сети к MySQL», а не наоборот.

Если ошибка всплывает на больших SELECT/INSERT/backup/репликации — в первую очередь проверяйте max_allowed_packet и net_read_timeout/net_write_timeout. Если она хаотичная и «плавает» по времени — чаще виноваты MTU/PMTUD, потери, NAT или proxy timeout.

Типовые сценарии, где встречается ошибка

Чаще всего вы попадёте в один из сценариев ниже.

  • Большие запросы/строки (BLOB/TEXT), дампы, миграции, репликация: упираетесь в max_allowed_packet или в таймауты чтения/записи.
  • «Долгий» запрос, а по пути стоит балансировщик/прокси/NAT, который рвёт idle-соединение: классический proxy timeout.
  • Проблемы канала: packet loss, нестабильный VPN/туннель, «чёрная дыра» PMTUD (Path MTU Discovery), несовпадение MTU.
  • Драйвер/пул соединений не синхронизирован с серверными таймаутами или агрессивно закрывает коннекты при рестартах приложений.

Если база крутится на отдельном сервере и соединений много, часто проще начинать диагностику на выделенной машине: на VDS удобнее изолировать сетевые эффекты, логи и метрики, чем на «общем» окружении.

Быстрая triage-проверка: что собрать за 10 минут

1) Смотрим, кто рвёт соединение и при каких условиях

На сервере БД полезно начать со статусов: они покажут, «отваливаются» ли клиенты и на каком этапе.

mysql -e "SHOW GLOBAL STATUS LIKE 'Aborted_%';"
mysql -e "SHOW GLOBAL STATUS LIKE 'Connections';"
mysql -e "SHOW GLOBAL STATUS LIKE 'Bytes_%';"

Подсказки по интерпретации:

  • Aborted_clients растёт — сессии часто обрываются уже после установления соединения.
  • Aborted_connects растёт — проблемы на рукопожатии/аутентификации/доступе, либо «дропы» в сети на старте.

Дальше сразу снимите значения ключевых переменных:

mysql -e "SHOW GLOBAL VARIABLES WHERE Variable_name IN ('max_allowed_packet','net_read_timeout','net_write_timeout','wait_timeout','interactive_timeout');"

2) Проверяем, нет ли явных TCP-потерь/ретрансмиссий

Если приложение и MySQL на разных узлах, проверьте обе стороны. Начните с быстрых индикаторов TCP:

ss -ti dst :3306
netstat -s | egrep -i "retrans|timeout|listen|reset" | head

Если видите заметные ретрансмиссии, RTO, сбросы (RST) — сначала приводим в порядок сеть/туннель/виртуализацию. Настройками MySQL можно «смягчить» симптомы, но первопричину это не вылечит.

Проверка Aborted_clients, Aborted_connects и ключевых переменных MySQL в терминале

max_allowed_packet: почему его связывают с communication packets

max_allowed_packet ограничивает максимальный размер одного пакета в протоколе MySQL. На практике это проявляется так: большие INSERT (многострочные VALUES), BLOB/TEXT, длинные JSON, дампы с --hex-blob, репликация или восстановление формируют пакет, который превышает лимит на сервере или на клиенте.

Иногда при превышении вы увидите прямую ошибку «packet too large», но при нестабильной сети, прокси или дополнительных таймаутах цепочка выглядит иначе: отправка/чтение затягивается, возникают ретрансмиссии, и в логах «всплывает» именно Got an error reading communication packets.

Как проверить текущие лимиты

mysql -e "SHOW VARIABLES LIKE 'max_allowed_packet';"

Проверьте и клиентскую сторону: у CLI и утилит лимит может быть меньше, чем на сервере.

mysql --max_allowed_packet=256M -e "SELECT 1;"
mysqldump --max_allowed_packet=256M --single-transaction --quick dbname > dump.sql

Как безопасно увеличить max_allowed_packet

Если у вас реально большие payload, увеличение — нормальная практика. Но помните: слишком большой лимит повышает верхнюю границу потребления памяти на соединение в неблагоприятных сценариях.

Временно (до перезапуска, удобно для диагностики):

mysql -e "SET GLOBAL max_allowed_packet = 268435456;"

Постоянно (MySQL, Debian/Ubuntu-подобные пути):

cat >> /etc/mysql/mysql.conf.d/mysqld.cnf <<'EOF'
[mysqld]
max_allowed_packet = 256M
EOF

Постоянно (MariaDB, путь может отличаться):

cat >> /etc/mysql/mariadb.conf.d/50-server.cnf <<'EOF'
[mysqld]
max_allowed_packet = 256M
EOF

Применение:

systemctl restart mysql

Чтобы не упираться в ограничения «общего» окружения по ресурсам, MySQL под большие пакеты и миграции чаще комфортнее держать на отдельной VDS с предсказуемой сетью и диском.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Таймауты MySQL: net_read_timeout, net_write_timeout, wait_timeout

Когда запрос или ответ большой, данные идут частями. Если сеть «подвисла» или приложение долго не читает сокет, срабатывают таймауты — и вы получаете обрыв на чтении/записи, который затем выглядит как communication packets.

net_read_timeout

net_read_timeout — сколько секунд сервер ждёт следующую порцию данных от клиента. Имеет смысл увеличивать, если клиент отправляет большой запрос медленно (потери, VPN, перегруженное приложение, медленный аплоад).

mysql -e "SHOW VARIABLES LIKE 'net_read_timeout';"
mysql -e "SET GLOBAL net_read_timeout = 120;"

net_write_timeout

net_write_timeout — сколько секунд сервер ждёт, пока клиент прочитает отправляемые данные. Важен при больших SELECT/экспортах, когда клиент читает медленно или промежуточный прокси буферизует трафик.

mysql -e "SHOW VARIABLES LIKE 'net_write_timeout';"
mysql -e "SET GLOBAL net_write_timeout = 300;"

wait_timeout и interactive_timeout

wait_timeout — сколько сервер держит неактивное соединение, прежде чем закрыть. На фоне пулов соединений и прокси это критично: приложение может попытаться использовать «простаявший» коннект, который уже закрыт сервером или сетевым устройством.

mysql -e "SHOW VARIABLES LIKE 'wait_timeout';"
mysql -e "SHOW VARIABLES LIKE 'interactive_timeout';"

Чтобы не ловить «призрачные» обрывы, согласуйте между собой три слоя:

  • idle/max lifetime в пуле соединений приложения;
  • wait_timeout на сервере;
  • таймауты NAT/прокси/балансировщика на TCP.

Если вы используете репликацию/фейловер, полезно держать под рукой отдельный разбор сетевых «хвостов» при переключениях: GTID, semi-sync и фейловер MySQL: как избежать сюрпризов.

MTU issues и PMTUD: скрытая причина обрывов MySQL

MTU-проблемы особенно неприятны тем, что проявляются «не всегда»: мелкие пакеты ходят, а большие периодически «исчезают». Типовой кейс: между клиентом и сервером есть VPN, GRE, PPPoE, overlay-сеть контейнеров, либо где-то режется ICMP. В итоге PMTUD не работает, крупные TCP-сегменты попадают в «чёрную дыру», растут ретрансмиссии и задержки, а MySQL упирается в net_read_timeout/net_write_timeout и логирует ошибки про communication packets.

Как быстро проверить MTU до хоста (IPv4)

С клиента до сервера БД подберите максимальный размер без фрагментации:

ping -M do -s 1472 -c 3 DB_HOST
ping -M do -s 1464 -c 3 DB_HOST

1472 — это 1500 MTU минус 20 байт IPv4 header и 8 байт ICMP. Если не проходит, уменьшайте размер, пока не начнёт проходить стабильно. Дальше уже разбирайтесь, где именно в пути MTU меньше ожидаемого.

Что делать, если MTU реально меньше 1500

Дальнейшие действия зависят от инфраструктуры, но логика всегда одна: либо сделать MTU «честным» на интерфейсах, либо обеспечить корректную работу PMTUD.

  • Выставьте корректный MTU на интерфейсах туннеля/оверлея и на хостах, чтобы избежать «чёрной дыры».
  • Если ICMP фильтруется, разрешите сообщения, необходимые для PMTUD (иначе крупные пакеты будут теряться без явных ошибок).
  • Как временная мера на границе — используйте TCP MSS clamping, чтобы большие сегменты не уходили в «провал».

Если трафик идёт через VPN, часто помогает правильный keepalive и параметры туннеля, чтобы NAT/маршрутизаторы не «забывали» состояние: WireGuard roaming и keepalive: как избежать отвалов.

Для прод-окружений, где вы реально заботитесь о целостности канала и шифровании на периметре, проверьте, что сертификаты выпускаются и обновляются без «ручного героизма»: SSL-сертификаты полезны, если нужно стандартизировать TLS для сервисов и админ-панелей.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Тест MTU и диагностика PMTUD с помощью ping без фрагментации

Packet loss: как отличить потери от “просто таймаута”

Потери пакетов часто выглядят как «то работает, то нет»: часть запросов проходит, часть падает на чтении/записи. Особенно заметно на длительных выгрузках, миграциях и восстановлении из дампов.

Минимальный набор проверок:

mtr -rwz -c 200 DB_HOST
ss -ti dst DB_HOST:3306

В ss -ti смотрите на ретрансмиссии, RTO и общее поведение TCP. Если потери подтверждаются — чините сеть (линк, перегруз, виртуализацию, туннель, conntrack/NAT), а уже потом «полируйте» MySQL-таймауты.

Прокси и балансировщики: proxy timeout как причина обрывов

Если между приложением и MySQL стоит устройство или сервис, который может закрыть TCP-сессию (L4 LB, NAT gateway, sidecar proxy, SQL-proxy), появляется отдельный класс проблем: соединение рвётся «по правилам» промежуточного слоя, а MySQL пишет про communication packets.

Признаки обычно повторяемые:

  • обрывы происходят примерно через фиксированный интервал простоя (60/300/900 секунд);
  • короткие запросы всегда успешны, а длинные выгрузки падают ближе к одному и тому же времени;
  • при прямом подключении (минуя прокси) проблема исчезает.

Решение — согласование таймаутов. Практическая цель: приложение должно либо обновлять соединение раньше, чем его закроет прокси/NAT, либо прокси должен держать MySQL-трафик достаточно долго. А wait_timeout на сервере не должен неожиданно «отстреливать» коннекты из пула.

Рекомендуемая последовательность действий (runbook)

  1. Зафиксируйте контекст: какой запрос/операция выполнялась, примерный размер данных, через какие хосты/прокси идёт трафик.

  2. Проверьте max_allowed_packet на сервере и на клиенте. Если есть большие операции — увеличьте до разумного (часто 128M–512M) и повторите.

  3. Для миграций/бэкапов поднимите net_read_timeout и net_write_timeout, особенно если канал не идеальный.

  4. Проверьте MTU/PMTUD через ping -M do. При симптомах «чёрной дыры» чините MTU/ICMP/туннель, а не MySQL.

  5. Подтвердите или исключите потери: mtr, TCP ретрансмиссии, счётчики интерфейса (ip -s link, ethtool -S где доступно).

  6. Сверьте таймауты всех промежуточных устройств с wait_timeout и политикой пула соединений приложения.

Набор «разумных» настроек для типичного прод-сервера

Универсальных значений нет, но как стартовая база для многих веб-проектов (API/админка/фоновые задачи) часто подходят такие диапазоны:

  • max_allowed_packet 128M–256M, если бывают большие payload.
  • net_read_timeout 60–120, если бывают длинные отправки.
  • net_write_timeout 120–300, если бывают длинные выгрузки.
  • wait_timeout согласовать с пулом соединений и прокси; часто это 60–600, но зависит от архитектуры.

Не «раздувайте» таймауты до бесконечности: это может скрыть реальные проблемы (например, потери) и привести к накоплению зависших соединений. Лучше сначала стабилизировать сеть и цепочку прокси, а затем выставить таймауты под ваши реальные операции (бэкапы, миграции, репликация, большие выборки).

Частые ошибки при исправлении

  • Увеличили только серверный max_allowed_packet, забыв про клиентский (mysqldump/драйвер) — проблема осталась.

  • Подняли wait_timeout, но прокси/NAT всё равно режет соединение раньше — обрывы продолжаются.

  • Игнорируют MTU issues и лечат таймаутами — становится «реже», но не исчезает, а миграции всё равно валятся.

  • Диагностируют только MySQL и не смотрят TCP ретрансмиссии — теряется главный сигнал о packet loss.

Чек-лист: что указать, если идёте в поддержку/к провайдеру

Чтобы проблему быстрее локализовали (особенно если подозрение на сеть), заранее соберите:

  • время инцидента, IP/хосты клиента и сервера;
  • значения max_allowed_packet, net_read_timeout, net_write_timeout, wait_timeout (вывод SHOW GLOBAL VARIABLES);
  • динамику Aborted_clients/Aborted_connects до и после (вывод SHOW GLOBAL STATUS);
  • результаты mtr -rwz -c 200 и тест MTU (ping -M do);
  • описание всех прокси/балансировщиков/NAT по пути и их таймаутов (если известны).

Итоги

Got an error reading communication packets — «зонтичный» симптом. В одних проектах он лечится просто: синхронизировали max_allowed_packet и аккуратно подняли net_read_timeout/net_write_timeout. В других — это индикатор сетевой проблемы: MTU/PMTUD, packet loss или немой разрыв из-за proxy timeout.

Оптимальная стратегия — идти по слоям: подтвердить или исключить MTU и потери, затем выровнять таймауты прокси/приложения/MySQL, и только после этого фиксировать значения переменных под ваши операции (бэкапы, миграции, репликация, большие выборки).

Поделиться статьей

Вам будет интересно

ACME renewal monitoring: systemd timer, healthcheck и правильный fullchain.pem OpenAI Статья написана AI (GPT 5)

ACME renewal monitoring: systemd timer, healthcheck и правильный fullchain.pem

Разберём практичную схему мониторинга продления ACME/Let’s Encrypt: почему systemd timer удобнее cron, как правильно использовать ...
EPP-статусы домена: ok, clientHold и serverHold — что означают и как снять блокировку OpenAI Статья написана AI (GPT 5)

EPP-статусы домена: ok, clientHold и serverHold — что означают и как снять блокировку

Если домен зарегистрирован и NS прописаны, но сайт и почта не работают, часто виноваты EPP-статусы в WHOIS/RDAP. Разберём ok, clie ...
Kubernetes NodeLocal DNSCache: как победить DNS latency и NXDOMAIN storm в CoreDNS OpenAI Статья написана AI (GPT 5)

Kubernetes NodeLocal DNSCache: как победить DNS latency и NXDOMAIN storm в CoreDNS

DNS в Kubernetes часто становится скрытым узким местом: растёт latency, CoreDNS уходит в CPU, на нодах раздувается conntrack и всп ...