Из-за временных ограничений на территории РФ наблюдаются проблемы с оплатой. Если платёж не проходит, оставьте запрос в службу поддержки.Служба поддержки работает 24/7 — мы всегда на связи по вопросам хостинга и серверов.Открыт прием заявок на аренду выделенных серверов и размещение оборудования в дата-центре.Напоминаем: рекомендуем включить резервное копирование для дополнительной защиты данных.Доступна новая линейка VPS/VDS с NVMe-дисками и увеличенной производительностью.Технические работы на части серверов завершены. Все сервисы работают в штатном режиме.
Статья6 мин чтенияПросмотры3

Файл удалён, но место не освободилось: диагностика с lsof

Как найти открытый удалённый файл с помощью lsof и проверить освобождение места. Реальный тест с двумя дескрипторами: почему du уменьшается сразу, а доступный объём по df растёт только после закрытия последнего FD.

Комментарии 0

Извлечённый накопитель, подключённый кабелем к компьютеру
В этой статье

Большой журнал удалили, но свободного места почти не прибавилось. В Linux это возможно: имя файла уже исчезло из каталога, а процесс продолжает держать его открытым. До закрытия последней ссылки ядра на такой объект занятые им блоки могут оставаться выделенными.

Подтвердите исходную ситуацию

Эта инструкция относится к Linux с установленной утилитой lsof. Права обычного пользователя могут ограничивать видимость чужих процессов. Если вы администрируете сервер, запускайте проверку с разрешёнными для вашей роли правами; иначе передайте задачу ответственному специалисту.

df -h /var

Запишите файловую систему и доступный объём. Путь /var приведён для примера: нужен именно тот том, на котором находился удалённый файл. Без этой привязки легко принять чужой временный файл за причину заполнения раздела сайта.

Найдите открытые файлы без имени

У lsof есть отбор по числу жёстких ссылок. Значение меньше единицы позволяет найти открытые файлы, удалённые из дерева каталогов:

lsof -nP +L1

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

Не складывайте каждую строку

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

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

Стендовый пример: один файл и два дескриптора

2 октября 2026 года мы воспроизвели эту ситуацию в отдельной тестовой среде Linux: ядро 6.18.44, lsof 4.95.0, GNU df/du 9.4, файловая система overlay. Python-процесс записал в обычный файл 64 MiB данных, выполнил fsync и сохранил два дескриптора одного файла через dup. Здесь нет клиентских данных и работающего сайта: пример показывает механизм удержания файла, а не результат очистки конкретного сервера.

До удаления имя held.log существовало в каталоге. Затем мы удалили именно это имя, сохранив открытыми оба дескриптора. Для проверки нужного процесса использовали команду ниже. Число 73809 — PID нашего теста; на своём сервере подставляют найденный PID. Параметр -a важен: он объединяет условия отбора через «и», поэтому остаются удалённые открытые файлы выбранного процесса.

lsof -nP -a -p 73809 +L1

COMMAND PID USER FD TYPE DEVICE SIZE NLINK NODE NAME

python3 73809 root 3u REG 0,27 67108864 0 1589490 …/held.log (deleted)

python3 73809 root 4u REG 0,27 67108864 0 1589490 …/held.log (deleted)

В примере сокращён только длинный путь в NAME; остальные значения взяты из реального вывода. FD 3u и 4u — разные дескрипторы, открытые для чтения и записи. REG означает обычный файл, NLINK 0 — отсутствие имён, указывающих на него. Совпадающие DEVICE 0,27 и NODE 1589490 показывают, что обе строки относятся к одному объекту. Смысл полей и отбора +L1 описан в руководстве lsof.

Чтобы проверить объём, мы сравнивали df и du на каждом шаге в байтах: df -B1 --output=source,fstype,size,used,avail,target для файловой системы тестового каталога и du -B1 -s для самого каталога. До создания файла каталог занимал 4096 байт. Это накладные расходы каталога, которые остаются после удаления файла.

Состояние теста

Открытые FD файла

du каталога, байт

Доступно по df, байт

Файл существует

3,4

67112960

27976044544

Имя файла удалено

3,4

4096

27976044544

Закрыт первый FD

4

4096

27976044544

Закрыт последний FD

нет

4096

28043153408

После удаления имени du перестал учитывать файл, но свободный объём по df не вырос. Закрытие первого дескриптора тоже не изменило df: второй продолжал удерживать тот же объект. После закрытия последнего дескриптора процессом строки исчезли из его вывода lsof, а доступный объём вырос ровно на 67108864 байта, то есть 64 MiB. Именно такую последовательность описывает unlink(2) в документации Linux.

Если сложить два значения SIZE из первоначального вывода, получится 128 MiB. В этом тесте это двойной подсчёт одного файла: его логический размер и выделенные блоки составляли 64 MiB. На другом сервере логический размер не равен гарантированно освобождаемому месту: разреженные файлы, особенности файловой системы и записи других процессов влияют на результат. Оценку подтверждают повторным df на том же томе, а не только столбцом SIZE/OFF.

Границы проверки: мы проверили один обычный файл без отображения в память и закрыли дескрипторы внутри собственного тестового процесса. Это не проверка поведения Nginx, СУБД, NFS, снимков или квот. В среде lsof также предупреждал о недоступной /dev/mqueue; поэтому пустой общий список не считаем доказательством полной проверки сервера. Для нашего файла наличие и исчезновение FD дополнительно проверены через /proc выбранного процесса. На рабочем сервере вывод нужно читать вместе с предупреждениями и правами доступа, а способ освобождения выбирать по документации приложения.

Следующее действие зависит от приложения

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

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

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

После штатного действия, выбранного администратором, повторите lsof -nP +L1 и замер свободного места на том же разделе. Исчезновение конкретного удерживаемого объекта вместе с ростом свободного объёма подтверждает гипотезу гораздо лучше, чем сам факт перезапуска службы.

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

Обсуждение 0

Делись опытом и задавай вопросы. Комментарии без ссылок появляются после проверки редактором.

Пока никто не написал. Начни обсуждение.