PHP

Сервер падал по несколько раз в день. Виноват был не MySQL

231 старт базы при нуле штатных остановок. Причиной оказался не MySQL

Диагностика и настройка Роль
2026 Год
MySQL, Apache, mod_fcgid, CentOS, VestaCP Стек

Что было видно заказчику

Сайты отдавали ошибки, таблицы помечались как marked as crashed, после каждого падения часть данных чинилась руками. Однажды все сайты разом отдали 502. Очевидная версия звучала так: «MySQL плохой, надо тюнить или переезжать».

Что оказалось на самом деле

MySQL не падал. Его убивал системный механизм освобождения памяти, потому что памяти в системе не хватало. Доказательство простое: 231 старт базы и ноль штатных остановок. Ни сигналов, ни ассертов, ни стек-трейсов самой базы в логах не было — внутренней ошибки не существовало. Железо при этом было здорово: диски прошли самодиагностику, массив в норме, 752 ГБ свободно.

Откуда бралась нехватка памяти

  • Конфигурация правилась слоями годами: параметры дублировались, побеждало последнее значение. Один лимит стоял в 2256 МБ на соединение при 500 разрешённых соединениях.
  • Веб-стек работал на значениях по умолчанию. Ключевая деталь: настройка минимального числа процессов на класс — это не «до трёх», а минимум три на каждый сайт, которые демон держит живыми принудительно. На 66 сайтов получался гарантированный пол в двести процессов.
  • Регулярные задачи запускались без блокировки: скрипт с 393 секундами ожидания внутри стартовал каждые 300 секунд и физически не мог уложиться. Копии накладывались друг на друга.

Что сделал

Сначала измерил, а не предположил: 156 процессов PHP держали 5,4 ГБ, весь PHP — 7,6 ГБ, а веб-сервер оказался мелочью в 589 МБ. Инвентарь таблиц в памяти дал 517 штук на 501 МБ суммарно — при потолке в 2256 МБ на каждую.

Затем переписал конфигурацию так, чтобы каждый параметр встречался ровно один раз, и изменил 13 значений — каждое с обоснованием по замеру, а не по совету из интернета. Отдельно защитил базу на уровне системы, чтобы при следующей нехватке памяти жертвой становился веб-процесс.

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

Результат

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

Что стоит знать про такую работу

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

Срок: четыре рабочих дня, распределённые по неделе. Собственная инфраструктура.

Похожая задача?

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