📦Как найти удаленные файлы, которые все еще занимают место на диске |

📦Как найти удаленные файлы, которые все еще занимают место на диске

Мануал

df утверждает, что ваш диск заполнен на 80%, но du утверждает, что вы используете едва половину, так что один из них лжет, и, вероятно, это не тот, о котором вы думаете.

Вы отлаживаете оповещение о полном объеме диска в 2 часа ночи, и команда df отображается красным цветом, в то время как du / возвращается в полном порядке.

Вы запускаете обе команды 3 раза, думая, что что-то неправильно поняли.

Цифры не совпадают, и теперь вы сомневаетесь в своем собственном терминале.

Это происходит в производственных системах Linux чаще, чем вы могли бы ожидать, и обычно для исправления требуется всего 2 команды, как только вы поймете, что происходит на самом деле.

Вот в чем хитрость:

  • df проверяет фактическое использование файловой системы с самого диска.
  • du подсчитывает только файлы и каталоги, которые он может видеть в данный момент.

Таким образом, если процесс удалил огромный файл журнала, но все еще сохраняет его открытым, du больше не увидит этот файл, но df по-прежнему считает занимаемое пространство использованным.

Другие распространённые причины:

  • Зарезервированные блоки файловой системы.
  • Скрытые точки монтирования.
  • Открытые, но удалённые файлы.
  • Особенности работы в контейнерах или с оверлейными файловыми системами.

Числа выглядят некорректно, однако обе команды технически верны и просто измеряют использование диска разными способами.

df получает данные об использовании диска напрямую из метаданных файловой системы, обращаясь к суперблоку, в котором хранится информация о том, сколько блоков занято и сколько свободно.

Эта команда не сканирует каталоги и не анализирует отдельные файлы.

df просто запрашивает у ядра:

«Сколько блоков занято и сколько свободно на этом разделе?»

Команда du работает совершенно иначе: она проходит по дереву каталогов, начиная с указанного пути, проверяет каждый доступный файл и каталог и суммирует их размеры.

Поэтому, когда вы запускаете

du -sh /

Она учитывает только те файлы, которые всё ещё присутствуют в структуре каталогов.

Именно поэтому значения иногда не совпадают.

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

Однако du уже не видит этот файл, потому что его запись в каталоге исчезла.

С точки зрения файловой системы, место всё ещё занято. С точки зрения дерева каталогов — файла больше нет.

В этом и заключается разница между показаниями df и du.

Настоящая причина: удалённые, но всё ещё открытые файлы

Самая частая причина расхождений между df и du — это файлы, которые были удалены, но всё ещё открыты каким-либо процессом.

Когда процесс открывает файл, а вы удаляете его командой rm, Linux не освобождает дисковое пространство немедленно.

Вместо этого удаляется запись из каталога, и файл исчезает из видимой структуры файловой системы. Поэтому du больше не может его увидеть.

Однако сами данные остаются на диске.

Если какой-то процесс всё ещё держит этот файл открытым, ядро продолжает считать блоки, занятые этим файлом, выделенными. С точки зрения Linux, эти данные всё ещё используются.

В результате возникает такая «раздвоенная» картина:

  • du перестаёт учитывать этот файл, потому что он «исчез» из дерева каталогов.
  • df продолжает считать занятое им место, так как блоки всё ещё выделены.

Очень распространённый пример из практики — лог-файлы.

Приложение продолжает писать в лог-файл, вы удаляете его командой rm, чтобы освободить место, и кажется, что всё очистилось. Но если процесс не закрыл дескриптор файла, он продолжает писать в файл, у которого больше нет имени.

Результат:

  • du показывает, что использование диска уменьшилось.
  • df не фиксирует никаких изменений.
  • диск по-прежнему выглядит заполненным.

Место освобождается только тогда, когда процесс закрывает файл или перезапускается, потому что именно в этот момент ядро снимает последнюю ссылку и освобождает блоки.

Это одна из самых частых причин «невидимого» использования диска на производственных Linux-системах.

