Хостинг от Ukr SKY
личный кабинет
служба поддержки
UA
Menu
СЛУЖБА ПОДДЕРЖКИ

MySQL server has gone away в WordPress и WooCommerce: как найти причину и исправить ошибку

Читать 29 мин.
16.08.2026

Ошибка MySQL server has gone away означает, что WordPress или WooCommerce попытался продолжить работу с соединением MySQL, которого к этому моменту уже не было. Но сама строка не объясняет, почему соединение исчезло. MySQL мог закрыть его по таймауту, разорвать соединение из-за слишком большого пакета, перезапуститься, попасть под OOM Killer или потерять связь с PHP во время долгой операции.

Поэтому совет просто увеличить max_allowed_packet или wait_timeout иногда действительно убирает ошибку, но такой результат ещё не доказывает причину. Если mysqld был завершён из-за нехватки RAM, изменение таймаута вообще не относится к проблеме. Если ошибка возникает только во время ночной синхронизации WooCommerce, открытие главной страницы магазина тоже ничего не проверяет.


Первое, что нужно зафиксировать, — время сбоя и операцию, которая выполнялась в этот момент. После этого сопоставляют WordPress, PHP-FPM, MySQL и системные журналы. Часто уже здесь становится понятно, куда копать.

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

Что на самом деле означает MySQL server has gone away в WordPress

MySQL server has gone away означает потерю уже установленного соединения между PHP и MySQL. WordPress дошёл до очередного обращения к базе и обнаружил, что продолжить обмен данными через прежнее соединение уже нельзя.

В журнале WordPress сообщение может выглядеть примерно так:

WordPress database error MySQL server has gone away for query ...

Рядом могут встречаться wpdb, mysqli, SQL-запрос и путь к файлу плагина. Но файл плагина в stack trace ещё не доказывает, что расширение разорвало соединение. Плагин мог просто первым обратиться к базе после того, как mysqld уже исчез.

У MySQL есть два близких сообщения. Error 2006 обычно выглядит как MySQL server has gone away, а Error 2013 — как Lost connection to MySQL server during query. При 2013 особенно полезно смотреть, что происходило непосредственно во время запроса: сколько он выполнялся, оставался ли MySQL жив, не было ли рестарта и не находится ли база на другом сервере. Но один код ошибки всё равно не заменяет журнал сервера.

Для WordPress и WooCommerce удобно сразу разделить несколько сценариев:

  • MySQL закрыл простаивающее соединение по wait_timeout;
  • операция превысила допустимый размер пакета;
  • mysqld аварийно завершился или был перезапущен;
  • Linux завершил mysqld из-за нехватки памяти;
  • долгий cron, импорт или WooCommerce job попытался использовать соединение после большой паузы;
  • нагрузка привела к OOM, аварийному рестарту или другому обрыву соединения;
  • WordPress использует удалённую БД, и соединение потерялось между web-сервером и MySQL.

Последний SQL-запрос в WordPress log не обязательно виноват. Иногда он просто первым обнаружил уже мёртвое соединение.

Ошибка 2006 также не означает автоматически повреждение таблиц. Если MySQL log не показывает corruption или ошибки таблиц, запускать repair только из-за server has gone away нет оснований.

Как за 10 минут определить, почему WordPress потерял соединение с MySQL

Если mysqld перезапустился в ту же минуту, когда WordPress записал ошибку, wait_timeout пока можно отложить. Поэтому первые проверки — доступность MySQL, uptime процесса и системный журнал.

Запишите точное время ошибки, URL или фоновую операцию и её повторяемость. Для WooCommerce отдельно отметьте импорт товаров, синхронизацию остатков, генерацию фида, Scheduled Actions, cron и внешние интеграции.

Проверьте, отвечает ли MySQL сейчас:

mysqladmin ping

Типичный ответ:

mysqld is alive

Он говорит только о текущем состоянии. MySQL может отвечать сейчас и при этом перезапускаться пять минут назад.

Проверьте сервис:

systemctl status mysql

Для MariaDB:

systemctl status mariadb

Теперь журнал за небольшой временной интервал:

journalctl -u mysql --since "30 minutes ago"

или:

journalctl -u mariadb --since "30 minutes ago"

Если WordPress зарегистрировал database error в 14:32, ищите события MySQL вокруг 14:32. Многомегабайтный журнал за неделю здесь только мешает.

