SystemdDoctor
служба не работает приложения таймауты базы данных

Приложение не стартует: блокировка миграций базы

Приложения, применяющие миграции при старте, берут блокировку в базе. Если прежний запуск был прерван — например по таймауту systemd, — блокировка остаётся, и следующий запуск ждёт её или падает.

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

Это типичное последствие слишком короткого таймаута запуска: systemd прерывает миграцию на середине, а приложение не успевает снять блокировку. Дальше каждая попытка запуска упирается в неё.

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

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

  1. Блокировка осталась от прерванного запуска

    Прерывание по таймауту или сигналом не даёт приложению убрать за собой. Запись о блокировке остаётся в базе.

  2. Миграции применяются несколькими экземплярами одновременно

    При запуске приложения на нескольких серверах все они пытаются применить миграции. Блокировка для этого и нужна, но ожидание может превысить таймаут.

  3. База недоступна в момент миграции

    Приложение ждёт базу, не укладывается в таймаут и прерывается на середине.

Диагностика

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

Что происходило с миграциями при последних запусках.

journalctl -u myapp.service -n 50 --no-pager | grep -iE "migrat|lock|timeout"

Таймаут и число прерванных попыток.

systemctl show myapp.service -p TimeoutStartSec -p NRestarts

Решение

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

1. Блокировка осталась от прерванного запуска
Почему происходит
Прерывание по таймауту или сигналом не даёт приложению убрать за собой. Запись о блокировке остаётся в базе.
Как проверить
Посмотрите журнал приложения и таблицу блокировок в базе.
journalctl -u myapp.service -n 40 --no-pager | grep -iE "migrat|lock"
Как исправить
Снимите блокировку средствами приложения (у большинства есть команда) и увеличьте таймаут запуска, чтобы миграция успевала завершиться.
sudo systemctl edit myapp.service   # [Service]\nTimeoutStartSec=10min
2. Миграции применяются несколькими экземплярами одновременно
Почему происходит
При запуске приложения на нескольких серверах все они пытаются применить миграции. Блокировка для этого и нужна, но ожидание может превысить таймаут.
Как проверить
Посмотрите, сколько экземпляров стартует одновременно.
systemctl list-units "myapp*" --no-pager
Как исправить
Выделите миграции в отдельную одноразовую службу и запускайте её до приложения: остальные экземпляры тогда не будут конкурировать.
3. База недоступна в момент миграции
Почему происходит
Приложение ждёт базу, не укладывается в таймаут и прерывается на середине.
Как проверить
Посмотрите доступность базы и порядок запуска.
systemctl show myapp.service -p After | tr " " "\n" | grep -i sql
pg_isready 2>/dev/null || mysqladmin ping 2>/dev/null
Как исправить
Добавьте зависимость от базы и повторные попытки подключения в приложении.

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

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

myapp[4300]: waiting for migration lock (held by instance 7f2a, since 14:02:11)
systemd[1]: myapp.service: start operation timed out. Terminating.
systemd[1]: myapp.service: Failed with result 'timeout'.

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

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

Источники

  • systemd.service(5)
    TimeoutStartSec= и прерывание запуска.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Воспроизведено прерыванием миграции по таймауту на тестовом приложении.
    собственная проверка, systemd 255
    сверено 15 сентября 2026