No space left on device: почему на сервере закончилось место и как проверить inodes
Если при сохранении файла появляется No space left on device, сначала установите, куда и от чьего имени пишет приложение. Свободное место на одном разделе ничего не говорит о другом разделе, временном каталоге или квоте отдельного пользователя. Даже несколько свободных гигабайт не помогут создать файл, если для него нельзя выделить inode.
Практический ответ на запрос «no space left on device что делать» начинается с четырёх вопросов: какая операция отказала, какой путь она использовала, какая файловая система обслуживает этот путь и какой именно ресурс исчерпан. После этого можно выбрать ограниченное действие, сохранить полезные данные и проверить восстановление записи. Все пути, пользователи и числа ниже — учебные примеры; команды предназначены для чтения состояния Linux.
1. Найдите исходную ошибку, путь и пользователя процесса
За сообщением «на сервере нет места» могут скрываться разные отказы. Возьмите запись журнала приложения для конкретного неуспешного действия: загрузки изображения, создания отчёта, сохранения сессии. Нужны время, операция, полный путь и исходная системная ошибка. Сообщение в браузере или общий HTTP 500 этих сведений не заменяют.
| Ошибка | Что проверять первым |
|---|---|
| ENOSPC | Возможность выделить место для данных или нового файла на нужной файловой системе |
| EDQUOT | Исчерпание применимой квоты блоков или inode |
| EROFS | Запись в файловую систему, доступную только для чтения |
| EACCES | Права на файл и проход по каталогам пути |
Эти различия отражены в описании ошибок Linux open. Очистка диска сама по себе не исправляет отсутствие прав, а смена прав не добавляет свободных блоков. Если библиотека заменяет исходную ошибку общим текстом, разработчику нужно найти вложенную причину в журнале.
Зафиксируйте пользователя службы и её рабочее окружение. Проверка под административной учётной записью может пройти, хотя приложению мешает собственная квота или ограничение доступа. Не переносите успешный результат другого пользователя на отказавший процесс. Сохраните диагностические сведения до изменений: после очистки первоначальную причину иногда уже трудно восстановить.
2. Определите файловую систему именно для проблемного пути
Для существующего каталога, в котором приложение должно создать файл, определите точку монтирования. Если конечный файл ещё не появился, используйте его существующий родительский каталог. В примере это каталог загрузок:
findmnt -T /var/lib/site/uploads
Запишите источник, точку монтирования, тип файловой системы и параметры. Согласно документации findmnt, параметр -T позволяет определить файловую систему для заданного пути. Корневой раздел, каталог базы данных и каталог загрузок могут относиться к разным хранилищам.
Проследите весь путь операции. Загрузка иногда сначала сохраняется во временный каталог, затем обрабатывается и переносится в постоянный. Свободное место в конечном каталоге не поможет, если заполнен промежуточный. Аналогично отчёт может требовать места и для исходной выборки, и для готового архива.
В контейнере проверяйте окружение нужного приложения: его слой записи, подключённый том и временные каталоги могут отличаться от того, что видно в оболочке хоста. Для пути на tmpfs учитывайте отдельное ограничение этой файловой системы, а не только ёмкость диска. Передайте администратору конкретный путь и контекст процесса, чтобы он сопоставил их с реальным хранилищем.
Составьте небольшую карточку отказавшей операции: «служба обработки изображений, пользователь siteapp, входной временный каталог, выходной каталог, точки монтирования». Попросите разработчика подтвердить пути по действующей конфигурации. Имя каталога в инструкции прошлогоднего развёртывания может уже не соответствовать установленной версии. Если запрос обслуживают несколько экземпляров приложения, укажите, на каком именно экземпляре произошёл отказ и где выполнены измерения.
3. Посмотрите свободные блоки и inode отдельно
Выполните две проверки для того же существующего каталога:
df -h -- /var/lib/site/uploads
df -i -- /var/lib/site/uploads
Первая показывает использование дискового пространства; вторая — inode. В руководстве GNU df эти режимы разделены. Параметр -h использует степени 1024; обозначение G соответствует GiB. Сравнивайте одинаковые единицы и сохраняйте время измерения.
В первом отчёте смотрите доступное пространство, а во втором — число свободных inode и процент их использования. Проверяйте также источник и точку монтирования: похожие строки легко перепутать. Одна команда df -h не показывает ни остаток inode, ни все ограничения квот пользователя или проекта.
Полезны именно остатки, а не только проценты. Небольшой остаток может закончиться за минуты при массовом создании файлов. Если блоки и inode выглядят свободными, не объявляйте ошибку ложной: дальше проверяются квоты, фактический промежуточный путь и особенности конкретного хранилища. Для файловой системы, которая не предоставляет сопоставимую статистику inode, прочерк в отчёте не означает бесконечный запас.
4. Разберите случай, когда закончились inodes
Inode хранит служебную информацию об объекте файловой системы. Когда приложение создаёт множество небольших файлов, ограничение может проявиться раньше, чем закончится место для их содержимого. Поэтому удаление одного большого архива иногда освобождает много байтов, но почти не помогает ситуации с огромным количеством мелких файлов.
Проверьте каталоги файловых сессий, миниатюр, временных результатов и кеша. Ищите конкретный механизм появления объектов: новая копия при каждом запросе, уникальное имя без срока хранения, остановившийся сборщик устаревших записей. Важен не сам большой каталог, а нарушение его ожидаемого жизненного цикла.
Нельзя утверждать, что количество inode навсегда фиксировано для любой файловой системы. В частности, Red Hat описывает динамическое выделение inode в XFS. Способ выделения, ограничения и интерпретация статистики зависят от типа файловой системы. Сначала установите её тип, затем выбирайте дальнейшую диагностику.
Нехватка inode может мешать созданию новых объектов, пока некоторые изменения уже существующих файлов ещё проходят. Это не подтверждение нормальной работы: сайт может открывать старые страницы, но перестать принимать загрузки или сохранять новые сессии.
5. Проверьте квоты пользователя, группы и проекта
Свободное место всей файловой системы и разрешённый объём конкретной службы — разные величины. Запросите отчёт по квоте фактического пользователя приложения, применимой группы и, если используется, проекта. Проверять нужно и блоки, и inode. Отчёт другого пользователя не отвечает на вопрос, почему отказала запись сайта.
Документация Red Hat по квотам различает жёсткий предел и мягкий предел с периодом отсрочки. Истечение этой отсрочки также важно: вчера приложение могло записывать данные при том же превышении, а сегодня операция уже блокируется.
Для XFS возможна квота проекта, связанная с деревом каталогов. Её нельзя заменить проверкой одного пользователя. Устройство таких ограничений и средства отчёта описаны в руководстве по квотам XFS. Конкретную команду выбирают по файловой системе и уже действующей конфигурации.
Учебный пример: на разделе свободны 8 GiB и достаточно inode, но пользователь службы достиг жёсткого лимита 2 GiB. Освобождение чужого каталога на этом разделе не уменьшит его собственное использование. Нужно определить, какие данные учитываются в нужной квоте, и согласовать очистку или обоснованное изменение лимита.
6. Найдите источник роста ограниченным обходом
Начинайте с известного каталога приложения, относящегося к проблемной файловой системе:
du -xh --max-depth=1 -- /var/lib/site
du --inodes -x --max-depth=1 -- /var/lib/site
Первый вариант помогает искать потребителей пространства, второй — каталоги с большим использованием inode. Это синтаксис GNU du; в минимальном контейнере набор параметров может отличаться. Значения -x, --inodes и --max-depth описаны в руководстве GNU du.
Параметр -x не даёт обходу перейти на другую файловую систему. При этом --max-depth=1 ограничивает глубину выводимых итогов, а не глубину работы, необходимой для подсчёта. Каталог с миллионами объектов всё равно может потребовать долгого обхода и заметной нагрузки на хранилище.
Сначала выберите подходящий момент и согласуйте обследуемое дерево. Затем углубляйтесь только в найденный подозрительный подкаталог. Ошибки доступа и исчезающие во время обхода файлы делают картину неполной; не скрывайте такие сообщения. Сравнение двух измерений одного дерева полезнее одиночного списка самых больших каталогов: оно показывает, кто продолжает расходовать ресурс.
7. Объясните расхождение df и du до очистки
df описывает файловую систему целиком, а du обходит доступные имена в выбранном дереве. Если просканировать только каталог сайта, в результат не попадут соседние журналы или резервные копии на том же разделе. Разный момент измерения тоже меняет итог на активно работающем сервере.
В FAQ GNU Coreutils отдельно разобраны служебные расходы файловой системы и удалённые файлы, которые остаются открытыми. Поэтому несовпадение двух чисел само по себе не свидетельствует о повреждении диска.
Проверьте единицы, область обхода и сообщения об ошибках. Не смешивайте логическую длину файлов с занятыми блоками: для разреженных файлов эти значения могут сильно отличаться. Жёсткие ссылки также требуют аккуратного подсчёта, а снимки, совместно используемые блоки и сжатие добавляют особенности конкретного хранилища.
Практическое решение — выписать, что каждый отчёт действительно охватывает. Если разница объясняется недоступным каталогом, нужен просмотр с подходящими правами. Если подозрение падает на удалённые открытые файлы, дальнейший обход директорий их не найдёт: нужно перейти к процессам, которые удерживают данные.
8. Найдите удалённые файлы, которые ещё открыты
Удаление имени журнала не обязательно освобождает его пространство. Если процесс продолжает держать файл открытым, данные остаются занятыми, хотя обычный обход каталога уже не показывает прежнее имя. Поэтому попытка «удалить ещё несколько больших файлов» может лишь уничтожить полезные сведения.
Для заранее установленного процесса можно использовать ограниченную проверку:
lsof -nP -a -p 12345 +L1
Здесь 12345 — учебный PID, который заменяют идентификатором нужной службы. В документации lsof выборка +L1 предназначена для открытых файлов без оставшихся жёстких ссылок; -a объединяет условия отбора. Видимость зависит от прав и окружения процесса.
Установите владельца файла и причину, по которой он не был закрыт. Для журнала может потребоваться штатное переоткрытие, предусмотренное службой. Плановый перезапуск допустим только с пониманием влияния на запросы и незавершённые операции. Файлы базы данных нельзя трактовать как расходный кеш.
Не суммируйте все строки как независимые файлы: один объект бывает открыт несколькими дескрипторами или процессами. После согласованного действия проверьте фактическое освобождение пространства. Само исчезновение одной строки из отчёта ещё не доказывает, что все удерживавшие файл обращения закрыты.
9. Оцените скорость роста на учебном примере
Допустим, два измерения одной файловой системы дали такие значения. Для примера считаем ресурс inode ограниченным, квоты не достигнутыми, а нагрузку между измерениями сопоставимой.
| Время | Свободное пространство | Свободные inode |
|---|---|---|
| 10:00 | 6 GiB | 120 000 |
| 11:00 | 5,5 GiB | 90 000 |
За час израсходованы 0,5 GiB и 30 000 inode. При сохранении такого темпа остатка блоков хватило бы примерно на 11 часов: 5,5 / 0,5. Остатка inode хватило бы на 3 часа: 90 000 / 30 000. Значит, в этой модели первым ограничением становится количество объектов, и удаление только нескольких крупных файлов задачу не решает.
Это оценка для принятия решения, а не обещание времени до отказа. Ночной импорт, очистка кеша или изменение поведения программы меняют темп. При наличии другого лимита он может сработать раньше обоих расчётов.
Теперь связывайте рост с работой системы. Какие задания запускались между измерениями? Изменились ли правила хранения временных результатов? Не стала ли повторяющаяся ошибка создавать отдельный файл на каждую попытку? Найденная причина должна объяснять наблюдаемый расход, а не просто совпадать с большим каталогом.
Разделите постоянные данные и результаты, которые можно воспроизвести. Например, рост оригиналов пользовательских загрузок требует иной политики хранения, чем накопление промежуточных миниатюр. Для каждого подозрительного дерева выясните ожидаемое количество объектов, срок жизни и ответственного за удаление. Если срок хранения настроен, проверьте последнее успешное выполнение очистки: наличие задания в расписании ещё не доказывает, что оно действительно завершалось.
10. Освободите ресурс через понятный жизненный цикл данных
Сначала ограничьте подтверждённый источник роста штатным способом: приостановите конкретный импорт, уменьшите поток диагностических данных или исправьте бесконечное создание временных результатов. Иначе очищенное место быстро исчезнет снова. При этом учитывайте, какие запросы или фоновые задачи временно перестанут выполняться.
Выберите данные с известным владельцем и сроком хранения. Для кеша используйте предусмотренную приложением очистку; для журналов — согласованную ротацию и политику хранения; для старых экспортов — подтверждённый список завершённых и ненужных результатов. Проверьте, не является ли выбранная копия единственной пригодной для восстановления.
Не удаляйте весь временный каталог, не обнуляйте произвольные журналы и не трогайте файлы базы данных вручную. Расширение файла хранилища, удаление сегментов или очистка служебных каталогов базы выполняются только её штатными средствами и по правилам конкретного продукта.
Перемещение файла в другую папку той же файловой системы не освобождает её ёмкость. Перенос на другое хранилище требует проверки копии, доступности назначения и ссылок приложения. Сжатие на заполненном разделе тоже не является гарантированным выходом: операции может понадобиться дополнительное рабочее место.
Если очистка не даёт достаточного запаса, администратор оценивает расширение хранилища или изменение квоты. Это отдельное изменение с проверкой результата. Оно должно сопровождаться исправлением причины роста, иначе лишь переносит следующий отказ.
Перед действием определите ожидаемый эффект: сколько блоков или inode оно должно вернуть и на какой файловой системе. После небольшой согласованной партии сравните измерения. Если эффект отсутствует, остановитесь и перепроверьте владельца данных, квоту и открытые файлы. Увеличение масштаба очистки без объяснения первого результата повышает риск потери данных и не делает диагноз точнее.
11. Подтвердите восстановление штатной операции
После освобождения ресурса повторите измерения для нужного пути и проверку квот. Затем проведите согласованный небольшой тест через само приложение под его обычной учётной записью. Пустой файл, созданный администратором в другом каталоге, не проверяет загрузку, обработку и сохранение пользовательского объекта.
Тест должен пройти те же промежуточные каталоги и этапы, которые отказали. Проверьте создание результата, ожидаемый размер, возможность повторного чтения и завершение операции без новых ошибок. Для базы данных проверяется штатное сохранение с подтверждением транзакции, а не ручная запись в её каталог.
Документация Linux write предупреждает о частичной записи и об ошибках, которые могут проявиться позднее. Поэтому одного сообщения «файл открыт» недостаточно: важно успешное завершение предусмотренного приложением протокола сохранения.
Разберите задания, остановившиеся во время отказа. Часть могла сохранить данные частично или успеть выполнить внешнее действие до ошибки локальной записи. Повторяйте их по правилам приложения, учитывая дубли и уже достигнутый результат. После теста наблюдайте остаток ресурса ещё на рабочей нагрузке: восстановление одной операции не объясняет, устранён ли источник роста.
Критерий завершения инцидента запишите заранее: нужная операция проходит, результат читается, очередь отложенных задач обрабатывается без повторяющейся ошибки, запас ресурса больше согласованного минимума. Если восстановилась только часть функций, перечислите оставшиеся ограничения. Это позволит поддержке корректно отвечать пользователям и не обещать восстановление загрузок только потому, что снова открылась главная страница.
12. Настройте контроль запаса и понятную ответственность
Для каждого важного пути зафиксируйте файловую систему, владельца данных, пользователя службы, применимые квоты и механизм очистки. Контролируйте свободные блоки и inode отдельно, а пороги выбирайте с учётом скорости роста и времени реакции команды. Большой процент свободного места бесполезен, если очередная задача расходует весь остаток быстрее, чем приходит дежурный.
В рабочей инструкции оставьте короткую последовательность: исходная ошибка, путь, точка монтирования, блоки, inode, квоты, источник роста, согласованное действие и проверка записи. Приложите результаты измерений до и после восстановления. Так следующий специалист сможет продолжить диагностику, не угадывая, что уже меняли на сервере.
Контроль хранилища полезно дополнить внешним наблюдением за сайтом. Подключите SiteGuard для проверки HTTP-доступности важных страниц. Диск, inode и квоты проверяются отдельными средствами сервера; открывающаяся страница сама по себе не подтверждает, что приложение снова сохраняет данные.