Отдельно проверьте OOM:

journalctl -k | grep -Ei 'oom|out of memory|killed process'

Если kernel journal через journalctl недоступен:

dmesg -T | grep -Ei 'oom|out of memory|killed process'
Симптом Что проверять первым Почему Что пока не менять
Ошибка только на большом SQL-импорте max_allowed_packet и размер операции Сбой привязан к крупной передаче данных wait_timeout без проверки
Ошибка после долгой паузы внутри одного PHP-процесса wait_timeout MySQL мог закрыть idle connection max_connections
Одновременно потеряли БД несколько сайтов Uptime MySQL, systemd, OOM Проблема одного WordPress-плагина менее вероятна Массовое отключение расширений
Ошибка только в WooCommerce Scheduled Action Конкретная задача, PHP log, MySQL log Фронтенд может продолжать работать Глобальные лимиты наугад
В kernel journal есть Killed process ... mysqld RAM, swap, PHP-FPM и нагрузка MySQL Соединение исчезло после завершения процесса Таймауты соединения

После этих проверок должна появиться рабочая гипотеза: restart, OOM, большой пакет, длительный простой соединения, конкретная фоновая задача или перегрузка. Дальше проверяется именно эта ветка.

Как проверить, не перезапускался ли MySQL или MariaDB

Если несколько WordPress-сайтов почти одновременно потеряли БД и затем сами восстановились, сначала проверяйте MySQL. При рестарте обрываются все активные соединения, поэтому независимые сайты могут получить одинаковый Error 2006.

Количество секунд с запуска текущего процесса показывает Uptime:

SHOW GLOBAL STATUS LIKE 'Uptime';

Из shell:

mysql -e "SHOW GLOBAL STATUS LIKE 'Uptime';"

Сам VPS работает месяц, а MySQL uptime составляет 240 секунд? Значит, текущий mysqld появился несколько минут назад. Это уже конкретный след.

Теперь смотрите systemd:

systemctl status mysql
journalctl -u mysql --since "2 hours ago"

Для MariaDB:

systemctl status mariadb
journalctl -u mariadb --since "2 hours ago"

Ищите остановку процесса, signal, failed state, новый запуск, сообщения InnoDB при старте и повторные попытки systemd поднять сервис.

Условная последовательность может выглядеть так:

mysql.service: Main process exited
mysql.service: Failed with result 'signal'
Starting MySQL...
... ready for connections

Формулировки зависят от MySQL, MariaDB, версии и дистрибутива. Смысл один: старый процесс завершился, затем был создан новый.

Расположение отдельного error log лучше не угадывать. Проверьте фактическую настройку:

SHOW VARIABLES LIKE 'log_error';

На одном сервере получится путь к файлу, на другом основная информация окажется в journald. Работайте с тем, что реально настроено.

Есть restart — ищем причину restart. Таймауты пока не трогаем.

Причины рестарта уже могут быть разными: OOM, crash, ручной systemctl restart, обновление пакета, перезагрузка VPS. Поэтому новый uptime — сильная улика, но не финальный диагноз.

Может ли MySQL server has gone away возникать из-за нехватки RAM на VPS

Да. Когда VPS исчерпывает доступную память, Linux может завершить mysqld, PHP-FPM или другой крупный процесс. Для WordPress картина простая: соединение существовало, затем сервер базы исчез, и очередной запрос получил Error 2006.

Текущее состояние памяти:

free -h
swapon --show

Но здесь легко ошибиться. После того как OOM Killer завершил крупный процесс, часть RAM освобождается. Через минуту free -h может выглядеть совершенно нормально.

Поэтому проверяйте историю:

journalctl -k | grep -Ei 'oom|out of memory|killed process'

Характерный след по смыслу выглядит примерно так:

Out of memory
Killed process ... (mysqld)

Представим обычную ситуацию: в 03:12 WooCommerce пишет database error, через несколько секунд kernel journal показывает завершение mysqld, а утром free -h снова показывает свободную память. Здесь первым делом разбирать wait_timeout бессмысленно. Соединение исчезло потому, что исчез сам процесс базы.

Посмотрите текущих потребителей RAM:

ps aux --sort=-%mem | head

