Znajdź, gdzie są używane i-węzły


189

Tak więc otrzymałem ostrzeżenie z naszego systemu monitorowania na jednym z naszych urządzeń, że liczba wolnych i-węzłów w systemie plików jest niska.

df -i wyjście pokazuje to:

Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/xvda1       524288 422613   101675   81% /

Jak widać, partycja główna ma 81% używanych i-węzłów.
Podejrzewam, że wszystkie są używane w jednym katalogu. Ale jak mogę znaleźć, gdzie to jest?

Odpowiedzi:


214

Widziałem to pytanie przy przepełnieniu stosu, ale nie podobała mi się żadna z odpowiedzi, a tak naprawdę to pytanie powinno być tutaj na U&L.

Zasadniczo dla każdego pliku w systemie plików używana jest i-węzeł. Skończyły się i-węzły, co oznacza, że ​​masz dużo małych plików. Tak naprawdę pytanie brzmi: „w którym katalogu znajduje się duża liczba plików?”

W tym przypadku systemem plików, na którym nam zależy, jest główny system plików /, więc możemy użyć następującego polecenia:

find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n

Spowoduje to zrzucenie listy każdego katalogu w systemie plików poprzedzonym liczbą plików (i podkatalogów) w tym katalogu. Tak więc katalog z największą liczbą plików będzie na dole.

W moim przypadku wygląda to następująco:

   1202 /usr/share/man/man1
   2714 /usr/share/man/man3
   2826 /var/lib/dpkg/info
 306588 /var/spool/postfix/maildrop

Więc w zasadzie /var/spool/postfix/maildropzużywa wszystkie i-węzły.

Uwaga: ta odpowiedź zawiera trzy zastrzeżenia, o których mogę myśleć. Nie obsługuje poprawnie niczego z nowymi liniami na ścieżce. Wiem, że mój system plików nie ma plików z nowej linii, a ponieważ jest to tylko wykorzystywane do spożycia przez ludzi, potencjalny problem nie jest wart rozwiązywania (i zawsze można wymienić \nze \0i używać sort -zpowyżej). Nie obsługuje również, jeśli pliki są rozproszone w dużej liczbie katalogów. Nie jest to jednak prawdopodobne, więc uważam ryzyko za dopuszczalne. Policzy również twarde linki do tego samego pliku (więc używając tylko jednego i-węzła) kilka razy. Ponownie mało prawdopodobne jest podanie fałszywych wyników pozytywnych


Głównym powodem, dla którego nie podobały mi się żadne odpowiedzi w odpowiedzi na przepełnienie stosu, jest to, że wszystkie przekraczają granice systemu plików. Ponieważ mój problem dotyczył głównego systemu plików, oznacza to, że przejdzie on przez każdy zamontowany system plików. Rzucanie -xdevkomend find nawet nie działałoby poprawnie.
Na przykład najbardziej pożądana odpowiedź to:

for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

Jeśli zamiast tego zmienimy to na

