Диск и inode: df, du и поиск причины ENOSPC
Ошибка No space left on device (ENOSPC) возникает не только при исчерпании блоков: файловая система может закончить inode, а процесс — удерживать уже удалённый большой файл и не…
Ошибка No space left on device (ENOSPC) возникает не только при исчерпании блоков: файловая система может закончить inode, а процесс — удерживать уже удалённый большой файл и не освобождать blocks. Квота пользователя вызывает отдельную ошибку EDQUOT, но входит в то же дерево диагностики неуспешной записи. df и du измеряют разные уровни и потому не обязаны совпадать.
df показывает файловую систему
Передавайте df путь, который реально должен принять запись: так команда выберет соответствующий mount, а не случайную строку из общего списка.
df -h /var/tmp
df -i /var/tmp
findmnt -T /var/tmp 2>/dev/null || truedf -h показывает занятые blocks, df -i — inode. Сто процентов inode при наличии гигабайтов свободного места типично для огромного числа маленьких файлов.
du объясняет видимое дерево
sudo du -xhd1 /var 2>/tmp/du-errors.log | sort -h
du -sh /var/log/* 2>/dev/null | sort -h | tail-x не переходит на другие filesystems, -d1 ограничивает глубину. Ошибки доступа нельзя бездумно скрывать: неполный обход занижает сумму. Сначала анализируйте без удаления и учитывайте mount boundaries.
Apparent size и реально выделенные blocks
Sparse file имеет большое логическое расстояние между байтами, но занимает мало blocks.
tmp_file=$(mktemp)
truncate -s 100M "$tmp_file"
ls -lh "$tmp_file"
du -h "$tmp_file"
du -h --apparent-size "$tmp_file"
rm -- "$tmp_file"Поэтому размер ls и usage du могут различаться без ошибки.
Удалённый файл всё ещё занимает место
unlink убирает имя, но blocks освобождаются после закрытия последнего file descriptor. lsof +L1 помогает найти deleted open files. Правильное действие — корректно перезапустить или заставить owner переоткрыть log; обнуление через чужой fd и kill -9 несут риск потери данных.
Ошибка и диагностика
Опасный ответ на отказ записи — удалить самый большой путь по первой выдаче. Сначала сохраните точное сообщение или errno: для ENOSPC определите mount через df/findmnt, проверьте blocks и inode, сравните du с df и найдите deleted-open files; для EDQUOT отдельно проверьте пользовательскую или групповую quota. Удаляйте только известные regenerable данные по retention policy. Логи должны ротироваться согласованно с процессом.
Практика
Создайте обычный и sparse file одинакового apparent size, сравните ls, du и du --apparent-size. На выбранном безопасном каталоге получите df -h/df -i и список первого уровня без удаления. Составьте дерево решений для случаев: blocks 100%, inode 100%, df намного больше du.
Что важно запомнить
- df измеряет filesystem allocation, du — достижимые файлы выбранного дерева.
ENOSPCуказывает на нехватку места или inode на device; исчерпанная quota возвращается отдельно какEDQUOT.- Освобождение места должно следовать ownership и retention, а не случайному rm.