На WordPress VPS память делят MySQL, PHP-FPM, веб-сервер, Redis при его наличии и системные процессы. WooCommerce добавляет импорты, очереди, cron и интеграции. Поэтому опасно настраивать MySQL так, будто вся RAM принадлежит только ему.

Например, увеличение MySQL buffers может дать базе больше кеша, но если PHP-FPM уже держит много workers и запаса памяти почти нет, общий риск OOM вырастет. Обратная ситуация — слишком высокий pm.max_children, когда PHP одновременно запускает больше тяжёлых процессов, чем выдерживает VPS.

Признак OOM Обычный restart MySQL
Killed process ... mysqld в kernel journal Сильное подтверждение Обычно отсутствует
Новый MySQL uptime Возможен после автоматического запуска Да
После сбоя снова много свободной RAM Вполне возможно Тоже возможно
Ошибка совпала со всплеском PHP/WooCommerce jobs Подозрение усиливается Нужен системный журнал

Swap помогает пережить отдельный пик, но не заменяет нормальный запас RAM. Если сервер постоянно активно использует swap, диск начинает захлёбываться, растут задержки PHP и MySQL, а одна проблема превращается в другую.

Когда виноват max_allowed_packet

max_allowed_packet стоит подозревать, когда MySQL server has gone away воспроизводится именно на большой операции: SQL-импорте, миграции, крупном INSERT, сохранении большого JSON или serialized-значения, резервном копировании или пакетном обновлении данных. Для случайных падений всего сайта без связи с размером операции этот параметр выглядит намного слабее.

Что ограничивает max_allowed_packet

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

В WordPress это встречается не только при ручном импорте дампа. Плагин миграции может сформировать огромный SQL-запрос, интеграция — сохранить крупный payload, а WooCommerce-расширение — отправить большую порцию метаданных за одну операцию.

В журнале или сообщении клиента может появиться фрагмент по смыслу:

Got a packet bigger than 'max_allowed_packet' bytes

Если маленький импорт проходит, большой стабильно падает, MySQL uptime не меняется, OOM отсутствует и журнал указывает на размер пакета — гипотеза уже подтверждается несколькими независимыми признаками.

Как проверить текущее значение

SHOW VARIABLES LIKE 'max_allowed_packet';

Из shell:

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

Смотрите фактическое runtime-значение, а не только строку в my.cnf. Конфигурация может состоять из нескольких файлов, include-директорий и переопределений.

Как не перепутать MySQL packet с лимитами PHP и импортера

Фраза «большой импорт падает» ещё не означает max_allowed_packet. Файл может упереться в лимит PHP, веб-сервера, phpMyAdmin или самого плагина ещё до того, как проблемные данные дойдут до MySQL.

Если PHP сообщает о превышении upload или POST limit — это другая ветка. Если MySQL-клиент или серверный журнал указывает на packet — тогда проверяем max_allowed_packet.

Карточки товаров сохраняются нормально, импорт небольшой выборки проходит, но большой дамп стабильно рвётся примерно на одной операции. MySQL не рестартует, OOM нет. Именно в такой ситуации пакетный лимит выглядит логично, а не как случайная настройка из поисковой выдачи.

Что делать после изменения

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

После изменения снова выполните:

SHOW VARIABLES LIKE 'max_allowed_packet';

И повторите именно тот большой импорт, который раньше падал. Если после увеличения packet обычная главная страница открывается, это ничего не доказывает — она и раньше могла работать.

Не ставьте огромное значение просто «с запасом». Сначала докажите, что соединение действительно рвётся на операции, связанной с размером пакета.

Когда проблема связана с wait_timeout и долгоживущим соединением

wait_timeout становится реальным кандидатом, когда один PHP-процесс или worker установил соединение с MySQL, долго его не использовал, а затем попытался продолжить работу через то же соединение. За время простоя MySQL мог успеть его закрыть.

Почему wait_timeout редко виноват в обычном открытии страницы WordPress

У обычного веб-запроса WordPress жизненный цикл короткий: PHP принимает запрос, WordPress подключается к БД, выполняет SQL, формирует ответ и завершает работу. Соединение обычно не простаивает внутри такого request десятки минут.

Поэтому сценарий «пользователь открыл обычную страницу и сразу получил Error 2006» не стоит автоматически объяснять wait_timeout. Сначала проверьте MySQL uptime, OOM, серверный журнал и сам момент ошибки.

