Powrót do strony głównej

df du różnią się: znaleźć usunięte pliki Linux

W Linux rozbieżność df i du powstaje z powodu usuniętych plików, trzymanych przez otwarte deskryptory procesów. Artykuł wyjaśnia mechanizm inode, wyszukiwanie przez lsof +L1 i zwolnienie miejsca poleceniem > /proc/PID/fd/FD bez restartu. Zalecenia dotyczące logrotate copytruncate i monitoringu.

df kłamie? Nie, szukajcie deleted plików w lsof
Advertisement 728x90

Dlaczego df i du się różnią: poszukiwanie ukrytych gigabajtów w systemie Linux

Polecenie df -h pokazuje 95% zajętości dysku, a du -sh /* sumuje jedynie 20%. Pozostałe 75% jest niewidoczne dla du, ale zajmuje bloki na dysku. Przyczyną są otwarte deskryptory plików procesów do usuniętych plików. df odczytuje superblok systemu plików bezpośrednio, du przechodzi przez drzewo katalogowe i ignoruje pliki bez wpisów w nim.

Inode przechowuje metadane pliku, w tym listę bloków danych. rm usuwa tylko wpis w katalogu (hard link), licznik odwołań inode spada, ale jeśli proces trzyma deskryptor, bloki pozostają przydzielone.

Schemat:

Google AdInline article slot
Przed rm:
katalog        inode          bloki
/var/log/  --> app.log  -->  [blok1][blok2]
               ^
               deskryptor nginx (pid 1234, fd 7)

Po rm:
katalog        inode          bloki
/var/log/  --> (usunięto) -->  [blok1][blok2]
               ^
               deskryptor nginx

du nie widzi pliku w /var/log/, df rejestruje zajęte bloki.

Klasyczne przypadki problemu

Rotacja logów: logrotate wykonuje rm starego pliku, ale nginx lub java trzyma deskryptor od momentu uruchomienia. Proces zapisuje do usuniętego pliku, df rejestruje wzrost zajętości, du — nie.

Inne scenariusze:

Google AdInline article slot
  • Długożyjące demony z otwartymi logami.
  • Błędy w skryptach czyszczenia, gdzie rm poprzedza zamknięcie deskryptora.
  • Kontenery Docker, gdzie procesy wewnątrz trzymają pliki hosta.

Problem narasta: gigabajty znikają niezauważenie, aż dysk się zapełni.

Poszukiwanie procesów z usuniętymi plikami

Użyj lsof +L1 dla plików z NLINK < 1 (usunięte z FS, ale otwarte):

COMMAND  PID  USER  FD  TYPE  DEVICE  SIZE/OFF  NLINK  NODE  NAME
nginx   1234  www   7w  REG   8,1  2147483648  0  12345  /var/log/app.log (deleted)
java    5678  app   3w  REG   8,1   536870912  0  67890  /var/log/service.log (deleted)

Kluczowe pola:

Google AdInline article slot
  • COMMAND/PID: proces i ID.
  • FD: deskryptor (7w — zapis, numer 7).
  • SIZE/OFF: rozmiar — źródło utraconych GB.
  • NLINK=0: potwierdzenie usunięcia.
  • NAME (deleted): ścieżka przed rm.

Filtr według rozmiaru: lsof +L1 | awk '$7 > 104857600 {print}' (pliki >100MB).

Zwolnienie miejsca bez restartu

Dla procesu PID 1234, FD 7:

$ > /proc/1234/fd/7

/proc — procfs w pamięci. Polecenie zeruje plik przez deskryptor, jądro zwalnia bloki natychmiast. df się zaktualizuje, proces kontynuuje zapis do fd 7.

Sprawdź: lsof +L1 | grep 1234 — SIZE/OFF=0 lub pusto.

Automatyzacja skryptem:

#!/bin/bash
lsof +L1 | awk '$7 > 104857600 && $9 ~ /deleted/ {print $2, $8}' | while read pid fd; do
  echo "Zerujemy $pid/$fd"
  > /proc/$pid/fd/$fd
  echo "Zwolniono"
done

Zapobieganie problemowi w logrotate

Unikaj rm w rotacji. W /etc/logrotate.d/app:

/var/log/app.log {
    daily
    rotate 7
    compress
    copytruncate
}

copytruncate kopiuje log, następnie zeruje oryginał (mechanizm >). Deskryptor się nie zmienia.

Minus: mikrozatrzymanie kopiowania — możliwa utrata linii.

Alternatywa dla zero-loss:

  • logrotate: mv stary → nowy plik.
  • kill -HUP <pid> (SIGHUP dla reopen loga).

nginx: nginx -s reopen. systemd: systemctl reload nginx.

Monitorowanie i alerty

Skrypt do sprawdzania:

lsof +L1 -F s | awk '/^s/ && substr($0,2)+0 > 104857600 {count++} END {print count+0}'

Wypisuje liczbę usuniętych plików >100MB.

Integracja Prometheus:

  • node_filefd_allocated — wzrost otwartych fd.
  • Porównanie df/disk_used vs du sum.

Cron co 5 min: alert przy rozbieżności >10%.

Co jest ważne

  • df pokazuje przydzielone bloki superbloku, du — widoczne w katalogu pliki.
  • lsof +L1 znajduje procesy z (deleted) plikami po NLINK=0.
  • Zwolnić: > /proc/PID/fd/FD — zerowanie bez restartu.
  • logrotate copytruncate zapobiega problemowi bez HUP.
  • Monitorowanie: skrypty na lsof lub metryki node_exporter.

— Editorial Team

Advertisement 728x90

Czytaj dalej