Ответ
Основная причина — удалённый файл всё ещё удерживается открытым дескриптором работающего процесса. В Linux место на диске освобождается только после того, как все жёсткие ссылки на файл удалены и все открытые дескрипторы закрыты.
Типичные сценарии и решения:
-
Процесс держит файл открытым. Часто случается с демонами (nginx, app-server), которые пишут логи.
- Проверка:
lsof +L1илиlsof | grep deletedпокажет процессы и размер удалённых, но открытых файлов. - Решение: Отправить процессу сигнал для переоткрытия логов (например,
systemctl reload nginxилиkill -HUP <PID>). Полный перезапуст (restart) также решит проблему.
- Проверка:
-
Использование logrotate без copytruncate. По умолчанию
logrotateсоздаёт копию лога и просит процесс переоткрыть файл. Если процесс этого не делает (не поддерживает сигнал), старый дескриптор остаётся.- Решение: В конфигурации
logrotateдля проблемного сервиса используйте директивуcopytruncate. Она копирует файл, а затем обрезает оригинал до нуля, не требуя от процесса переоткрытия./var/log/myapp.log { daily rotate 7 copytruncate # Ключевая директива missingok }
- Решение: В конфигурации
-
Монтирование в пространство имён контейнера. Файл может быть удалён внутри контейнера, но оставаться открытым на хосте.
Порядок диагностики:
df -h— показывает «занятое» место, включая файлы с открытыми дескрипторами.du -sh /var/log/— показывает реальный размер файлов в директории. Еслиdfпоказывает много занятого, аdu— мало, это явный признак проблемы.lsof | grep deleted— найти виновника.- Принять меры (перезагрузка,
copytruncate, очистка диска от других файлов).