Encuentra dónde se usan los inodes

189

Así que recibí una advertencia de nuestro sistema de monitoreo en una de nuestras cajas de que el número de inodos libres en un sistema de archivos se estaba reduciendo.

df -i la salida muestra esto:

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

Como puede ver, la partición raíz utiliza el 81% de sus inodos.
Sospecho que todos se están utilizando en un solo directorio. Pero, ¿cómo puedo encontrar dónde está eso?

Patricio
fuente

Respuestas:

214

Vi esta pregunta en stackoverflow, pero no me gustaron las respuestas, y realmente es una pregunta que debería estar aquí en U&L de todos modos.

Básicamente se usa un inodo para cada archivo en el sistema de archivos. Por lo tanto, quedarse sin inodos generalmente significa que tienes muchos archivos pequeños por ahí. Entonces la pregunta realmente se convierte en "¿qué directorio tiene una gran cantidad de archivos?"

En este caso, el sistema de archivos que nos interesa es el sistema de archivos raíz /, por lo que podemos usar el siguiente comando:

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

Esto volcará una lista de cada directorio en el sistema de archivos con el prefijo de la cantidad de archivos (y subdirectorios) en ese directorio. Por lo tanto, el directorio con el mayor número de archivos estará en la parte inferior.

En mi caso, esto resulta lo siguiente:

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

Así que básicamente /var/spool/postfix/maildropestá consumiendo todos los inodes.

Tenga en cuenta que esta respuesta tiene tres advertencias en las que puedo pensar. No maneja adecuadamente nada con líneas nuevas en la ruta. Sé que mi sistema de archivos no tiene archivos con líneas nuevas, y dado que esto solo se usa para consumo humano, no vale la pena resolver el problema potencial (y siempre se puede reemplazar \ncon \0y usar sort -zarriba). Tampoco maneja si los archivos se extienden entre una gran cantidad de directorios. Sin embargo, esto no es probable, por lo que considero que el riesgo es aceptable. También contará los enlaces duros a un mismo archivo (por lo tanto, usando solo un inodo) varias veces. De nuevo, es poco probable que dé falsos positivos.


La razón clave por la que no me gustaron las respuestas de stackoverflow es que todas cruzan los límites del sistema de archivos. Dado que mi problema estaba en el sistema de archivos raíz, esto significa que atravesaría cada sistema de archivos montado. Lanzar -xdevlos comandos de búsqueda ni siquiera funcionaría correctamente.
Por ejemplo, la respuesta más votada es esta:

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

Si cambiamos esto en lugar de

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

a pesar de que /mnt/fooes un montaje, también es un directorio en el sistema de archivos raíz, por lo que aparecerá find . -mount -type dy luego ls -a $ipasará al , que se sumergirá en el montaje.

En findmi respuesta, en su lugar, se enumera el directorio de cada archivo en el montaje. Básicamente, con una estructura de archivos como:

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

terminamos con

/foo
/foo
/pop

Entonces solo tenemos que contar el número de líneas duplicadas.

Patricio
fuente
2
@MohsenPahlevanzadeh que no es parte de mi respuesta, estaba comentando por qué no me gusta la solución, ya que es una respuesta común a esta pregunta.
Patrick
77
El uso de un montaje de enlace es una forma más sólida de evitar buscar en otros sistemas de archivos, ya que permite el acceso a los archivos debajo de los puntos de montaje. Por ejemplo, imagine que creo 300,000 archivos debajo /tmpy luego el sistema está configurado para montar un tmpfs /tmp. Entonces no podrá encontrar los archivos findsolo. Senario improbable, pero vale la pena señalar.
Graeme
2
Ambos trabajos solo tuvieron que eliminar la ordenación porque la ordenación necesita crear un archivo cuando la salida es lo suficientemente grande, lo que no fue posible ya que llegué al 100% de uso de inodes.
qwertzguy
1
Tenga en cuenta que -printfparece ser una extensión de GNU para encontrar, ya que la versión BSD disponible en OS X no es compatible.
Xiong Chiamiov
1
La suposición de que todos los archivos están en un solo directorio es difícil. Muchos programas saben que muchos archivos en un solo directorio tienen un mal rendimiento y, por lo tanto
generan
26

Esto se vuelve a publicar desde aquí a instancias del autor de la pregunta:

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

Y si quieres permanecer en el mismo sistema de archivos que haces:

du --inodes -xS

Aquí hay un ejemplo de salida:

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

AHORA CON LS:

Varias personas mencionaron que no tienen coreutils actualizados y que la opción --inodes no está disponible para ellos. Entonces, aquí está 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

Si tiene curiosidad, el corazón y el alma de ese tedioso trozo de regexallí está reemplazando el filenamede cada uno de ls'slos resultados de búsqueda recursiva con el nombre del directorio en el que se encontró. A partir de ahí, solo es cuestión de apretar números de inodo repetidos y luego contar nombres de directorio repetidos y ordenarlos en consecuencia.

La -Uopción es especialmente útil con la clasificación, ya que específicamente no se clasifica, y en su lugar presenta la lista de directorios en orden original, o, en otras palabras, por inodenúmero.

Y, por supuesto, -1es increíblemente útil, ya que garantiza un único resultado por línea, independientemente de las posibles nuevas líneas incluidas en los nombres de archivo u otros problemas espectacularmente desafortunados que pueden ocurrir cuando intenta analizar una lista.

Y, por supuesto, -Apara todos y -ipara el inodo y -Rpara el recursivo y eso es todo.

