Trova dove vengono utilizzati gli inode


189

Quindi ho ricevuto un avviso dal nostro sistema di monitoraggio su una delle nostre scatole che il numero di inode gratuiti su un filesystem stava diventando basso.

df -i l'output mostra questo:

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

Come puoi vedere, la partizione di root ha l'81% dei suoi inode utilizzati.
Sospetto che vengano utilizzati tutti in un'unica directory. Ma come posso trovare dove si trova?

Risposte:


214

Ho visto questa domanda su StackOverflow, ma non mi piaceva nessuna delle risposte, ed è davvero una domanda che dovrebbe essere qui su U&L comunque.

Fondamentalmente viene usato un inode per ogni file sul filesystem. Quindi a corto di inode significa generalmente che ci sono molti piccoli file in giro. Quindi la domanda diventa davvero "quale directory contiene un gran numero di file?"

In questo caso, il filesystem a cui teniamo è il filesystem di root /, quindi possiamo usare il seguente comando:

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

Questo scaricherà un elenco di ogni directory sul filesystem con il prefisso con il numero di file (e sottodirectory) in quella directory. Quindi la directory con il maggior numero di file sarà in fondo.

Nel mio caso, questo mostra quanto segue:

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

Quindi sostanzialmente /var/spool/postfix/maildropsta consumando tutti gli inode.

Nota, questa risposta ha tre avvertimenti a cui posso pensare. Non gestisce correttamente nulla con le nuove righe nel percorso. So che il mio filesystem non ha file con newline e poiché questo è usato solo per il consumo umano, il potenziale problema non vale la pena risolverlo (e si può sempre sostituire il \ncon \0e usarlo sort -zsopra). Inoltre, non gestisce se i file sono distribuiti in un gran numero di directory. Tuttavia, ciò non è probabile, quindi considero accettabile il rischio. Conterà anche i collegamenti reali a uno stesso file (quindi utilizzando solo un inode) più volte. Ancora una volta, è improbabile che dia falsi positivi


Il motivo principale per cui non mi è piaciuta nessuna delle risposte sulla risposta stackoverflow è che attraversano tutti i confini del filesystem. Dato che il mio problema era nel filesystem di root, questo significa che avrebbe attraversato ogni singolo filesystem montato. Lanciare -xdevi comandi find non funzionerebbe nemmeno correttamente.
Ad esempio, la risposta più votata è questa:

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

Se invece lo cambiamo in

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

anche se /mnt/fooè un mount, è anche una directory sul filesystem di root, quindi si aprirà find . -mount -type de poi passerà al ls -a $i, che si tufferà nel mount.

La findmia risposta elenca invece la directory di ogni singolo file sul monte. Quindi sostanzialmente con una struttura di file come:

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

finiamo con

/foo
/foo
/pop

Quindi non ci resta che contare il numero di righe duplicate.


2
@MohsenPahlevanzadeh che non fa parte della mia risposta, stavo commentando perché non mi piace la soluzione in quanto è una risposta comune a questa domanda.
Patrick,

7
L'uso di un bind mount è un modo più efficace per evitare di cercare altri file system in quanto consente l'accesso ai file sotto i punti di mount. Ad esempio, immagina di creare 300.000 file sotto /tmpe poi il sistema è configurato per montare un tmpfs /tmp. Quindi non sarai in grado di trovare i file da findsolo. Senario improbabile, ma vale la pena notare.
Graeme,

2
Entrambi i lavori dovevano solo rimuovere l'ordinamento perché l'ordinamento ha bisogno di creare un file quando l'output è abbastanza grande, il che non è stato possibile da quando ho raggiunto il 100% di utilizzo degli inode.
qwertzguy,

1
Si noti che -printfsembra essere un'estensione GNU da trovare, poiché la versione BSD disponibile in OS X non la supporta.
Xiong Chiamiov,

1
L'ipotesi che tutti i file si trovino in una singola directory è difficile. Molti programmi sanno che molti file in una singola directory hanno cattive prestazioni e quindi hanno uno o due livelli di directory
PlasmaHH,

26

Questo viene ripubblicato da qui su richiesta del richiedente:

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

E se vuoi rimanere nello stesso filesystem fai:

du --inodes -xS

Ecco alcuni esempi di output:

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

ORA CON LS:

Diverse persone hanno affermato di non avere coreutils aggiornati e l'opzione --inodes non è disponibile per loro. Quindi, ecco 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

Se sei curioso, il cuore e l'anima di quel noioso pezzo di regexlì sta sostituendo il filenamein ognuno dei ls'srisultati di ricerca ricorsivi con il nome della directory in cui è stato trovato. Da lì si tratta solo di spremere numeri di inode ripetuti, quindi contare i nomi di directory ripetuti e ordinare di conseguenza.

L' -Uopzione è particolarmente utile con l'ordinamento in quanto non ordina in modo specifico e presenta invece l'elenco di directory nell'ordine originale o, in altre parole, in base al inodenumero.

E, naturalmente, -1è incredibilmente utile in quanto garantisce un singolo risultato per riga, indipendentemente da eventuali nuove righe incluse nei nomi dei file o da altri problemi incredibilmente sfortunati che potrebbero verificarsi quando si tenta di analizzare un elenco.

E ovviamente -Aper tutti e -iper inode e -Rricorsivi e questo è il lungo e il corto.