for i in `find . -xdev -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

mimo że /mnt/foojest to mount, jest to także katalog w głównym systemie plików, więc się pojawi find . -mount -type d, a następnie zostanie przekazany do ls -a $i, który zanurkuje w mount.

findW mojej odpowiedzi zamiast wymienia katalog każdego pojedynczego pliku na górze. Zasadniczo ze strukturą pliku, taką jak:

/foo/bar
/foo/baz
/pop/tart

kończymy z

/foo
/foo
/pop

Musimy tylko policzyć liczbę zduplikowanych linii.


2
@MohsenPahlevanzadeh, który nie jest częścią mojej odpowiedzi, komentowałem, dlaczego nie lubię rozwiązania, ponieważ jest to częsta odpowiedź na to pytanie.
Patrick

7
Korzystanie z podłączenia do łączenia jest bardziej niezawodnym sposobem uniknięcia przeszukiwania innych systemów plików, ponieważ umożliwia dostęp do plików w punktach podłączenia. Na przykład wyobraź sobie, że tworzę 300 000 plików, /tmpa następnie system jest skonfigurowany do montowania tmpfs /tmp. Wtedy nie będziesz w stanie znaleźć plików findsamodzielnie. Mało prawdopodobne, że senario, ale warte odnotowania.
Graeme

2
Obie prace musiały po prostu usunąć sort, ponieważ sort musi utworzyć plik, gdy wynik jest wystarczająco duży, co nie było możliwe, ponieważ osiągnąłem 100% użycie i-węzłów.
qwertzguy,

1
Zauważ, że -printfwydaje się być rozszerzeniem GNU do znalezienia, ponieważ wersja BSD dostępna w OS X go nie obsługuje.
Xiong Chiamiov

1
Założenie, że wszystkie pliki znajdują się w jednym katalogu, jest trudne. Wiele programów wie, że wiele plików w jednym katalogu ma
słabą

26

To jest odesłane stąd na żądanie pytającego:

du --inodes -S | sort -rh | sed -n \
        '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'

A jeśli chcesz pozostać w tym samym systemie plików, robisz:

du --inodes -xS

Oto kilka przykładowych danych wyjściowych:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
...
519     /usr/lib/python2.7/site-packages/bzrlib
516     /usr/include/KDE
498     /usr/include/qt/QtCore
487     /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484     /usr/src/linux-3.12.14-2-MANJARO/include/config

TERAZ Z LS:

Kilka osób wspomniało, że nie mają aktualnych coreutils, a opcja --inodes nie jest dla nich dostępna. Oto ls:

ls ~/test -AiR1U | 
sed -rn '/^[./]/{h;n;};G;
    s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|\1:\2|p' | 
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10

Jeśli jesteś ciekawy, serce i dusza tego nużącego fragmentu regexzastępuje filenamew każdym z ls'srekurencyjnych wyników wyszukiwania nazwą katalogu, w którym został znaleziony. Stamtąd wystarczy wycisnąć powtarzające się numery i-węzłów, a następnie policzyć powtarzające się nazwy katalogów i odpowiednio posortować.

-UOpcja jest szczególnie przydatna przy sortowania tym, że specjalnie nie nie sortowania, a zamiast tego zawiera listę katalogów w oryginalnej kolejności - czyli, innymi słowy, przez inodeliczbę.

I oczywiście -1jest niezwykle pomocny, ponieważ zapewnia pojedynczy wynik na linię, niezależnie od ewentualnego uwzględnienia nowych linii w nazwach plików lub innych spektakularnie niefortunnych problemów, które mogą wystąpić podczas próby analizy listy.

I oczywiście -Adla wszystkich, dla i- -iwęzłów i -Rrekurencyjnych, i to jest długa i krótka z tego.

Podstawową metodą tego jest to, że zastępuję każdą z nazw plików ls zawierającą nazwę katalogu w sed. Po tym ... Cóż, jestem trochę rozmyty. Jestem całkiem pewien, że dokładnie zlicza pliki, jak widać tutaj:

% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
>   2 /home/mikeserv/test
>   1 /home/mikeserv/test/linkdir

To zapewnia mi prawie identyczne wyniki z dupoleceniem:

DU:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
1.9K    /usr/share/fonts/100dpi
1.9K    /usr/share/doc/arch-wiki-markdown
1.6K    /usr/share/fonts/TTF
1.6K    /usr/share/dolphin-emu/sys/GameSettings
1.6K    /usr/share/doc/efl/html

LS:

14686   /usr/share/man/man3:
4322    /usr/lib:
3653    /usr/bin:
2457    /usr/share/man/man1:
1897    /usr/share/fonts/100dpi:
1897    /usr/share/fonts/75dpi:
1890    /usr/share/doc/arch-wiki-markdown:
1613    /usr/include:
1575    /usr/share/doc/efl/html:
1556    /usr/share/dolphin-emu/sys/GameSettings:

Myślę, że includerzecz zależy tylko od tego, który katalog najpierw program wygląda - ponieważ są to te same pliki i są połączone. Trochę jak powyższa rzecz. Mogę się jednak mylić - i z zadowoleniem przyjmuję korektę ...

DU DEMO

% du --version
> du (GNU coreutils) 8.22

Utwórz katalog testowy:

% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1       .

Niektóre katalogi dzieci:

% mkdir ./realdir ./linkdir
% du --inodes -S
> 1       ./realdir
> 1       ./linkdir
> 1       .

Zrób kilka plików:

% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Niektóre twarde linki:

% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` | 
    . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Spójrz na twarde linki:

% cd ./linkdir
% du --inodes -S
> 101

% cd ../realdir
% du --inodes -S
> 101

Są liczeni sami, ale idź o jeden katalog wyżej ...

% cd ..
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .

Następnie uruchomiłem mój uruchomiony skrypt od dołu i:

> 100     /home/mikeserv/test/realdir
> 100     /home/mikeserv/test/linkdir
> 2       /home/mikeserv/test

A Graeme's:

> 101 ./realdir
> 101 ./linkdir
> 3 ./

Myślę więc, że to pokazuje, że jedynym sposobem zliczania i-węzłów jest użycie i-węzła. A ponieważ zliczanie plików oznacza zliczanie i-węzłów, nie można podwójnie zliczać i-węzłów - aby dokładnie zliczyć pliki, nie można zliczyć więcej niż raz.


2
która wersja została dodana --inodes? które „warianty” / „smaki” / „posix-wannabes” / „implementacje” / cokolwiek to ma?
n611x007

Ubuntu 14.04.5: du: nierozpoznana opcja '--inodes'
Putnik

du (GNU coreutils) 8.23 ​​z 2014 roku ma to (jest w mojej nieaktualnej Debian Jessie). Debian> Ubuntu przepraszam za tę grę słów: P Ubuntu ma tak stare pakiety ...
Daniel W.

6

Użyłem odpowiedzi z SO Q&A zatytułowanej: Gdzie są używane wszystkie moje i-węzły? kiedy nasz NAS skończył się około 2 lata temu:

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n

Przykład

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n
...
110 ./MISC/nodejs/node-v0.8.12/out/Release/obj.target/v8_base/deps/v8/src
120 ./MISC/nodejs/node-v0.8.12/doc/api
123 ./apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios
208 ./MISC/nodejs/node-v0.8.12/deps/openssl/openssl/doc/crypto
328 ./MISC/nodejs/node-v0.8.12/deps/v8/src
453 ./MISC/nodejs/node-v0.8.12/test/simple

Sprawdzanie i-węzłów urządzenia

W zależności od serwera NAS może nie oferować w pełni funkcjonalnego dfpolecenia. W takich przypadkach możesz tune2fszamiast tego użyć :

$ sudo tune2fs -l /dev/sda1 |grep -i inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Inode count:              128016
Free inodes:              127696
Inodes per group:         2032
Inode blocks per group:   254
First inode:              11
Inode size:           128
Journal inode:            8
Journal backup:           inode blocks

Przekraczanie granic systemu plików

Możesz użyć -xdevprzełącznika, aby bezpośrednio findzawęzić wyszukiwanie do urządzenia, na którym inicjujesz wyszukiwanie.

Przykład

Powiedzmy, że mam automatyczne /homekatalogowanie katalogu za pośrednictwem udziałów NFS z mojego serwera NAS, którego nazwa to mulder.

$ df -h /home/sam 
Filesystem            Size  Used Avail Use% Mounted on
mulder:/export/raid1/home/sam
                      917G  572G  299G  66% /home/sam

Zauważ, że punkt podłączenia jest nadal uważany za lokalny dla systemu.

$ df -h /home/ .
Filesystem            Size  Used Avail Use% Mounted on
-                        0     0     0   -  /home
/dev/mapper/VolGroup00-LogVol00
                      222G  159G   52G  76% /

Teraz kiedy inicjuję find:

$ find / -xdev  | grep '^/home'
/home

Nie znaleziono, /homeale żadna z automatycznie zamontowanych treści, ponieważ są one na innym urządzeniu!

Typy systemów plików

Możesz użyć przełącznika do find, -fstypeaby kontrolować, jakiego rodzaju systemy plików findbędą sprawdzane.

   -fstype type
          File is on a filesystem of type type.  The valid filesystem types 
          vary among different versions of Unix; an incomplete list of 
          filesystem  types that are accepted on some version of Unix or 
          another is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K.  You can use 
          -printf with the %F directive to see the types of your
          filesystems.

Przykład

Jaki mam system plików?