Другая ситуация возникает у:

  • WP-CLI-команды;
  • долгого импорта;
  • очереди или worker;
  • кастомного daemon;
  • длительной синхронизации;
  • кода, который надолго уходит во внешний API;
  • persistent connection.

Здесь один процесс действительно может жить долго, а пауза между двумя обращениями к MySQL становится значимой.

Как проверить таймаут

SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';

wait_timeout относится к неинтерактивным соединениям и потому особенно интересен для приложений. interactive_timeout относится к другому типу соединения; увеличивать оба параметра одновременно «для надёжности» не нужно.

Пример: импорт записал первую порцию товаров в MySQL, затем несколько минут ждал внешний API и за это время не обращался к базе. После паузы код пытается сохранить следующую порцию. Если простой оказался длиннее текущего wait_timeout, прежнего соединения уже может не существовать.

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

Может ли WordPress восстановить соединение сам

Класс wpdb в WordPress умеет проверять соединение и в некоторых ситуациях пытается переподключиться к MySQL. Но наличие reconnect-механизма не означает, что любой долгий процесс автоматически переживёт разрыв.

Переподключение не поможет, если MySQL всё ещё недоступен, постоянно перезапускается или причина разрыва повторяется сразу после нового соединения. Кроме того, конкретная фоновая операция может иметь собственное состояние, которое нельзя безопасно продолжить простым reconnect.

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

Большой wait_timeout оставляет неактивные соединения живыми дольше. Иногда это соответствует архитектуре приложения. Иногда лишь маскирует worker, который держит соединение без необходимости.

Если ошибка появляется только после долгой паузы одного процесса и эта пауза превышает текущий timeout — гипотеза сильная. Если Error 2006 возникает через полсекунды после открытия обычной страницы, таймаут простоя выглядит совсем не убедительно.

Timeout должен совпасть со сценарием по времени. Иначе это просто число в конфигурации.

Почему WooCommerce чаще проявляет проблему во время фоновых задач

WooCommerce может нормально работать для покупателей и одновременно получать MySQL server has gone away в фоне. Витрина, checkout и админка — только часть нагрузки. Отдельно работают очереди, cron, импорты, вебхуки, обновления остатков и внешние интеграции.

Как проверить Action Scheduler

Откройте Scheduled Actions в разделе состояния WooCommerce или соответствующем интерфейсе установленной версии. Ищите повторяющиеся failed actions, долгие задачи и hooks, время которых совпадает с PHP или MySQL log.

Витрина открывается, checkout принимает заказ, но каждые два часа один Scheduled Action падает с database error. Это уже другой сценарий. Главную страницу здесь проверять первой бессмысленно.

Таблицы Action Scheduler обычно имеют текущий WordPress-префикс и часть имени actionscheduler, например:

*_actionscheduler_actions

Но вручную удалять строки из этих таблиц без понимания зависимостей опасно. Сначала определите hook, источник задачи и причину failed state.

Как проверить WP-Cron

При наличии WP-CLI:

wp cron event list

Если cron запускается из панели управления или системного задания, отдельно проверьте правильный путь к PHP CLI: неверный бинарник или путь к скрипту может создать отдельную проблему, не связанную с MySQL.

Если используется системный cron, проверьте и его расписание. Ошибка, которая кажется случайной каждые четыре часа, нередко оказывается задачей, которая именно каждые четыре часа запускается по расписанию.

Импорт товаров, массовые обновления и внешние API

WooCommerce-импорт сочетает несколько факторов риска: долгий PHP-процесс, большое количество SQL, метаданные, hooks, рост потребления памяти и внешние запросы. Если сторонний API отвечает медленно, один batch живёт ещё дольше.

Scheduled Action упал в 02:41 — проверяйте PHP log и MySQL log вокруг 02:41, затем ресурсы VPS в тот же период. Такая временная привязка намного полезнее общего списка установленных расширений.

Фронтенд работает — не значит, что WooCommerce полностью здоров. Ночная очередь живёт своей жизнью.

Хостинг для WordPress
Хостинг для WordPress
Быстрый хостинг под WordPress
Автоустановка WordPress • NVMe • SSL бесплатно
Перейти к тарифам

Как найти запрос или плагин, после которого пропадает соединение с MySQL

Если MySQL не перезапускался, OOM отсутствует, а ошибка возникает только при определённой операции, поиск нужно сужать до конкретного веб-запроса, cron, импорта или Scheduled Action.