Il metodo alla base di questo è quello di sostituire tutti i nomi di file di ls con il nome della directory contenente in sed. In seguito a quello ... Beh, sono un po 'sfocato anch'io. Sono abbastanza certo che sta contando accuratamente i file, come puoi vedere qui:

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

Questo mi sta fornendo risultati praticamente identici al ducomando:

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:

Penso che la includecosa dipenda solo dalla directory in cui il programma guarda prima - perché sono gli stessi file e hardlinked. Piace la cosa sopra. Potrei sbagliarmi però - e accolgo con favore la correzione ...

DU DEMO

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

Crea una directory di prova:

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

Alcune directory per bambini:

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

Crea alcuni file:

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

Alcuni hardlink:

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

Guarda i collegamenti:

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

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

Sono contati da soli, ma vanno in alto di una directory ...

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

Quindi ho eseguito il mio script run dal basso e:

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

E Graeme's:

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

Quindi penso che ciò dimostri che l'unico modo per contare gli inode è l'inode. E poiché contare i file significa contare gli inode, non è possibile contare doppiamente gli inode - per contare i file con precisione gli inode non possono essere conteggiati più di una volta.


2
quale versione aggiunta --inodes? quali "varianti" / "sapori" / "posix-wannabes" / "implementazioni" / che cosa hanno?
n611x007,

Ubuntu 14.04.5: du: opzione non riconosciuta '--inodes'
Putnik

du (GNU coreutils) 8.23 ​​del 2014 ce l'ha (è nella mia Debian Jessie obsoleta). Debian> Ubuntu mi dispiace per quel gioco di parole: P Ubuntu ha pacchetti così vecchi ...
Daniel W.

6

Ho usato questa risposta dalle domande e risposte SO intitolata: Dove vengono utilizzati tutti i miei inode? quando il nostro NAS si è esaurito circa 2 anni fa:

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

Esempio

$ 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

Verifica degli Inodi del dispositivo

A seconda del NAS, potrebbe non offrire un dfcomando completo . Quindi in questi casi puoi ricorrere all'uso di tune2fs:

$ 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

Attraversare i confini del filesystem

Puoi utilizzare l' -xdevinterruttore per indirizzare findper restringere la ricerca solo al dispositivo in cui stai avviando la ricerca.

Esempio

Supponiamo di avere il mio /homeautomounting della directory tramite condivisioni NFS dal mio NAS, il cui nome è mulder.

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

Si noti che il punto di montaggio è ancora considerato locale per il sistema.

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

Ora quando inizio find:

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

Si è riscontrato /home, ma nessuno dei contenuti automaticamente che perché sono su un dispositivo diverso!

Tipi di filesystem

È possibile utilizzare l'interruttore per find, -fstypeper controllare quale tipo di filesystem di findesaminerà.

   -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.

Esempio

Che filesystem ho?

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

Quindi puoi usarlo per controllare l'attraversamento:

solo 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

solo nfs

$ find . -fstype nfs | head -5
$ 

ext3 ed 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

Quale sarebbe la tua soluzione per impedire che attraversi i confini del filesystem? Come se /fosse pieno, e hai montato filesystem di rete, non vorrai immergerti nel filesystem di rete.
Patrick,

@Patrick - vedi gli aggiornamenti, puoi controllarlo usando -fstypea find.
slm

1
@Gilles - semplice risposta ... non la pagina verso il basso fino in fondo pagina man di find 8-)
SLM

@Gilles - la pagina man non sembra indicare che -xtypeescluda i filesystem, sembra guardare il tipo di file. Sto solo trovando esempi come questo:find . \( -fstype nfs -prune \)
slm

@Gilles - Stavo affrontando la domanda di Patrick nei commenti su come evitare finddi oltrepassare i confini del filesystem. Nel suo ex. menziona "Come se / fosse pieno, e tu abbia montato i filesystem di rete, non vuoi tuffarti nei filesystem di rete".
slm

4

Comando per trovare l'inode utilizzato:

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

3

Per elencare l'utilizzo dettagliato dell'inode per /, usare il seguente comando:

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" 

Benvenuto qui! Suggerisco, la prossima volta meglio il formato, per favore.
Pietro,

1
È un oneliner, non vedo nulla di male in questo.
sjas,

2

Sicuramente rispondere con il massimo dei voti aiuta a comprendere il concetto di inode in Linux e Unix, ma non aiuta davvero quando si tratta di affrontare il problema reale dell'eliminazione o della rimozione degli inode dal disco. Un modo più semplice per farlo su sistemi basati su Ubuntu è rimuovere le intestazioni e le immagini del kernel Linux indesiderate.

sudo apt-get autoremove

Lo farebbe per te. Nel mio caso, l'utilizzo degli inode era al 78% a causa del quale ho ricevuto un avviso.

$ 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

Dopo aver eseguito il sudo apt-get autoremovecomando era sceso al 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

Questa è stata solo la mia osservazione che mi ha risparmiato tempo. Le persone potrebbero trovare una soluzione migliore di questa.


2

Trovo più rapido e semplice eseguire il drill down utilizzando il seguente comando:

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

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

Puoi quindi andare ad varesempio e vedere cosa c'è il grande inode usando le directory.


0

Ogni risposta finora presuppone che il problema riguardi molti file in una singola directory, anziché molte sottodirectory che contribuiscono al problema. Fortunatamente la soluzione è semplicemente usare un minor numero di 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

O con le opzioni più brevi: du --inodes -x | sort -n. Sfortunatamente non tutte le versioni di duhanno l'opzione inodes.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.