Encuentra directorios con muchos archivos en

33

Entonces, un cliente mío recibió un correo electrónico de Linode hoy diciendo que su servidor estaba haciendo explotar el servicio de respaldo de Linode. ¿Por qué? Demasiados archivos Me reí y luego corrí:

# df -ih
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/xvda        2.5M  2.4M   91K   97% /

Mierda. 2,4 millones de inodos en uso. ¿Qué demonios ha estado pasando?

He buscado los sospechosos obvios ( /var/{log,cache}y el directorio desde donde están alojados todos los sitios) pero no encuentro nada realmente sospechoso. En algún lugar de esta bestia, estoy seguro de que hay un directorio que contiene un par de millones de archivos.

Para el contexto uno de mis mis servidores ocupados utiliza 200k inodos y mi escritorio (una vieja instalación con más de 4 TB de almacenamiento ocasión) es sólo algo más de un millón. Hay un problema.

Entonces mi pregunta es, ¿cómo puedo encontrar dónde está el problema? ¿Hay un dupara inodes?

Oli
fuente
1
ejecuta vmstat -1 100 y muéstranos algo de eso. tenga cuidado con un gran número en CS (cambio de contexto). A veces, un sistema de archivos que falla puede perder muchos inodes por errores. O tal vez legítimamente, hay muchos archivos. Este enlace debe informarle sobre archivos e inodes. stackoverflow.com/questions/653096/howto-free-inode-usage puede que necesite ver qué se está ejecutando / abrir con el comando lsof.
j0h

Respuestas:

23

Verifique /lost+founden caso de que haya un problema de disco y se haya detectado una gran cantidad de basura como archivos separados, posiblemente de forma incorrecta.

Verifique iostatsi alguna aplicación todavía produce archivos como locos.

find / -xdev -type d -size +100kle dirá si hay un directorio que usa más de 100kB de espacio en disco. Ese sería un directorio que contiene muchos archivos, o que contenía muchos archivos en el pasado. Es posible que desee ajustar la figura del tamaño.

No creo que haya una combinación de opciones para GNU dupara que cuente 1 por entrada de directorio. Puede hacerlo produciendo la lista de archivos findy contando un poco en awk. Aquí hay una dupara inodes. Probado mínimamente, no intenta hacer frente a los nombres de archivo que contienen nuevas líneas.

#!/bin/sh
find "$@" -xdev -depth | awk '{
    depth = $0; gsub(/[^\/]/, "", depth); depth = length(depth);
    if (depth < previous_depth) {
       # A non-empty directory: its predecessor was one of its files
       total[depth] += total[previous_depth];
       print total[previous_depth] + 1, $0;
       total[previous_depth] = 0;
    }
    ++total[depth];
    previous_depth = depth;
}
END { print total[0], "total"; }'

Uso: du-inodes /. Imprime una lista de directorios no vacíos con el recuento total de entradas en ellos y sus subdirectorios de forma recursiva. Redireccione la salida a un archivo y revísela a su gusto. sort -k1nr <root.du-inodes | headte dirá los mayores delincuentes.

Gilles 'SO- deja de ser malvado'
fuente
El guión da errores:awk: line 2: find: regular expression compile failed (bad class -- [], [^] or [) [^ awk: line 2: syntax error at or near ] `/tmp/tmpw99dhs': Permission denied
Radu Rădeanu
@ RaduRădeanu Ah, ya veo, usé una peculiaridad gawk que no funciona en otras versiones. He agregado una barra diagonal inversa que creo que es necesaria según POSIX.
Gilles 'SO- deja de ser malvado'
14

Puede verificar con este script:

#!/bin/bash

if [ $# -ne 1 ];then
  echo "Usage: `basename $0` DIRECTORY"
  exit 1
fi

echo "Wait a moment if you want a good top of the bushy folders..."

find "$@" -type d -print0 2>/dev/null | while IFS= read -r -d '' file; do 
    echo -e `ls -A "$file" 2>/dev/null | wc -l` "files in:\t $file"
done | sort -nr | head | awk '{print NR".", "\t", $0}'

exit 0

Esto imprime los 10 subdirectorios principales por conteo de archivos. Si desea una x superior, cambie headcon head -n x, donde xes un número natural mayor que 0.

Para obtener resultados 100% seguros, ejecute este script con privilegios de root:

top-tupido-carpetas

Radu Rădeanu
fuente
2019: levantado 10: read: Illegal option -d... borró la -dbandera de la readesperanza de que no pasara nada malo. Te avisará cuando termine de ejecutarse ...
Williams
3

A menudo más rápido que buscar, si su base de datos de localización está actualizada:

# locate '' | sed 's|/[^/]*$|/|g' | sort | uniq -c | sort -n | tee filesperdirectory.txt | tail

Esto descarga toda la base de datos de localización, elimina todo lo que haya pasado el último '/' en la ruta, luego la ordenación y "uniq -c" le dan el número de archivos / directorios por directorio. "sort -n" se canalizó a tail para obtener los diez directorios con más cosas en ellos.

Chad
fuente
+1: ¡usar la base de datos de localizar es una muy buena idea!
Max Beikirch
Cuando no pueda utilizar localizar por cualquier razón, ejecute find /path/to/parent -xdev > filelistprimero, luego dirija directamente para leer la entrada de esa lista.
gerrit
1

Otro sugiere:

http://www.iasptk.com/20314-ubuntu-find-large-files-fast-from-command-line

Use estas búsquedas para encontrar los archivos más grandes en su servidor.

Encuentra archivos de más de 1 GB

sudo find / -type f -size + 1000000k -exec ls -lh {} \;

Encuentra archivos de más de 100 MB

sudo find / -type f -size + 100000k -exec ls -lh {} \;

Encuentra archivos de más de 10 MB

sudo find / -type f -size + 10000k -exec ls -lh {} \;

La primera parte es el comando de búsqueda que utiliza el indicador "-size" para buscar archivos de diferentes tamaños medidos en kilobytes.

El último bit al final que comienza con "-exec" permite especificar un comando que queremos ejecutar en cada archivo que encontramos. Aquí el comando "ls -lh" para incluir toda la información que se ve al enumerar el contenido de un directorio. La h hacia el final es especialmente útil, ya que imprime el tamaño de cada archivo en un formato legible para humanos.

ptheo
fuente
2
Su problema es el alto uso de inodes, que apunta a muchos archivos más pequeños, no a archivos grandes.
UpTheCreek
0

Esto funcionó para mí cuando el otro falló en Android a través del shell:

find / -type d -exec sh -c "fc=\$(find '{}' -type f | wc -l); echo -e \"\$fc\t{}\"" \; | sort -nr | head -n25
Kevin Parker
fuente
0

Me gusta usar algo como du --inodes -d 1 encontrar un directorio que recursivamente o directamente contenga muchos archivos.

También me gusta esta respuesta: https://unix.stackexchange.com/a/123052

Para los perezosos, aquí está la esencia de esto:

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