Сопоставьте один временной интервал сразу в нескольких местах:

  • wp-content/debug.log, если настроен WP_DEBUG_LOG;
  • PHP/PHP-FPM error log;
  • MySQL/MariaDB error log;
  • WooCommerce Scheduled Actions;
  • slow query log, если он был включён;
  • system journal.

На production подробные ошибки лучше писать в журнал, а не показывать посетителю. Публичный вывод database error редко помогает расследованию и заодно раскрывает внутренние детали сайта.

Если проблема воспроизводится обычным веб-запросом, Query Monitor может помочь увидеть SQL, hooks и время выполнения. Но Query Monitor не покажет cron, который упал ночью, когда сайт никто не открывал.

Текущее состояние MySQL:

SHOW FULL PROCESSLIST;

Смотрите длительность запросов, состояния потоков, блокировки и повторяющиеся тяжёлые операции. Но PROCESSLIST — фотография текущей секунды. Запрос, который оборвался минуту назад, там уже не появится.

Где возникает ошибка Куда смотреть Что это помогает исключить
Один URL WordPress PHP log, Query Monitor, конкретный hook Общую проблему всех сайтов
Один WooCommerce Scheduled Action Action Scheduler, PHP log, MySQL log Случайный сбой обычной страницы
Один большой импорт Размер batch, packet, PHP memory, длительность Постоянную недоступность MySQL
Несколько сайтов одновременно MySQL uptime, systemd, OOM, ресурсы VPS Проблему одного WordPress-плагина
Только при пиковой нагрузке PROCESSLIST, Threads_running, RAM, CPU, I/O Чисто функциональную ошибку одной страницы

Название плагина в последней строке лога — ориентир, не приговор. Посмотрите, что произошло несколькими секундами раньше.

Как отличить проблему PHP-FPM от потери соединения с MySQL

PHP-FPM timeout и MySQL server has gone away нельзя автоматически считать одной неисправностью. Если первым завершился PHP-FPM worker, внешний симптом обычно отличается от ситуации, когда исчез сам mysqld.

Что проверять в PHP-FPM

Для долгих WordPress и WooCommerce операций интересны:

  • memory_limit;
  • max_execution_time;
  • настройки PHP-FPM pool;
  • request_terminate_timeout, если он используется;
  • сообщения killed, terminated и memory exhausted.

Часть настроек CLI PHP:

php -i | grep -E 'memory_limit|max_execution_time'

Но CLI и PHP-FPM могут читать разные php.ini и дополнительные конфигурационные файлы. Поэтому вывод php -i нельзя автоматически считать настройками рабочего сайта.

Для начала:

php --ini

Затем проверяйте именно ту версию PHP и тот FPM pool, через которые обслуживается WordPress.

PHP memory error может выглядеть по смыслу так:

Allowed memory size ... exhausted

А FPM log может отдельно сообщить о принудительном завершении слишком долгого request. Это другой диагностический след.

Как понять, какой компонент завершился первым

Что произошло Какой симптом ожидаем Следующая проверка
mysqld исчез или перезапустился WordPress/PHP может получить Error 2006 или 2013 MySQL log, systemd, OOM
PHP-FPM worker принудительно завершён Чаще 502/504 или upstream error PHP-FPM и Nginx/Apache log
PHP исчерпал memory_limit PHP Fatal error PHP error log и память процесса
Сработал request_terminate_timeout FPM завершает долгий request Конфигурация FPM pool и журнал
Живой PHP request потерял MySQL connection Error 2006/2013 внутри PHP MySQL, сеть, timeout, server log

Если в ту же секунду PHP-FPM пишет о terminated request, а Nginx отдаёт 502, это другой след, чем новый MySQL uptime и запись о повторном старте mysqld.

Смотрите, кто завершил работу первым. Если исчез MySQL, PHP-лимиты вторичны. Если база продолжала работать, а FPM сам завершил долгий процесс, расследовать нужно PHP и конкретную задачу.

Если проблема появилась именно после смены версии PHP, отдельно проверьте сценарий, когда WordPress показывает белый экран после перехода на PHP 8.2: такой сбой относится к другой ветке диагностики и не должен смешиваться с Error 2006.

Как проверить нагрузку и долгие запросы MySQL

