Почему место не освободилось после удаления большого файла в Linux?

«Почему место не освободилось после удаления большого файла в Linux?» — вопрос из категории Linux, который задают на 24% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Диагностика: Первым делом нужно найти процесс, который удерживает удаленный файл.

# Самый распространенный способ
lsof +L1  # Покажет файлы с количеством ссылок <1 (удаленные)
# Или более конкретно:
lsof | grep deleted

# Альтернатива через /proc (полезно в контейнерах, где нет lsof)
for pid in /proc/[0-9]*; do ls -la $pid/fd 2>/dev/null | grep -q "(deleted)" && echo "PID: ${pid##*/}"; done

Вывод покажет PID процесса и номер файлового дескриптора (FD). Часто это лог-файлы, которые продолжает писать приложение (например, Java-процесс, nginx, база данных), после того как лог был удален администратором.

Решение:

  1. Идеальный вариант: Аккуратно перезапустить или остановить зависящий процесс (например, отправив сигнал SIGHUP для реконфигурации или выполни graceful restart сервиса).
  2. Если перезапуск невозможен: Можно вручную очистить содержимое файла через его дескриптор в /proc, что освободит место, но процесс продолжит писать "в ноль".
    # Предположим, PID=1234, FD=5
    > /proc/1234/fd/5  # Очистка файла через перенаправление пустого вывода
    # ИЛИ
    cat /dev/null > /proc/1234/fd/5

    Важно: Это временное решение, основное — переконфигурировать приложение на запись в новый корректный файл.

Для DevOps: Чтобы предотвратить эту проблему, мы настраиваем log rotation (через logrotate) с опцией copytruncate или create и отправляем сигнал приложению для переоткрытия логов. Также важно мониторить использование диска и иметь алерты, которые сработают ДО полного заполнения.