No space left on device — почему диск «полный», когда место ещё есть

df показывает: занято 0 %. А запись падает с ошибкой No space left on device.
Я воспроизвёл это на маленьком диске. Места было мегабайт, занятого — ноль. Двадцатый файл создать не удалось. Система не врёт. Просто «место» — это не одна цифра, а несколько разных запасов. Кончиться может любой.
Вот причины, от самой частой.
Диск и правда заполнен
Как проверить. Смотри колонку Use% для диска, куда идёт запись:
df -h
Если там 100 %, ищи, что съело место. Команда идёт по папкам и выводит самые тяжёлые в конце:
du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -15
Флаг -x не даёт уйти на другие диски. Спускайся в самую большую папку и повторяй.
Как починить. Обычные виновники:
- Логи. Посмотри
/var/log. Если растёт журнал systemd:sudo journalctl --vacuum-size=200M. - Docker. Он копит образы и слои незаметно. Сначала посмотри:
docker system df. Потом почисти неиспользуемое:docker system prune. Тома команда не трогает без флага--volumes, так что данные контейнеров останутся. - Кэши и сборки.
~/.cache,node_modules, папкиdist, скачанные модели. Одна модель легко занимает 20 ГБ.
Если df показывает 95 % и упало только у обычного пользователя, это тоже бывает. На ext4 часть диска, обычно 5 %, зарезервирована для root.
Кончились inode
Вот случай из начала. Каждый файл, даже пустой, занимает запись в таблице файлов. Такая запись называется inode. Их количество на ext4 задаётся при создании диска и потом не растёт. Как в гардеробе: вешалок полно, а номерки кончились.
Как проверить. Флаг -i показывает inode вместо байтов:
df -i
У меня это выглядело так:
Filesystem Inodes IUsed IFree IUse%
tmpfs 20 20 0 100%
Занято 100 % при совершенно пустом месте. Значит, виноваты мелкие файлы, и много.
Как починить. Найди папку, где файлов больше всего:
du --inodes -d1 / 2>/dev/null | sort -n | tail -15
Обычно это кэш пакетов, сессии, письма в очереди или брошенные node_modules. Удали лишнее — inode освободятся сразу.
Файл удалён, но программа его держит
Логи раздулись, ты удалил файл, а места не прибавилось. Причина в том, что программа всё ещё держит его открытым. Пока открыт хотя бы один дескриптор, данные остаются на диске.
Я проверил. Записал 880 КБ в файл на диске в 1 МБ и удалил, не закрывая:
df: использовано 880K из 1024K
du: 0
Вот главный признак этой причины: df говорит, что занято много, а du не находит ни байта.
Как проверить. Покажи удалённые, но открытые файлы:
lsof +L1
В конце строки будет (deleted), а в начале — имя процесса.
Как починить. Перезапусти этот процесс. Как только файл закрылся, у меня сразу вернулись все 880 КБ. На будущее очищай логи, не удаляя файл:
truncate -s 0 app.log
Так файл обнуляется, а дескриптор у программы остаётся рабочим.
Ошибка ENOSPC есть, а с диском всё в порядке
Если в тексте написано System limit for number of file watchers reached — диск вообще ни при чём. Кончился лимит наблюдателей за файлами, которых требует dev-сервер. Код ошибки тот же, ENOSPC, отсюда и путаница.
Чинится поднятием лимита:
sudo sysctl fs.inotify.max_user_watches=524288
Подробнее — в статье почему не работает hot reload.
Почему ошибка всплывает в непонятных местах?
Потому что диск нужен почти всем. Не собирается проект, падает git commit, база отказывается писать, cron молча перестаёт работать. Если всё сломалось одновременно и без причины, сначала набери df -h и df -i.
Что безопасно удалять?
Кэши и старые логи, почти всегда. Осторожно с /var/lib: там живут базы данных и Docker. Папку /var/lib/docker руками не удаляй, для этого есть docker system prune.
Почему падает только запись в /tmp?
Часто /tmp живёт в памяти как отдельный диск со своим лимитом. Проверь его отдельно: df -h /tmp. Основной диск при этом может быть почти пустым.
Как не допустить этого снова?
Включи ротацию логов через logrotate. Логи Docker ограничь при запуске контейнера: --log-opt max-size=10m. Без этого один шумный контейнер спокойно съедает весь диск.
Что делать, если места совсем нет и даже команды падают?
Удали один заведомо лишний большой файл, например старый архив логов. Это даст системе дышать. Потом разбирайся спокойно по шагам выше.
Короткие уроки-истории, симулятор агента и ежедневная практика — в нашем мобильном приложении. Бесплатно.





