Failed with result timeout — Решение таймаута запуска служб в systemd
Архитектура ошибки и симптомы сбоя
Сообщение «systemd: Failed with result 'timeout'» (сопровождающееся «service.service: start operation timed out. Terminating...») генерируется диспетчером systemd. Ошибка означает, что процедура инициализации службы в ExecStart= или ExecStartPre= не завершилась в течение отведенного времени (по умолчанию TimeoutStartSec = 90s). Это типично для тяжелых баз данных при восстановлении после сбоя (Crash Recovery / WAL replay), служб с типом Type=notify / Type=forking, не отправивших сигнал готовности sd_notify(), или зависших сетевых скриптов.
Диагностическая таблица параметров сбоя
| Параметр | Значение | Инженерный смысл сбоя |
|---|---|---|
| TimeoutStartSec | 90s (Default) | Максимальное допустимое время на запуск и инициализацию службы. |
| Type=notify | Ready Notification | Служба обязана явно вызвать sd_notify("READY=1") через сокет $NOTIFY_SOCKET. |
| Type=forking | Double Fork Daemon | systemd ждет завершения родительского процесса после создания дочернего демона. |
Пошаговое дерево решений и сценарии траблшутинга
Сценарий 1: Проверка времени запуска и статуса сервиса
# Просмотр точного таймаута и текущего состояния службы:
systemctl show service_name.service -p TimeoutStartUSec -p Type -p ActiveState
# Анализ журналов во время зависания запуска:
sudo journalctl -u service_name.service -fСценарий 2: Увеличение или отключение TimeoutStartSec
Для тяжелых приложений (PostgreSQL при долгом replay WAL, GitLab, Elasticsearch, ClickHouse):
# Редактирование конфигурации сервиса:
sudo systemctl edit service_name.service
# Увеличение таймаута до 10 минут (600s) или полное отключение (infinity / 0):
[Service]
TimeoutStartSec=600
TimeoutSec=600
# Примените изменения:
sudo systemctl daemon-reload
sudo systemctl start service_name.serviceСценарий 3: Исправление некорректного Type=notify / Type=simple
Если приложение не поддерживает протокол systemd notify, но в юните указано Type=notify, systemd ждет 90 секунд и убивает работающий сервис по таймауту:
# Замена типа службы на simple или forking:
[Service]
Type=simpleСценарий 4: Отладка зависших предстартовых скриптов (ExecStartPre)
Часто таймаут вызван зависанием внешних скриптов (проверка сети, ожидание БД):
# Проверьте все ExecStartPre директивы:
systemctl show service_name.service -p ExecStartPre
# Установите индивидуальный таймаут для предстартовых команд в скриптах (timeout 10s cmd).ITSTM оптимизирует цепочки запуска служб, настроит интеграцию Type=notify и ускорит восстановление баз данных после сбоев.
Частые вопросы (FAQ)
Как работает механизм Type=notify в systemd?
При старте systemd передает сервису путь к Unix-сокету через переменную окружения $NOTIFY_SOCKET. Приложение, закончив внутреннюю инициализацию, отправляет в этот сокет строку READY=1. Только после этого systemd переводит службу в статус active (running).
Что означает директива WatchdogSec в systemd?
Она активирует сторожевой таймер. Приложение обязано регулярно отправлять строку WATCHDOG=1. Если приложение зависает в deadlock и не отправляет сигнал в течение WatchdogSec, systemd принудительно перезапускает сервис с ошибкой Result: timeout.
Чем TimeoutSec отличается от TimeoutStartSec?
TimeoutSec — это сокращенная директива, которая одновременно выставляет одинаковое значение для TimeoutStartSec (таймаут запуска) и TimeoutStopSec (таймаут остановки службы).
Что произойдет, если указать TimeoutStartSec=0?
Значение 0 (или infinity) полностью отключает контроль времени запуска. systemd будет бесконечно ждать завершения инициализации службы.