El método subyacente a esto es que reemplazo cada uno de los nombres de archivo de ls con su nombre de directorio que contiene en sed. Después de eso ... Bueno, yo también estoy un poco confusa. Estoy bastante seguro de que está contando con precisión los archivos, como puede ver aquí:

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

Esto me proporciona resultados prácticamente idénticos 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:

Creo que la includecosa solo depende del directorio en el que se ve el programa al principio, porque son los mismos archivos y están vinculados. Un poco como la cosa de arriba. Sin embargo, podría estar equivocado al respecto, y agradezco la corrección ...

DU DEMO

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

Haga un directorio de prueba:

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

Algunos directorios secundarios:

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

Crea algunos archivos:

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

Algunos enlaces duros:

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

Mira los enlaces duros:

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

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

Se cuentan solo, pero sube un directorio ...

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

Luego ejecuté mi script de ejecución desde abajo y:

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

Y de Graeme:

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

Así que creo que esto muestra que la única forma de contar inodos es por inodo. Y debido a que contar archivos significa contar inodos, no puede contar doblemente inodos: para contar archivos con precisión, los inodos no pueden contarse más de una vez.

mikeserv
fuente
2
--inodes¿Qué versión agregada ? ¿Qué "variantes" / "sabores" / "posix-wannabes" / "implementaciones" / lo que sea que tenga?
n611x007
Ubuntu 14.04.5: du: opción no reconocida '--inodes'
Putnik
du (GNU coreutils) 8.23 ​​de 2014 lo tiene (está en mi obsoleto Debian Jessie). Debian> Ubuntu, perdón por ese juego de palabras: P Ubuntu tiene paquetes tan viejos ...
Daniel W.
6

Utilicé esta respuesta de SO Q&A titulada: ¿Dónde se usan todos mis inodes? cuando nuestro NAS se agotó hace unos 2 años:

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

Ejemplo

$ 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

Comprobación de los inodos del dispositivo

Dependiendo de su NAS, es posible que no ofrezca un dfcomando con todas las funciones . Entonces, en estos casos, puede recurrir a usar en su tune2fslugar:

$ 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

Cruzando los límites del sistema de archivos

Puede usar el -xdevinterruptor para dirigir findla búsqueda restringida solo al dispositivo donde está iniciando la búsqueda.

Ejemplo

Digamos que tengo mi /homedirectorio de montaje automático a través de recursos compartidos NFS desde mi NAS, cuyo nombre es mulder.

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

Tenga en cuenta que el punto de montaje todavía se considera local para el sistema.

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

Ahora cuando inicio find:

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

¡No encontró /homeninguno de los contenidos montados automáticamente porque están en un dispositivo diferente!

Tipos de sistema de archivos

Usted puede utilizar el interruptor para find, -fstypepara controlar qué tipo de sistemas de archivos findestudiará.

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

Ejemplo

¿Qué sistema de archivos tengo?

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

Entonces puedes usar esto para controlar el cruce:

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 y 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
slm
fuente
¿Cuál sería su solución para evitar que cruce los límites del sistema de archivos? Al igual que si /está lleno, y tienes sistemas de archivos de red montados, no quieres sumergirte en los sistemas de archivos de red.
Patrick
@Patrick: vea las actualizaciones, puede controlarlo usando -fstypeto find.
slm
1
@Gilles - respuesta simple ... no pasó página en la página de manual de find 8-)
slm
@Gilles: la página de manual no parece indicar que -xtypeexcluye los sistemas de archivos, sino que busca mirar el tipo de archivo. Solo estoy encontrando ejemplos como este:find . \( -fstype nfs -prune \)
slm
@Gilles: me dirigía a la Q de Patrick en los comentarios sobre cómo evitar findcruzar los límites del sistema de archivos. En su ex. menciona "Me gusta si está lleno, y tienes sistemas de archivos de red montados, no quieres sumergirte en los sistemas de archivos de red".
slm
4

Comando para encontrar el inodo utilizado:

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

Para enumerar el uso detallado del inodo para /, use el siguiente 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" 
usuario108434
fuente
¡Bienvenido! Sugiero, la próxima vez mejor formato, por favor.
Peter
1
Es una línea, no veo nada malo en eso.
sjas
2

Definitivamente responda con la máxima cantidad de votos positivos para ayudar a comprender el concepto de inodes en Linux y Unix, sin embargo, realmente no ayuda cuando se trata de resolver el problema real de eliminar o eliminar los inodes del disco. Una forma más sencilla de hacer esto en sistemas basados ​​en ubuntu es eliminar los encabezados e imágenes no deseadas del kernel de Linux.

sudo apt-get autoremove

Haría eso por ti. En mi caso, el uso de inodes fue del 78% debido a lo cual recibí una alerta.

$ 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

Después de ejecutar el sudo apt-get autoremovecomando se había reducido 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

Esta fue solo mi observación que me ahorró tiempo. La gente puede encontrar una solución mejor que esta.

Shailesh Sutar
fuente
2

Me resulta más rápido y fácil profundizar usando el siguiente comando:

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

170202  var
157325  opt
103134  usr
53383   tmp
<snip>

Luego puede ir a, varpor ejemplo, y ver cuál es el gran inodo que usa directorios allí.

JonoB
fuente
0

Cada respuesta hasta ahora asume que el problema es con muchos archivos en un solo directorio, en lugar de muchos subdirectorios que contribuyen al problema. Afortunadamente, la solución es simplemente usar menos banderas.

# 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 opciones más cortas: du --inodes -x | sort -n. Lamentablemente, no todas las versiones dutienen la opción de inodes.

OrangeDog
fuente