Наблюдение за каталогом перестаёт работать на больших деревьях
Наблюдение за путями опирается на механизм ядра с ограниченным числом наблюдений на пользователя. При большом числе наблюдаемых каталогов предел исчерпывается, и новые наблюдения не создаются молча — unit остаётся активным, но события не приходят.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Исчерпан предел числа наблюдений
Предел считается на пользователя. Его исчерпание другими программами отражается и на unit наблюдения.
-
Наблюдение за деревом каталогов вместо одного пути
Механизм ядра не следит за деревом рекурсивно. Программа, делающая это, создаёт наблюдение на каждый каталог.
-
События приходят пачками и запускают службу многократно
Массовое изменение файлов даёт множество событий. Служба может запускаться чаще, чем успевает работать.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Предел числа наблюдений на пользователя.
sysctl fs.inotify.max_user_watchesЗа чем следит unit и что запускает.
systemctl show mywatch.path -p Paths -p UnitЖурнал наблюдения и запускаемой службы.
journalctl -u mywatch.path -u mywatch.service -n 30 --no-pagerРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Предел считается на пользователя. Его исчерпание другими программами отражается и на unit наблюдения.
- Как проверить
-
Посмотрите предел и текущее использование.
sysctl fs.inotify.max_user_watches fs.inotify.max_user_instances find /proc/*/fd -lname anon_inode:inotify 2>/dev/null | wc -l
- Как исправить
- Поднимите предел числа наблюдений настройкой ядра и закрепите её в файле настроек. На машинах со средами разработки предел по умолчанию мал.
- Почему происходит
- Механизм ядра не следит за деревом рекурсивно. Программа, делающая это, создаёт наблюдение на каждый каталог.
- Как проверить
-
Посмотрите, за чем следит unit и сколько там каталогов.
systemctl cat mywatch.path | grep -E "^Path" find /srv/data -type d 2>/dev/null | wc -l
- Как исправить
- Следите за конкретным путём, а не за большим деревом. Для деревьев лучше периодический обход по таймеру.
- Почему происходит
- Массовое изменение файлов даёт множество событий. Служба может запускаться чаще, чем успевает работать.
- Как проверить
-
Посмотрите частоту запусков службы.
journalctl -u mywatch.service --since "1 hour ago" --no-pager | grep -c Started
- Как исправить
- Добавьте задержку в саму службу или переходите на периодический обход. Unit наблюдения не умеет объединять события.
Пример вывода
Предел наблюдений исчерпан, события не приходят. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
$ sysctl fs.inotify.max_user_watches
fs.inotify.max_user_watches = 8192
$ systemctl is-active mywatch.path
active
# файлы в каталоге меняются, служба не запускается
$ journalctl -u mywatch.service --since "1 hour ago" --no-pager | grep -c Started
0
Связанные ошибки
- Path-unit не реагирует на изменения Unit .path не запускает службу при появлении или изменении файла. Разбор: не включён, следит не за тем, служба уже активна.
- Path-unit создаёт каталог с неверными правами Каталог наблюдения создан systemd, но служба не может в него писать: параметр режима каталога.
- Too many open files в журнале службы Служба исчерпала лимит файловых дескрипторов. Как правильно поднять LimitNOFILE и когда дело в утечке.
- Cannot allocate memory в журнале службы Не удалось выделить память: предел службы, память машины, настройка overcommit, исчерпанные области отображения.
- Disk quota exceeded для службы Место на разделе есть, а запись отклоняется: исчерпана дисковая квота пользователя или группы.
- Elasticsearch: max virtual memory areas vm.max_map_count is too low Elasticsearch отказывается стартовать из-за заниженного vm.max_map_count. Как поднять значение и закрепить его.
- Failed with result 'resources' Состояние resources: systemd не смог выделить ресурсы для запуска службы. Чем отличается от кодов 200-й группы и что проверять.
- No buffer space available в журнале службы Ошибка 105: нет места в буферах ядра. Разбор для сети и таблиц соседей.
Источники
-
systemd.path(5)
Unit наблюдения за путями и их ограничения. -
inotify(7)
Пределы числа наблюдений и экземпляров. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Проверено на systemd 255: при исчерпанном пределе события не приходят без сообщения.