SystemdDoctor
служба не работает частое сигналы память oom остановка

signal=KILL (status=9/KILL) в systemd

Сигнал KILL нельзя перехватить: процесс исчезает мгновенно, без сохранения данных и без прощальных строк в журнале. Поэтому вопрос не «почему программа упала», а «кто её убил». Обычно это OOM-killer ядра, сам systemd по истечении таймаута остановки или человек с командой kill -9.

Что это значит

Разобраться помогает строка Result: в состоянии службы. oom-kill — убило ядро из-за нехватки памяти. timeout — systemd не дождался остановки и добил процесс. Просто signal без уточнения — сигнал пришёл извне.

В записях ядра при нехватке памяти всегда остаётся след: строка про «Out of memory: Killed process» с именем и объёмом. Если её нет, а служба убита KILL, ищите того, кто послал сигнал вручную или сценарием.

Вероятные причины

По порядку: сверху то, что встречается чаще.

  1. Процесс убит ядром из-за нехватки памяти

    При исчерпании памяти в контрольной группе или на машине ядро выбирает процесс и убивает его сигналом KILL. Для служб с MemoryMax= это происходит по достижении предела, даже когда на машине память есть.

  2. systemd добил процесс после таймаута остановки

    При остановке systemd посылает TERM, ждёт TimeoutStopSec= (по умолчанию 90 секунд) и затем посылает KILL. Программа, которая долго завершает работу или игнорирует TERM, всегда будет получать KILL.

  3. Сигнал послан вручную или сторонним средством

    Команда kill -9, сценарий обслуживания, сторожевой скрипт или средство мониторинга могли убить процесс. systemd об этом не знает и просто сообщает факт.

  4. Процесс убит вместе с группой при остановке другой службы

    При KillMode=control-group останавливаются все процессы контрольной группы. Если ваш процесс оказался в чужой группе (например запущен из чужого unit), он умрёт вместе с ней.

Диагностика

Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.

Строка Result: уточняет причину: oom-kill, timeout или просто signal.

systemctl status myapp.service -l --no-pager

След OOM-killer в записях ядра. Если строки нет, память тут не при чём.

journalctl -k -b --no-pager | grep -i "killed process"

Полная картина событий: остановка по команде выглядит иначе, чем внезапная смерть.

journalctl -u myapp.service --since "30 min ago" --no-pager

Три числа, которые чаще всего объясняют KILL.

systemctl show myapp.service -p MemoryMax -p MemoryPeak -p TimeoutStopSec

Решение

Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.

1. Процесс убит ядром из-за нехватки памяти
Почему происходит
При исчерпании памяти в контрольной группе или на машине ядро выбирает процесс и убивает его сигналом KILL. Для служб с MemoryMax= это происходит по достижении предела, даже когда на машине память есть.
Как проверить
Посмотрите записи ядра и предел памяти у службы.
journalctl -k -b --no-pager | grep -iE "out of memory|oom-kill"
systemctl show myapp.service -p MemoryMax -p MemoryPeak
Как исправить
Поднимите MemoryMax= или уменьшите потребление программы. Разовое повышение предела без разбора роста потребления только отложит проблему.
sudo systemctl edit myapp.service   # MemoryMax=2G
2. systemd добил процесс после таймаута остановки
Почему происходит
При остановке systemd посылает TERM, ждёт TimeoutStopSec= (по умолчанию 90 секунд) и затем посылает KILL. Программа, которая долго завершает работу или игнорирует TERM, всегда будет получать KILL.
Как проверить
Поищите в журнале строку про таймаут остановки.
journalctl -u myapp.service -n 40 --no-pager | grep -iE "stop|timeout|SIGKILL"
systemctl show myapp.service -p TimeoutStopSec -p KillSignal
Как исправить
Увеличьте TimeoutStopSec= до времени, которое программе действительно нужно на корректное завершение, и убедитесь, что она реагирует на TERM. Если ей нужен другой сигнал, задайте KillSignal=.
TimeoutStopSec=300
3. Сигнал послан вручную или сторонним средством
Почему происходит
Команда kill -9, сценарий обслуживания, сторожевой скрипт или средство мониторинга могли убить процесс. systemd об этом не знает и просто сообщает факт.
Как проверить
Посмотрите записи вокруг момента смерти и активность администраторов.
journalctl --since "10 min ago" --no-pager | grep -iE "kill|stopped|session"
last -n 10
Как исправить
Найдите источник. Если это ваш сценарий обслуживания, замените kill -9 на systemctl stop: systemd остановит службу по правилам unit-файла, а не оборвёт процесс.
4. Процесс убит вместе с группой при остановке другой службы
Почему происходит
При KillMode=control-group останавливаются все процессы контрольной группы. Если ваш процесс оказался в чужой группе (например запущен из чужого unit), он умрёт вместе с ней.
Как проверить
Посмотрите, в какой группе живёт процесс.
systemd-cgls --no-pager | grep -B5 myapp
systemctl show myapp.service -p KillMode
Как исправить
Запускайте программу собственным unit-файлом, а не из скрипта другой службы: тогда у неё будет своя контрольная группа.

