Что было видно заказчику
Сайты отдавали ошибки, таблицы помечались как 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 значений — каждое с обоснованием по замеру, а не по совету из интернета. Отдельно защитил базу на уровне системы, чтобы при следующей нехватке памяти жертвой становился веб-процесс.
Восстановил битые таблицы, добавил защиту от наложения регулярных задач и сторожевой скрипт из десяти проверок с порогами, взятыми из замеров именно этого сервера.
Результат
Убийства базы прекратились. Из неопределённого «сервер падает» получился воспроизводимый диагноз с цифрами и журнал, по которому следующий инцидент разбирается за часы, а не за недели.
Что стоит знать про такую работу
Защита от нехватки памяти не создаёт память — она переводит удар на другую цель. Дефицит остаётся, и это было написано в отчёте прямым текстом, вместе с планом мониторинга. Обещать «теперь точно не упадёт» в такой ситуации нельзя.
Срок: четыре рабочих дня, распределённые по неделе. Собственная инфраструктура.