Что было. Учебный проект на арендованной виртуальной машине: один vCPU, 2 ГБ памяти, подкачка не настроена. Debian 11, Apache с PHP-модулем, MySQL, плюс оставшиеся от курса мониторинг и визуализация метрик. Периодически OOM-killer убивает процессы; в top процессы веб-сервера и MySQL занимают около 80 % памяти.
Что советовали участники.
- Подкачка. Её отсутствие превращает любой пик в убийство процесса; 1–2 ГБ файла подкачки дают буфер (об этом отдельный разбор).
- Ограничить Apache.
MaxConnectionsPerChild 1000(перезапуск процессов против утечек) и посчитанные лимитыMaxRequestWorkers/ServerLimitвmpm_prefork.confпод реальную память процесса. - Остановить лишнее. Стек мониторинга и панели визуализации на 2 ГБ рядом с базой это половина памяти на инструменты.
systemctl disable --nowдля того, что не нужно проекту. - Смотреть правильно.
htopпо памяти,dstatво времени,journalctl -k | grep -i oomдля точной картины; и не убивать процессы Apache вручную, они тут же пересоздаются, вместо этогоsystemctl restart apache2илиa2dissite. - Добавить памяти, если после всего этого нагрузка не помещается: 2 ГБ для LAMP с MySQL это нижняя граница.
Наш расчёт для такой машины.
| Компонент | Разумный лимит |
|---|---|
| ОС и службы | ~250 МБ |
MySQL (innodb_buffer_pool_size) |
256–384 МБ, performance_schema = OFF |
| Apache prefork с PHP | 8–10 процессов × ~50 МБ = ~500 МБ |
| Запас под пики и кэш файлов | остальное |
При таких лимитах машина держит небольшой сайт стабильно; при большем трафике нужен mpm_event + PHP-FPM и кэш страниц, а не рост MaxRequestWorkers. |
Как убедиться, что подкачка не стала костылём. vmstat 5: столбцы si/so должны быть нулями почти всегда; постоянный обмен означает, что рабочая нагрузка не помещается, и лечится это памятью или сокращением нагрузки, а не размером файла подкачки.
Что делать в момент инцидента. dmesg -T | grep -B3 -A25 'Out of memory' покажет, кто вызвал и кого убили; часто это не веб-сервер, а фоновый процесс мониторинга или задача резервного копирования, запущенная в час пик. Перенести тяжёлое на ночь и защитить базу OOMScoreAdjust=-500 в её юните.
Модуль prefork описан в документации Apache.