du показывает 1 ГБ, а df — 10 ГБ занятыми на том же монтировании — диагностируйте
Срабатывает алерт мониторинга: файловая система /var заполнена на 90%, но сумма файлов в ней по du объясняет лишь малую долю занятого места. Два инструмента расходятся:
$ du -sh /var
1.0G /var
$ df -h /var
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 10G 9.0G 500M 95% /var
Новые файлы не появляются, перезапуск ничего пока не даёт, и разрыв сам не уйдёт.
Определите причину и скажите, как вернуть место.
Процесс держит открытый дескриптор на файл, удалённый из каталога. du обходит имена и больше его не видит, но блоки inode живут, пока открыт хоть один дескриптор, поэтому df всё ещё считает место. Найдите через lsof | grep deleted; верните место перезапуском или сигналом держащего процесса либо обнулив его дескриптор через /proc/<pid>/fd.
- ✗Запускать
fsckна живом монтировании вместо поиска процесса, держащего удалённый файл - ✗Считать, что место потеряно навсегда, а не удержано открытым дескриптором
- ✗Удалять ещё файлы, когда настоящий фикс — освободить или перезапустить держащий процесс
- →Почему обнуление
/proc/<pid>/fd/<n>освобождает место без убийства процесса? - →Какой распространённый сервис обычно вызывает это удалённым, но ещё пишущимся лог-файлом?
Что происходит
du и df считают занятое место по-разному:
duобходит дерево каталогов и суммирует размеры файлов, до которых может дойти по имени.dfспрашивает у файловой системы, сколько блоков помечено занятыми, независимо от того, ссылается ли на них ещё какое-то имя.
Когда процесс открыл файл, а файл затем удалили (unlink) из каталога, имя исчезает — но inode и его блоки остаются живыми, пока открыт хотя бы один дескриптор. du файл больше не видит, а df продолжает считать его блоки. Классический пример — сервис, который пишет в лог, лог удалили (или повернули неправильно), а сервис всё ещё держит дескриптор и пишет дальше.
Диагностика
# показать удалённые, но всё ещё открытые файлы
lsof | grep '(deleted)'
# пример строки: nginx 1234 www-data 5w REG 8,2 9663676416 /var/log/app.log (deleted)
Колонки дают PID (1234) и номер дескриптора (5).
Как вернуть место
# Вариант 1 — перезапустить/просигналить держащий процесс (закроет дескриптор)
systemctl restart nginx
# Вариант 2 — обнулить дескриптор, не убивая процесс
: > /proc/1234/fd/5
⚠️ fsck на смонтированной живой ФС не нужен и опасен — повреждения здесь нет.