$ find . -printf "%F\n" | sort -u
ext3

Możesz więc użyć tego do kontrolowania przejścia:

tylko ext3

$ find . -fstype ext3 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt

tylko nfs

$ find . -fstype nfs | head -5
$ 

ext3 i ext4

$ find . -fstype ext3 -o -fstype ext4 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt

Jakie byłoby twoje rozwiązanie, aby zapobiec przekroczeniu granic systemu plików? Jak jeśli /jest pełne, a masz podłączone sieciowe systemy plików, nie chcesz nurkować w sieciowych systemach plików.
Patrick

@Patrick - patrz aktualizacji, można ją kontrolować za pomocą -fstypecelu find.
slm

1
@Gilles - prosta odpowiedź ... nie przewijałem strony do końca w man's find strona 8-)
slm

@Gilles - strona podręcznika nie wydaje się wskazywać, że -xtypewyklucza systemy plików, wygląda na typ pliku. Znajduję tylko takie przykłady:find . \( -fstype nfs -prune \)
slm

@Gilles - zwracałem się do Q Patricka w komentarzach na temat tego, jak unikać findprzekraczania granic systemu plików. W jego byłej. wspomina: „Jeśli / jest pełny, a masz podłączone sieciowe systemy plików, nie chcesz nurkować w sieciowych systemach plików”.
slm

4

Polecenie znajdowania użytego i-węzła:

for i in /*; do echo $i; find $i |wc -l | sort ; done

3

Aby wyświetlić szczegółowe informacje na temat użycia i-węzła /, użyj następującego polecenia:

echo "Detailed Inode usage for: $(pwd)" ; for d in `find -maxdepth 1 -type d |cut -d\/ -f2 |grep -xv . |sort`; do c=$(find $d |wc -l) ; printf "$c\t\t- $d\n" ; done ; printf "Total: \t\t$(find $(pwd) | wc -l)\n" 

Witaj tutaj! Sugeruję, następnym razem lepiej sformatuj, proszę.
peterh

1
To oneliner, nie widzę w tym nic złego.
sjas

2

Zdecydowanie odpowiedź przy maksymalnej liczbie głosów pozytywnych pomaga zrozumieć pojęcie i-węzłów w Linuksie i Uniksie, jednak tak naprawdę nie pomaga, jeśli chodzi o rozwiązanie problemu usuwania lub usuwania i-węzłów z dysku. Prostszym sposobem na to w systemach opartych na Ubuntu jest usunięcie niechcianych nagłówków i obrazów jądra Linuxa.

sudo apt-get autoremove

Zrobiłbym to dla ciebie. W moim przypadku użycie i-węzłów wyniosło 78%, z powodu czego otrzymałem alert.

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 407957 116331   78% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

Po uruchomieniu sudo apt-get autoremovepolecenia spadł do 29%

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 150472 373816   29% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user

To tylko moja obserwacja pozwoliła mi zaoszczędzić czas. Ludzie mogą znaleźć jakieś lepsze rozwiązanie niż to.


2

Uważam, że szybsze i łatwiejsze jest drążenie w dół za pomocą następującego polecenia:

$ sudo du -s --inodes * | sort -rn

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

Możesz varna przykład przejść do i zobaczyć, jaki jest duży i-węzeł za pomocą katalogów.


0

Każda dotychczasowa odpowiedź zakłada, że ​​problem dotyczy wielu plików w jednym katalogu, zamiast wielu podkatalogów przyczyniających się do problemu. Na szczęście rozwiązaniem jest po prostu użycie mniejszej liczby flag.

# du --inodes --one-file-system /var | sort --numeric-sort
...
2265    /var/cache/salt/minion
3818    /var/lib/dpkg/info
3910    /var/lib/dpkg
4000    /var/cache/salt/master/gitfs/refs
4489    /var/lib
5709    /var/cache/salt/master/gitfs/hash
12954   /var/cache/salt/master/gitfs
225058  /var/cache/salt/master/jobs
241678  /var/cache/salt/master
243944  /var/cache/salt
244078  /var/cache
248949  /var

Lub z krótszymi opcji: du --inodes -x | sort -n. Niestety nie wszystkie wersje dumają opcję i-węzłów.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.