Начало
» Основни познания
»
Как да поправите „ENOSPC: Достигнат е системен лимит за наблюдатели на файлове“ в Linux
Как да поправите „ENOSPC: Достигнат е системен лимит за наблюдатели на файлове“ в Linux
Ако инструмент за разработка на Linux внезапно спре с ENOSPC: System limit for number of file watchers reached, съобщението може да бъде подвеждащо. ENOSPCОбикновено се чете като „няма място на устройството“, но в този конкретен път това често не означава, че дискът ви е пълен. inotify_add_watch()Ръководството за Linux казва, ENOSPCче може да бъде върнато, когато е достигнат лимитът на inotify наблюденията на потребител или когато ядрото не може да разпредели необходимия ресурс. Това разграничение е важно, защото изтриването на файлове може да не направи нищо за решаване на проблема.
Това ръководство първо разглежда диагнозата, след това най-малко нарушаващото решение и накрая постоянна конфигурация. Командите се отнасят за Linux системи, които използват интерфейса inotify на ядрото , който позволява на приложенията да наблюдават файлове и директории за промени. Сървърите за разработка, IDE, клиентите за синхронизация, инструментите за изпълнение на тестове и инструментите за изграждане често разчитат на него.
Необходим ви е терминал и, за промяна на параметрите на ядрото, акаунт, който може да използва sudo. Запазете незапазената работа, преди да спрете сървърите за разработка или редакторите. Също така обърнете внимание къде се изпълнява неуспешната команда: директно в Linux, във виртуална машина, в WSL или вътре в контейнер. Контейнерът може да споделя настройките на ядрото със своя хост и може да не му е позволено да променя sysctl на ниво хост.
Не започвайте с копиране на много голям лимит за наблюдение от публикация във форум. Първо проверете текущата си настройка и определете дали не се използват от стари или дублирани процеси за наблюдение.
Стъпка 1: Потвърдете, че това е грешката на наблюдателя на inotify
Изпълнете командата, която е претърпяла неуспех, и прочетете цялата грешка. Типичните причини за стартиране включват стартиране на сървър за разработка на JavaScript, програма за тестване на файлове или работно пространство на IDE, което съдържа много голямо дърво на директории. Важната фраза е „достигнат е системният лимит за брой наблюдатели на файлове“.
Пример за неуспех на watcher-limit в терминал за разработка. Показаните име на проекта и версия са илюстративни; вашият инструмент и трасирането на стека може да се различават.
Ако грешката е възникнала ENOSPCпри запис на файл, проверете капацитета на диска и наличността на inode с команди като df -hи df -i. Тази статия е по-специално за формата inotify watcher-limit на ENOSPC.
Стъпка 2: Прочетете текущите ограничения за inotify
Linux предоставя ограничения на inotify под /proc/sys/fs/inotify/. Наблюдателният обект е един наблюдаван обект на файлова система в рамките на inotify екземпляр. Документацията на ядрото разграничава три контроли:
max_user_watches: максимален брой наблюдения за един реален потребителски идентификатор.
max_user_instances: максимален брой inotify инстанции за един реален потребителски ID.
max_queued_events: максимален брой събития, поставени в опашка за екземпляр на inotify.
Можете също така да прочетете първата стойност директно:
cat /proc/sys/fs/inotify/max_user_watches
Прочетете стойностите на вашата машина, вместо да приемате фиксирана стойност по подразбиране за Linux. Показаните тук числа са примерни, а не препоръчителни стойности.
Не бъркайте fs.inotify.max_user_watchesс fs.epoll.max_user_watches. Това са различни механизми на ядрото. За тази грешка обикновено е важен пътят на inotify.
Стъпка 3: Потърсете процеси, които консумират много часовници
Ядрото предоставя информация за наблюдение от inotify във всеки /proc/<pid>/fdinfoзапис на процеса. Документацията на proc_pid_fdinfo(5) посочва, че редовете, започващи с , inotifyописват наблюдавани файлове или директории.
За бърза проверка, тази команда показва редове от inotify, които вашите разрешения ви позволяват да четете:
sudo grep -H '^inotify' /proc/[0-9]*/fdinfo/* 2>/dev/null | head -n 50
За по-полезна оценка за всеки процес за текущия ви потребител, използвайте:
Третирайте този резултат като диагностична оценка, а не като перфектна отчетност, особено когато се споделят файлови дескриптори. Целта му е да разкрие очевидни нарушители, като например няколко стари сървъра за разработка, дублиращи се IDE екземпляри или множество наблюдатели в едно и също голямо хранилище.
Инспекцията /proc/*/fdinfo/*може да разкрие кои процеси съдържат дескриптори за наблюдение на inotify. Показаните PID и стойности на inode са илюстративни.
Стъпка 4: Спрете наблюдателите на застояли данни и опитайте отново, преди да увеличите лимита
Ако откриете сървъри или инструменти за разработка, от които вече не се нуждаете, първо ги затворете по обичайния начин. Рестартирането на редактор или сървър за разработка, който използва много наблюдатели, също може да освободи наблюденията, оставени от продължителна сесия. Избягвайте широка killallкоманда, освен ако не разбирате точно какво ще спре тя.
След като затворите подозрителните процеси, изпълнете отново оригиналната си команда. Ако сега работи, може изобщо да не се нуждаете от промяна на ядрото. Повтарящото се изчерпване обаче предполага, че работното натоварване наистина се нуждае от повече наблюдение или че инструментът наблюдава твърде много.
Рестартирайте само процеса, който е силно свързан с наблюдение и който познавате. Примерът pkillе илюстративен; използвайте действителното име на процеса си и предпочитайте нормалното изключване на приложението, когато е възможно.
Стъпка 5: Временно тествайте по-висока стойност на max_user_watches
Промяната в sysctl по време на изпълнение е полезна, защото можете да я тествате, преди да я направите постоянна. Първо запишете текущата стойност:
sysctl fs.inotify.max_user_watches
След това изберете стойност, която е достатъчно голяма за наблюдаваното натоварване. Например, ако умишлено решите да тествате 524 288 гледания:
sudo sysctl fs.inotify.max_user_watches=524288
Това е примерна стойност, а не универсална препоръка . Лимитите на inotify съществуват за ограничена консумация на ресурси на ядрото, така че повишаването им без разбиране на работното натоварване не е безплатно. По-добър подход е да увеличите измерените стъпки, да опитате отново приложението и да го спрете, след като имате достатъчно място за работа.
Промяната в sysctl по време на изпълнение ви позволява незабавно да тествате нов таван на наблюдателя. Тук 524 288 е само примерна тестова стойност.
Ръководството за sysctl (8) документира четенето и промяната на параметрите на ядрото по време на изпълнение.
Стъпка 6: Направете тестваната стойност постоянна
Ако временната промяна отстрани проблема и стойността е подходяща за вашата машина, запазете я в конфигурационен файл на sysctl. В дистрибуции, базирани на systemd, локален администратор може да постави конфигурацията в /etc/sysctl.d/*.conf. Документацията на systemd sysctl.d обяснява, че файловете в /etc/sysctl.d/са предназначени за конфигурация на локален администратор и се обработват по реда на имената на файловете.
Създайте специален файл, вместо да заравяте промяната сред несвързани настройки:
sudo nano /etc/sysctl.d/99-inotify.conf
Добавете стойността, която вече сте тествали:
fs.inotify.max_user_watches=524288
Запазете настройката на тествания наблюдател в специален конфигурационен файл sysctl.d. Заменете примерния номер със стойността, която сте валидирали за вашето работно натоварване.
Ако вашата система не използва потока sysctl.d на systemd, консултирайте се с документацията на вашата дистрибуция, преди да изберете постоянно местоположение за конфигурация.
Стъпка 7: Приложете постоянната конфигурация и я проверете
Можете да рестартирате, но това обикновено не е необходимо. На системи с sysctlинструмента procps, приложете системната конфигурация с:
sudo sysctl --system
След това проверете активната стойност:
sysctl fs.inotify.max_user_watches
Активната стойност трябва да съответства на желаната от вас настройка. Ако не е така, проверете изхода на sysctl --systemза по-късен конфигурационен файл, който презаписва въведения от вас запис. Правилата за именуване на sysctl.d са важни, защото по-късните имена на файлове могат да имат приоритет, когато една и съща променлива е присвоена повече от веднъж.
Приложете конфигурацията, след което прочетете параметъра обратно. Проверката е по-надеждна от предположението, че файлът е зареден.
Стъпка 8: Рестартирайте приложението и намалете ненужния обхват на наблюдение
Стартирайте приложението, което първоначално е прекъснало работата. Ако се стартира нормално, корекцията от страна на ядрото работи. Не спирайте дотук, ако използването на наблюдение остава неочаквано високо. Конфигурирайте приложението, където се поддържа, да изключва директории, които не се нуждаят от наблюдение в реално време, като например генериран изход от компилация, кешове, големи лог файлове, дървета на доставчици или директории на зависимости.
Намаляването на обхвата на наблюдение често е най-доброто дългосрочно решение, защото намалява използването на ресурси на ядрото и намалява обработката на файлови събития. Някои инструменти предлагат анкетирането като резервен вариант, но анкетирането може да увеличи активността на процесора и входно/изходните операции, така че обикновено е по-добре да се третира като опция за съвместимост, а не като първото решение.
Последна проверка: изпълнете отново оригиналната команда за разработка и потвърдете, че тя стартира без грешката watcher-limit.
Ами ако грешката все още се появява?
Проверете дали max_user_instances е истинското ограничение
max_user_instancesограничава броя на inotify инстанциите за всеки реален потребителски ID. Режимът на грешка обаче е различен: текущото ръководство за inotify_init(2) документира EMFILEкога е достигнат лимитът на inotify-instance за всеки потребител. Това означава, че точното съобщение за наблюдение на ENOSPC по-директно сочи към наблюдение или разпределение на ресурси, а не автоматично към лимита на инстанциите.
Не посягайте първо към ulimit -n
ulimit -nконтролира лимита за отворени файлови дескриптори на процеса. Файловите дескриптори са свързани с inotify екземпляри, но един inotify екземпляр може да съдържа много наблюдения. Следователно повишаването на лимита за отворени файлове не е директно решение за inotify_add_watch()ENOSPC, причинен от max_user_watches.
Контейнерите може да не са в състояние да променят този sysctl
Docker документира, че не всеки sysctl е с именувани пространства и че не поддържа промяна на sysctl-ове на контейнери, която би променила хост системата. Ако неуспешното натоварване се изпълнява в Docker и fs.inotify.max_user_watchesсе контролира от ядрото на хоста, направете промяната на съответния хост или виртуална машина, вместо да я насилвате от непривилегирован контейнер. Вижте документацията за sysctl по време на изпълнение на Docker .
Често срещани грешки, които трябва да се избягват
Ако приемем, че ENOSPC винаги означава пълен диск, системното извикване inotify изрично използва ENOSPC за грешки, свързани с ограничение на наблюдението/ресурси.
Промяна на max_queued_events вместо max_user_watches. Ограничението на опашката контролира чакащите събития, а не колко обекта на файловата система може да наблюдава един потребител.
Задаване на огромна стойност без измерване. Съществуват ограничения за Inotify, за да се ограничи използването на ресурси на ядрото; увеличете ги умишлено.
Правене на постоянна промяна преди тестването ѝ. Временната sysctlпромяна е по-лесна за валидиране и отмяна.
Забравяне на дублиращите се процеси за наблюдение. Няколко редактора, сървъра за разработчици или инструмента за синхронизиране могат да използват един и същ пул за всеки потребител.
Използване sudo echo value > /proc/...и очакване на sudo за покриване на пренасочването. Шелът се изпълнява >преди sudoизпълненията. Използвайте sudo sysctl ...вместо това.
Контролен списък за бърза диагностика
Въпрос
Команда или действие
Какво ви казва
Това ли е формата за наблюдение на ENOSPC?
Прочетете пълното съобщение за грешка в приложението
Разделя изчерпването на наблюдателя от дисковото пространство ENOSPC
Какъв е моят лимит за наблюдатели?
sysctl fs.inotify.max_user_watches
Показва активния таван за наблюдение на потребител
Кои процеси използват inotify?
Инспектирайте/proc/<pid>/fdinfo
Помага за намиране на застояли или силно наблюдавани процеси
Мога ли да го реша без промяна на ядрото?
Затворете дублиращи се/неактуализиращи наблюдатели и опитайте отново
Пуска в продажба съществуващи часовници
По-висок лимит оправя ли го?
sudo sysctl fs.inotify.max_user_watches=VALUE
Тества незабавно стойност по време на изпълнение
Ще оцелее ли поправката след рестартиране?
Използвайте /etc/sysctl.d/*.confи проверете
Прави тествана настройка постоянна
Първична документация
Описаното тук поведение идва от документацията за потребителския интерфейс на ядрото на Linux, документацията за файловата система proc, документацията за sysctl.d на systemd и документацията за изпълнение на Docker. За най-важните подробности вижте inotify(7) , inotify_add_watch(2) , proc_pid_fdinfo(5) и sysctl.d(5) .