Высокая нагрузка сама по себе не доказывает причину Error 2006. Она становится значимой, когда вслед за перегрузкой MySQL перезапускается, попадает под OOM, соединение обрывается или приложение перестаёт получать ответ.

Что показывает SHOW FULL PROCESSLIST

SHOW FULL PROCESSLIST;

Ищите долгие запросы, блокировки, множество похожих операций и состояния ожидания. Один SQL, который долго выполняется, и сотни одновременно активных запросов — разные сценарии и требуют разной реакции.

Без достаточных привилегий пользователь MySQL может видеть не все процессы. Это ограничение нужно учитывать, прежде чем делать вывод «в базе ничего не происходит».

Threads_connected и Threads_running

SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Threads_running';
SHOW VARIABLES LIKE 'max_connections';

Threads_connected показывает открытые соединения, Threads_running — потоки, которые реально выполняют работу. Само по себе большое max_connections не показывает текущую нагрузку.

Добавьте ещё три метрики:

SHOW GLOBAL STATUS LIKE 'Aborted_clients';
SHOW GLOBAL STATUS LIKE 'Aborted_connects';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';

Aborted_clients помогает заметить клиентские соединения, которые завершились некорректно. Aborted_connects показывает неудачные попытки подключения. Max_used_connections даёт пиковое число одновременно использованных соединений с момента запуска MySQL.

Ни одна из этих метрик отдельно не означает MySQL server has gone away. Но в сочетании с журналами они помогают понять, был ли сервер близок к пределу соединений или наблюдались обрывы клиентов.

Не увеличивайте max_connections автоматически. Чем больше соединений сервер разрешает открыть одновременно, тем выше потенциальная нагрузка на память. На VPS без запаса такой «фикс» способен приблизить OOM.

Когда нужен Slow Query Log

PROCESSLIST показывает текущий момент. Slow query log полезен, когда сбой возникает периодически и тяжёлый SQL уже успел завершиться до того, как администратор подключился к серверу.

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

На уровне Linux:

top
free -h
vmstat 1 10

При наличии iostat:

iostat -xz 1 5

Если диск перегружен I/O, сначала растёт длительность SQL, затем PHP-FPM собирает очередь, cron-задачи начинают накладываться друг на друга. Сам по себе такой сценарий ещё не равен Error 2006, но он способен довести сервер до OOM, рестарта или других условий, при которых соединения уже начинают обрываться.

Что проверять при MySQL на отдельном сервере или внешней базе данных

Сетевой слой нужно добавлять в диагностику только тогда, когда WordPress действительно подключается к MySQL по TCP через отдельный сервер, VM, контейнер, proxy, VPN или другую сетевую прослойку. Для локального Unix socket искать packet loss между WordPress и MySQL бессмысленно.

Если MySQL вообще недоступен по TCP

Сначала проверьте DB_HOST WordPress. Если там отдельный hostname или IP, проверьте доступность порта:

nc -vz db-host 3306

Затем реальное MySQL-подключение:

mysql -h db-host -u user -p

Если TCP/3306 недоступен, разбирайте firewall, bind address, маршрут и состояние DB-сервера. Успешный ping здесь слабый аргумент: ICMP может проходить, а порт MySQL оставаться закрытым.

Если соединение устанавливается, но потом рвётся

Однократный успешный nc не исключает сетевую проблему. Если WordPress подключается нормально, но через несколько минут или только во время долгой задачи получает Error 2006/2013, проверяйте уже стабильность соединения.

В цепочке могут участвовать:

  • NAT с собственным idle timeout;
  • stateful firewall;
  • VPN или туннель;
  • database proxy;
  • контейнерная сеть;
  • нестабильный маршрут между VPS;
  • packet loss.

Текущие TCP-соединения:

ss -tnp

Если проблема воспроизводится на длинной сетевой сессии, можно дополнительно проверить маршрут с помощью mtr. Но интерпретировать результат нужно осторожно: промежуточные маршрутизаторы иногда ограничивают ICMP и показывают «потери», которых нет у конечного TCP-трафика.

При периодическом disconnect сопоставляйте три источника:

  • PHP log на web-сервере;
  • MySQL log на DB-сервере;
  • firewall или сетевые события в тот же момент.

Например, MySQL на DB-сервере не перезапускался, OOM отсутствует, другие локальные клиенты продолжают работать, а web-сервер теряет TCP connection. Здесь причина уже выглядит сетевой, а увеличение MySQL buffers или PHP memory_limit уводит расследование не туда.

