6 октября 2026 г.

«No space left on device», а место есть: как найти и освободить inode

Диск наполовину пуст, а файл не создаётся. Показываем, как заканчиваются inode, как это увидеть командой df -i и очистить.

Приложение падает с ошибкой «No space left on device», а df -h честно показывает, что диск занят на 3%. Не сломан ни диск, ни команда: на диске закончились не байты, а inode. Разберём, что это такое, как это увидеть за одну команду и как очистить сервер, ничего не сломав.

Коротко. inode - запись о файле в файловой системе: один файл или каталог занимает один inode, независимо от размера. Их число ограничено. Проверка: df -i, колонка IUse%. Найти виновника: sudo du --inodes -x -d1 /var | sort -rn | head. Очистить: find КАТАЛОГ -type f -delete. Причина почти всегда одна: миллионы мелких файлов (сессии, кэш, очередь почты).

Что такое inode и почему он заканчивается

Представьте библиотеку: книг может быть мало, но каждой нужна карточка в каталоге. Если карточки кончились, новую книгу не принять, хотя полки пусты. Так и здесь: в inode хранятся владелец, права и положение данных файла, а само содержимое лежит отдельно. Файл на 1 байт и файл на 1 ГБ занимают по одному inode.

В файловой системе ext4, которая стоит на большинстве серверов, число inode задаётся при её создании. Обычно оно считается из размера диска - примерно один inode на 16 КиБ, - то есть на обычной нагрузке хватает с запасом. Но если приложение плодит миллионы крошечных файлов, лимит выбирается раньше, чем место.

Как это выглядит

Чтобы показать симптом без поломки настоящего диска, мы создали временный диск в памяти (tmpfs) на 64 МБ и сами ограничили его двумя тысячами inode. Это имитация: у реального ext4 лимит задаётся при создании, мы просто выставили его вручную. Так сервер выглядит до проблемы:

df -h считает байты, df -i - inode. Это две разные шкалы, и вторую почти никто не смотрит, пока не случится беда. Теперь заполним диск пустыми файлами, как это делает приложение, которое не чистит за собой временные файлы. Создалось 1998 штук. Следующий файл не создаётся:

Теперь смотрим на диск в обоих режимах:

В колонке Avail по-прежнему 64 МБ, а в колонке IFree ноль. Это и есть главный признак: df -h пустой, df -i на 100%. Нет смысла искать большие файлы - они не виноваты.

Как найти каталог-виновник

Нужно понять, где лежит множество мелких файлов. Для этого у du есть ключ --inodes: он считает не размер, а число объектов. Остальные ключи: -x - не заходить на другие файловые системы, -d1 - глубина один уровень. sort -rn ставит самые большие числа первыми, head оставляет начало списка. Проверяем нужную точку монтирования (на реальном сервере обычно /, /var или /home):

Первая строка - итог по каталогу, а вторая показывает, кто съел почти всё: каталог sessions. Дальше спускаемся ниже тем же способом, пока не найдём конкретное место. На боевых серверах чаще всего это каталоги сессий PHP, кэш приложения, очередь почты /var/spool и временные файлы в /tmp.

Как безопасно очистить

Прежде чем удалять, убедитесь, что файлы действительно временные: посмотрите, что за приложение их создаёт, и какие из них можно стереть. Если сомневаетесь - сначала переместите или заархивируйте.

Для миллионов файлов команда rm КАТАЛОГ/* не подходит: оболочка раскрывает звёздочку в огромный список, и rm отвечает ошибкой «Argument list too long». Вместо этого find сам обходит каталог и удаляет файлы по одному:

find /mnt/inode-demo/sessions -xdev -type f -name 'sess_1*' -delete

Разберём ключи. -xdev - не выходить за пределы одной файловой системы. -type f - только обычные файлы, каталоги не трогаем. -name 'sess_1*' - только файлы, имя которых начинается с sess_1 (в бою здесь может стоять, например, -mtime +7: старше семи дней). -delete - удалить найденное. Если сомневаетесь, сначала запустите команду без -delete: она просто покажет, что нашла.

Занято 45%, файлы создаются, ошибка ушла (0 - команда выполнилась успешно). Мы удалили только часть - и этого хватило. После этого нужно ещё вылечить причину, иначе через неделю всё повторится.

Как не допустить повторения

  • Включите очистку старых файлов у источника: у PHP это сборщик мусора сессий, у приложений - срок жизни кэша, у почты - лимит очереди.
  • Для временных файлов добавьте правило очистки: например, find /var/tmp -type f -mtime +7 -delete раз в сутки через cron.
  • Следите за IUse% так же, как за местом. Достаточно команды df -i в вашей проверке состояния сервера.
  • Если файлов всё равно много и мелких, выберите файловую систему под такую нагрузку или храните данные в базе. Число inode в ext4 потом не увеличить: придётся создавать файловую систему заново с другим числом inode.

Если при нехватке места сервер ещё и тормозит, смотрите разбор «Сервер тормозит», а за памятью следите по статье про OOM killer.

Частые вопросы

Почему «No space left on device», если df показывает свободное место?

Скорее всего, закончились inode. Запустите df -i: если IUse% равен 100%, дело в них. Если и там порядок, смотрите квоты и тома, но в первую очередь проверяйте inode.

Что такое inode?

Запись о файле или каталоге: владелец, права и где лежат данные. Один файл - один inode, независимо от размера.

Как найти каталог с огромным числом файлов?

Командой sudo du --inodes -x -d1 /var | sort -rn | head. Повторяйте её для найденного каталога, спускаясь вглубь, пока не найдёте источник.

Как удалить миллион файлов?

Через find КАТАЛОГ -type f -delete. Обычный rm * на таком объёме ответит «Argument list too long».

Итог

  • «No space left on device» при свободных байтах - почти всегда нехватка inode.
  • Проверка одной командой: df -i, смотрим IUse%.
  • Виновника ищем так: sudo du --inodes -x -d1 /var | sort -rn | head.
  • Чистим через find КАТАЛОГ -type f -delete, а не rm *; сначала запускаем без -delete.
  • Потом лечим причину: очистка сессий и кэша у источника и df -i в регулярной проверке.
PUBLISHED
6 октября 2026 г.
AUTHOR
HIP-HOSTING
LANGUAGES
EN · RU