inotify: достигнут предел числа наблюдателей
Ядро ограничивает число наблюдателей за файлами на пользователя. Службы, следящие за деревьями каталогов — сборщики, средства синхронизации, наблюдатели за путями, — исчерпывают предел и перестают замечать изменения.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Предел числа наблюдателей исчерпан
Значение по умолчанию невелико, а каждый отслеживаемый каталог расходует одного наблюдателя. Большое дерево исчерпывает предел целиком.
-
Исчерпан предел числа экземпляров
Кроме наблюдателей ограничено число экземпляров механизма на пользователя. Его исчерпывают программы, создающие много независимых наблюдателей.
-
Служба следит за слишком большим деревом
Наблюдение за каталогом с сотнями тысяч файлов расходует ресурсы и замедляет систему. Иногда правильнее сузить область.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Действующие пределы.
sysctl fs.inotify.max_user_watches fs.inotify.max_user_instancesСообщения службы о наблюдателях.
journalctl -u myapp.service -n 30 --no-pager | grep -iE "inotify|watch"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Значение по умолчанию невелико, а каждый отслеживаемый каталог расходует одного наблюдателя. Большое дерево исчерпывает предел целиком.
- Как проверить
-
Посмотрите предел и текущее использование.
sysctl fs.inotify.max_user_watches find /proc/*/fd -lname anon_inode:inotify 2>/dev/null | wc -l
- Как исправить
-
Поднимите предел через файл в /etc/sysctl.d и примените настройку. Значения в сотни тысяч для машин со сборкой нормальны.
echo "fs.inotify.max_user_watches = 524288" | sudo tee /etc/sysctl.d/99-inotify.conf && sudo sysctl --system
- Почему происходит
- Кроме наблюдателей ограничено число экземпляров механизма на пользователя. Его исчерпывают программы, создающие много независимых наблюдателей.
- Как проверить
-
Посмотрите оба предела.
sysctl fs.inotify.max_user_instances fs.inotify.max_user_watches
- Как исправить
- Поднимите предел экземпляров так же, через файл настроек ядра.
- Почему происходит
- Наблюдение за каталогом с сотнями тысяч файлов расходует ресурсы и замедляет систему. Иногда правильнее сузить область.
- Как проверить
-
Посмотрите, за чем следит служба.
systemctl show myapp.service -p ExecStart sudo ls /proc/$(systemctl show -p MainPID --value myapp.service)/fd | wc -l
- Как исправить
- Исключите из наблюдения каталоги сборки, кеши и зависимости: обычно это даёт кратное сокращение.
Пример вывода
Предел наблюдателей исчерпан. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
myapp[1200]: error: failed to add watch for /srv/project/node_modules: no space left on device (inotify watch limit reached)
$ sysctl fs.inotify.max_user_watches
fs.inotify.max_user_watches = 8192
Связанные ошибки
- No space left on device в журнале службы Нет места на устройстве: разбор по свободным блокам, по inode, по журналу systemd и по удалённым, но открытым файлам.
- Path-unit не реагирует на изменения Unit .path не запускает службу при появлении или изменении файла. Разбор: не включён, следит не за тем, служба уже активна.
- Too many open files в журнале службы Служба исчерпала лимит файловых дескрипторов. Как правильно поднять LimitNOFILE и когда дело в утечке.
- VFS: file-max limit reached: в системе кончились описатели Общесистемный предел числа открытых файлов исчерпан: службы перестают принимать соединения и открывать файлы.
- Argument list too long в службе или скрипте Список аргументов слишком длинный: подстановка имён файлов дала тысячи аргументов. Как переписать вызов.
- Bad file descriptor в журнале службы Ошибка 9 при операции с файлом: дескриптор закрыт или не тот. Разбор для служб и сокет-активации.
- Cannot allocate memory в журнале службы Не удалось выделить память: предел службы, память машины, настройка overcommit, исчерпанные области отображения.
- Could not open file и cannot open shared object file Программа не может открыть файл или библиотеку: путь, права, отсутствующая зависимость сборки, изоляция.
Источники
- inotify(7): пределы ядра
-
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено наблюдением за каталогом с зависимостями сборки при пределе 8192.