Пример вывода

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

× indexer.service - Search indexer
     Loaded: loaded (/etc/systemd/system/indexer.service; enabled; preset: enabled)
     Active: failed (Result: oom-kill) since Mon 2026-09-15 03:41:55 MSK; 1min ago
   Main PID: 7781 (code=killed, signal=KILL)
     Memory: 512.0M (max: 512.0M available: 0B)

kernel: Memory cgroup out of memory: Killed process 7781 (indexer) total-vm:2412480kB, anon-rss:519424kB
systemd[1]: indexer.service: A process of this unit has been killed by the OOM killer.
systemd[1]: indexer.service: Main process exited, code=killed, status=9/KILL
systemd[1]: indexer.service: Failed with result 'oom-kill'.

Частые вопросы

Почему в журнале нет ни одной строки от самой программы перед смертью?

Потому что KILL не перехватывается: программа не получает управления и не успевает ничего записать. Это нормальное поведение, а не потеря журнала.

Связанные ошибки

  • Failed with result 'oom-kill' Состояние oom-kill: процесс службы убит из-за нехватки памяти. Как понять, упёрлись в предел службы или в память машины.
  • signal=TERM (status=15/TERM) в systemd Процесс службы завершён сигналом TERM. Когда это нормальная остановка, а когда признак проблемы.
  • Failed with result 'timeout' Состояние timeout: служба не уложилась в отведённое время при запуске, остановке или перезагрузке настроек.
  • status=204/MEMORY в systemd Код 204/MEMORY: systemd не смог выделить память при подготовке запуска службы. Что проверять на машине и в unit-файле.
  • MySQL убит из-за памяти: буферный пул больше доступной памяти MySQL падает сразу после старта или через минуты: размер innodb_buffer_pool_size превышает память машины.
  • signal=INT и signal=QUIT в systemd Процесс службы завершён сигналом INT или QUIT. Кто их посылает службам и почему это обычно не systemd.
  • signal=SEGV (status=11/SEGV) в systemd Процесс службы завершён сигналом SEGV: обращение к недопустимой памяти. Как собрать дамп и что смотреть.
  • status=206/OOM_ADJUST в systemd Код 206/OOM_ADJUST: не удалось изменить оценку OOM для процесса службы. Обычно мешают права или значение вне диапазона.

Где встречается чаще всего

Источники

  • systemd.kill(5)
    KillSignal=, KillMode= и порядок посылки сигналов при остановке.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • systemd.resource-control(5)
    MemoryMax= и поведение при достижении предела памяти.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Воспроизведено на службе с MemoryMax=64M и на программе, игнорирующей TERM.
    собственная проверка, systemd 255
    сверено 15 сентября 2026