Если после очистки логов или удаления большого файла цифры использования диска выглядят совершенно некорректно, почти наверняка произошло именно это.

Как найти виновные процессы

Для этого вам понадобится инструмент lsof, который выводит список всех открытых файловых дескрипторов в системе.

Чтобы обнаружить файлы, которые были удалены, но всё ещё открыты, используйте следующую команду:

sudo lsof +L1

Этот фильтр ищет файлы, у которых число ссылок меньше 1, что обычно означает: файл был удалён, но всё ещё открыт каким-либо запущенным процессом.

Использование sudo здесь важно, потому что без него lsof показывает только файлы, открытые текущим пользователем. В этом случае вы не увидите большинство системных служб, демонов и производственных процессов, которые часто и являются причиной проблем с диском.

Если запустить команду без sudo и получить неполный вывод или ошибки доступа, это происходит именно по этой причине.

Типичный вывод выглядит так:

COMMAND     PID   USER   FD   TYPE DEVICE  SIZE/OFF NLINK NODE NAME
nginx      1423   root   10w   REG  253,1  524288000     0 1048 /var/log/nginx/access.log (deleted)
java       2201 tomcat   22w   REG  253,1  209715200     0 2341 /tmp/app.log (deleted)

Метка (deleted) в конце подтверждает, что у файла нет записи в каталоге.

В столбце SIZE/OFF указано, сколько места он всё ещё занимает.

В данном выводе nginx удерживает 500 МБ, которые du не видит, но которые полностью учитываются df.

Как только вы определили процесс, решение обычно заключается в его перезапуске или принудительном закрытии файлового дескриптора, что сразу освобождает место на диске.

Как освободить место без перезагрузки

У вас есть два варианта.

Первый — корректный, а второй — для экстренных случаев, когда нельзя перезапускать сервисы и нужно срочно освободить место.

Вариант 1. Перезапустить процесс, который держит файл открытым

Это самый безопасный и надёжный способ решения проблемы.

sudo systemctl restart nginx

При перезапуске службы все открытые файловые дескрипторы закрываются, после чего ядро освобождает блоки диска, и команда df сразу же отображает освобождённое пространство.

Используйте этот способ, если:

  • Служба допускает перезапуск.
  • Вам требуется чистое и предсказуемое восстановление.
  • Вы не хотите рисковать, работая с /proc.

Вариант 2: усечение файла через /proc — метод «без простоя»

Этот способ позволяет освободить место на диске, не останавливая службу.

Он особенно полезен, если перезапуск сервиса невозможен или нежелателен.

sudo truncate -s 0 /proc/1423/fd/10

Что делает эта команда

  • truncate -s 0 — устанавливает размер файла в ноль (очищает его).
  • /proc/1423/fd/10 — указывает на уже открытый файл внутри запущенного процесса.

Проверьте результат.

df -h /var/log

Пример вывода:

Filesystem      Size  Used Avail Use%  Mounted on
/dev/sda1        50G   18G   30G  38%  /

Пространство освобождается немедленно.

Процесс продолжает работать, его файловый дескриптор остаётся открытым, но в самом файле уже ничего нет.

Предупреждение: никогда не очищайте файлы через /proc, если это журнал упреждающей записи базы данных или любой другой файл, который процесс использует для восстановления после сбоя. Вы повредите данные. Этот приём безопасен только для обычных журналов приложений, где потеря содержимого допустима.

Ситуация Команда
Файловая система действительно заполнена? df -h
Что занимает всё место в этом каталоге? `du -sh *
Почему место не освобождается после удаления файлов? lsof +L1
Сколько места на самом деле занимает разреженный файл? du -sh (без --apparent-size)
Сколько места резервирует файловая система? tune2fs -l /dev/sdX

см. также:



Пожалуйста, не спамьте и никого не оскорбляйте. Это поле для комментариев, а не спамбокс. Рекламные ссылки не индексируются!
Добавить комментарий