Почему увеличение всех лимитов сразу — плохой способ исправления

Одновременно изменить max_allowed_packet, wait_timeout, max_connections, PHP memory_limit и timeout — значит лишиться нормальной проверки гипотезы. Даже если ошибка исчезнет, вы не будете знать почему.

  • Огромный max_allowed_packet. Не помогает, если mysqld убивает OOM Killer.
  • Очень большой wait_timeout. Может оставить больше idle connections и скрыть неправильную логику worker.
  • Рост max_connections на маленьком VPS. Разрешает ещё большую пиковую нагрузку на память.
  • Swap вместо решения OOM. Поможет пережить отдельный пик, но постоянная подкачка способна резко замедлить сервер.
  • Регулярный restart MySQL. Возвращает сервис, но не исправляет причину его падения.
  • Отключение всех плагинов на рабочем магазине. Слишком грубый метод для ошибки одного фонового job и потенциальный риск для продаж.
  • Ручная очистка таблиц Action Scheduler. Может добавить новую проблему поверх исходной.
Параметр Когда проверять Чего не делать
max_allowed_packet Крупный импорт или payload Повышать без пакетного симптома
wait_timeout Подтверждённый долгий idle Использовать как лечение обычного веб-запроса
max_connections Реальное давление по соединениям Повышать без оценки RAM
PHP memory_limit PHP memory exhausted Подменять им нехватку RAM всего VPS
PHP timeout Подтверждённое завершение PHP request Объяснять им MySQL 2006 без логов

Меняйте один параметр и повторяйте тот же сценарий. Иначе диагностика превращается в настройку методом тыка.

Пошаговый алгоритм исправления MySQL server has gone away

Порядок диагностики лучше строить от проверок, которые быстро исключают целые классы причин. Нет смысла час разбирать my.cnf, если kernel journal уже показывает завершение mysqld.

  1. Зафиксируйте время и операцию. URL, импорт, cron, Scheduled Action, CLI-команда или другой процесс.
  2. Проверьте MySQL сейчас. Выполните mysqladmin ping.
  3. Проверьте uptime. Выполните SHOW GLOBAL STATUS LIKE 'Uptime';.
  4. Посмотрите systemd journal. Ищите restart, crash, signal и новый запуск.
  5. Проверьте OOM. Ищите Killed process в kernel journal.
  6. Если падает большая операция, проверьте max_allowed_packet. Не забудьте отдельно исключить ограничения PHP и импортера.
  7. Если сбой идёт после длительного простоя одного процесса, проверьте wait_timeout. Сопоставьте timeout с реальной длительностью idle.
  8. Если ошибка внутри WooCommerce job, найдите конкретный Scheduled Action или cron.
  9. Если сайт сначала сильно замедляется, проверьте PROCESSLIST, Threads_running, RAM и I/O.
  10. При удалённой БД проверьте TCP и сетевые прослойки.
  11. Измените только подтверждённую причину.
  12. Повторите исходный сценарий и снова проверьте логи.

Короткое дерево решений

  • MySQL перезапускался — ищем crash, OOM, ручной или системный restart.
  • MySQL не перезапускался, падает только большая операция — проверяем packet и ограничения импортера.
  • Ошибка возникает после долгого idle — проверяем wait_timeout и логику worker.
  • Ошибка только в одном WooCommerce job — локализуем Scheduled Action и источник задачи.
  • Сбой совпадает с перегрузкой — разбираем запросы, соединения, память и диск.
  • База удалённая — добавляем TCP, firewall, NAT, proxy и маршрут.

Если после restart всё заработало, это ещё не диагноз. Нужно найти причину самого restart.

Как убедиться, что проблема действительно устранена

Исправление подтверждается только повторением того сценария, который раньше вызывал MySQL server has gone away. Главная страница WordPress может открываться идеально, пока ночная синхронизация продолжает падать.

После изменения проверьте несколько уровней:

  • импорт или WooCommerce job завершается полностью;
  • новая запись Error 2006/2013 не появляется;
  • MySQL uptime не сбрасывается;
  • systemd не показывает новый аварийный restart;
  • kernel journal не содержит нового OOM;
  • Scheduled Action не возвращается в failed state;
  • RAM, swap и I/O не уходят в проблемный режим.

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

