Що таке OOM Killer і коли він спрацьовує
OOM Killer (Out Of Memory Killer) — механізм ядра Linux, який примусово завершує процеси, коли оперативна пам'ять і swap закінчуються одночасно. Ядро не дозволяє системі зависнути через брак пам'яті, тому обирає "жертву" і вбиває її сигналом SIGKILL. Найчастіше таке трапляється на VDS з 1-2 ГБ RAM без налаштованого swap, коли MySQL, PHP-FPM або Java-застосунок різко збільшують споживання пам'яті.
Важливо розуміти: OOM Killer — захисний механізм, а не баг. Раз він спрацював — системі справді забракло пам'яті, і причину варто шукати в конфігурації сервісів або в обсязі RAM.
Як дізнатися, що процес убив саме OOM Killer
Коли сервіс несподівано впав без явної помилки у власному логу, перевірте системний журнал:
journalctl -k | grep -i "out of memory"
dmesg | grep -i oom
У виводі буде запис виду Out of memory: Killed process 1234 (mysqld) із зазначенням PID, імені процесу і кількості зайнятої пам'яті на момент убивства. Так найпростіше відрізнити OOM Killer від падіння процесу з іншої причини — скажімо, помилки сегментації.
Як знайти процес, що з'їдає пам'ять
Перед налаштуванням захисту знайдіть реального споживача пам'яті. Швидкий спосіб — відсортувати процеси за використанням RAM:
ps aux --sort=-%mem | head -n 10
free -h
Команда free -h покаже загальний обсяг пам'яті, зайняту, вільну і розмір swap. Без swap або за його малого розміру будь-який стрибок навантаження — резервне копіювання бази, сплеск трафіку — миттєво призводить до OOM. Детально про налаштування підкачки дивіться у статті про swap на VPS Linux.
Як ядро обирає жертву: oom_score
Кожному процесу ядро призначає значення oom_score — чим вище воно, тим більша ймовірність, що процес вб'ють першим. Подивитися поточний рахунок допоможе команда:
cat /proc/PID/oom_score
На рахунок впливають обсяг зайнятої пам'яті, час роботи процесу і явне налаштування oom_score_adj, яке приймає значення від -1000 до 1000. Значення -1000 повністю виключає процес із кандидатів на вбивство, а 1000 робить його першою мішенню.
Як захистити важливий процес від OOM Killer
Якщо на сервері є сервіс, вбивати який неприпустимо за жодних обставин — скажімо, основна база даних — знизьте його пріоритет на вбивство:
echo -900 > /proc/$(pidof mysqld)/oom_score_adj
Зміна діє лише до перезапуску процесу. Щоб закріпити налаштування назавжди, додайте параметр до unit-файлу systemd сервісу:
[Service]
OOMScoreAdjust=-900
Після правки виконайте systemctl daemon-reload і перезапустіть сервіс. Захищаючи один процес, ви автоматично підвищуєте ризик для інших — ядро все одно знайде, кого вбити, за реальної нестачі пам'яті.
Профілактика: swap, ліміти пам'яті та моніторинг
Разове налаштування oom_score_adj не вирішує нестачу пам'яті — воно лише перекладає ризик на інший процес. Справжня профілактика виглядає так:
- Налаштуйте swap-файл хоча б 1-2 ГБ, щоб згладити короткочасні піки навантаження.
- Обмежте пам'ять важких сервісів явно:
memory_limitу PHP,innodb_buffer_pool_sizeу MySQL,-Xmxу Java. - Підключіть моніторинг використання RAM, щоб бачити зростання споживання до спрацювання OOM — див. статтю про моніторинг ресурсів VDS.
- Перевіряйте журнал через
journalctl -kпісля кожного інциденту — детальніше у статті про journalctl і rsyslog. - За системної нестачі пам'яті правильний крок — збільшити тариф VDS, а не боротися із симптомами.