Для сравнения состояния до и после удобно сохранить:

SHOW GLOBAL STATUS LIKE 'Uptime';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Threads_running';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';
free -h

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

Перед закрытием задачи проверьте:

  • зафиксировано время первоначального сбоя;
  • проверен MySQL uptime;
  • проверены systemd и MySQL logs;
  • проверен kernel journal на OOM;
  • проверены max_allowed_packet и wait_timeout, если сценарий на них указывает;
  • для WooCommerce проверены Scheduled Actions и cron;
  • проверены PHP-FPM logs;
  • при нагрузке проверены PROCESSLIST, соединения, RAM и I/O;
  • при удалённой БД проверена сеть;
  • повторена именно проблемная операция.

Как снизить вероятность повторения ошибки на WordPress и WooCommerce

Профилактику лучше строить по найденной причине, а не по универсальному набору параметров my.cnf. Небольшой WordPress и WooCommerce с постоянной ERP-синхронизацией создают совершенно разную нагрузку.

Если причиной был OOM: контролируйте RAM и swap, количество PHP-FPM workers и потребление MySQL. Полезно отслеживать OOM и Killed process, потому что после завершения процесса память быстро освобождается и проблема может остаться незаметной.

Если MySQL аварийно перезапускался: следите не только за HTTP uptime сайта, но и за uptime mysqld и событиями systemd. Сайт может снова отвечать через минуту, хотя база только что пережила crash.

Если проблема была в WooCommerce: проверяйте failed Scheduled Actions. Одна сломанная интеграция способна часами повторять задачу, пока витрина выглядит полностью исправной.

Если сервер упирался в запросы: на диагностический период используйте slow query log и следите за Threads_running, Max_used_connections, RAM и I/O. Не ограничивайтесь одним графиком CPU.

Если MySQL расположен отдельно: контролируйте доступность TCP между web- и DB-сервером, а при периодических разрывах учитывайте firewall, NAT, VPN и proxy.

Крупные импорты лучше дробить на контролируемые batch, чем пытаться обработать весь каталог одним огромным запросом или одним PHP-процессом. Это уменьшает пиковое потребление памяти, упрощает повтор после сбоя и делает причину ошибки заметнее.

После исправления должны совпасть три вещи: исходная операция проходит, mysqld не перезапускается, а в журналах больше нет прежней причины сбоя. Тогда MySQL server has gone away можно считать действительно разобранной, а не временно скрытой перезапуском сервиса.

Вопросы и ответы
WordPress потерял уже установленное соединение с MySQL. Причиной может быть таймаут, слишком большой пакет, рестарт mysqld, OOM, перегрузка или разрыв удалённого TCP-соединения.
Выполните SHOW VARIABLES LIKE 'max_allowed_packet'; и сравните фактическое значение с проблемной операцией. Сам по себе большой импорт ещё не доказывает, что причина именно в этом лимите.
Не автоматически. Сначала подтвердите, что один долгоживущий процесс действительно простаивал дольше текущего wait_timeout и затем попытался использовать старое соединение.
Да. Если OOM Killer завершил mysqld, активные соединения оборвутся. Проверяйте kernel journal на Out of memory и Killed process, а не только текущее значение free -h.
Фоновая задача может жить значительно дольше обычной страницы, выполнять большие пакеты SQL или ждать внешний API. Сопоставьте время failed action с PHP, MySQL и системными логами.
wpdb в некоторых ситуациях пытается переподключиться, но reconnect не помогает, если MySQL остаётся недоступным, постоянно перезапускается или причина разрыва сразу повторяется.
Повторите тот же сценарий, который раньше падал, и проверьте, что он завершается успешно, mysqld не перезапускается, OOM не возникает и прежняя ошибка больше не появляется в журналах.
Рекомендуемые статьи

Реквизиты:


Украина, 61202, Харьков, пр. Людвига Свободы 26/298.
ФО-П Харитинов Виталий Сергеевич
IBAN: UA903052990000026009005902765
МФО 305299
ИНН 2743208017
ПАТ КБ "ПриватБанк"
mail:

Документы:


Свидетельство плательщика единого налога

Свидетельство о регистрации

Служба поддержки:


  + 380 57 7209279
   создать тикет
© 2008 - 2026 Ukr Sky. All rights reserved