Finden Sie Verzeichnisse mit vielen Dateien in


33

Ein Kunde von mir hat heute eine E-Mail von Linode erhalten, in der er mitteilt, dass sein Server Linodes Backup-Service in die Luft gejagt hat. Warum? Zu viele Dateien. Ich lachte und lief dann:

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

Mist. 2,4 Millionen Inodes im Einsatz. Was zum Teufel ist los ?!

Ich habe nach den offensichtlichen Verdächtigen gesucht ( /var/{log,cache}und nach dem Verzeichnis, in dem alle Websites gehostet werden), aber ich finde nichts wirklich Verdächtiges. Irgendwo auf diesem Biest gibt es bestimmt ein Verzeichnis, das ein paar Millionen Dateien enthält.

Für den ersten Kontext verwenden meine ausgelasteten Server 200.000 Inodes und mein Desktop (eine alte Installation mit mehr als 4 TB verwendetem Speicher) ist nur etwas mehr als eine Million. Es gibt ein Problem.

Meine Frage ist also, wo finde ich das Problem? Gibt es eine dufür Inodes?



1
Führen Sie vmstat -1 100 aus und zeigen Sie uns etwas davon. Vorsicht vor großer Anzahl in CS (Context Switching). Manchmal kann ein fehlerhaftes Dateisystem viele Inodes durch Fehler verlieren. Oder zu Recht gibt es viele Dateien. Dieser Link sollte Sie über Dateien und Inodes informieren. stackoverflow.com/questions/653096/howto-free-inode-usage Möglicherweise müssen Sie mit dem Befehl lsof sehen, was läuft / geöffnet ist.
03.07.13 Uhr

Antworten:


23

Überprüfen Sie, ob /lost+foundein Festplattenproblem aufgetreten ist und viele Junk-E-Mails möglicherweise fälschlicherweise als separate Dateien erkannt wurden.

Überprüfen Sie iostat, ob in einer Anwendung noch verrückte Dateien erstellt werden.

find / -xdev -type d -size +100kZeigt an, ob ein Verzeichnis mehr als 100 KB Speicherplatz belegt. Das wäre ein Verzeichnis, das viele Dateien enthält oder in der Vergangenheit viele Dateien enthielt. Möglicherweise möchten Sie die Größe anpassen.

Ich glaube nicht, dass es eine Kombination von Optionen gibt, mit denen GNU du1 pro Verzeichniseintrag zählt. Sie können dies tun, indem Sie die Dateiliste mit erstellen findund ein wenig in awk zählen. Hier ist ein dufür Inodes. Minimal getestet, versucht nicht mit Dateinamen umzugehen, die Zeilenumbrüche enthalten.

#!/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"; }'

Verbrauch: du-inodes /. Druckt eine Liste nicht leerer Verzeichnisse mit der Gesamtzahl der darin enthaltenen Einträge und deren Unterverzeichnisse rekursiv aus. Leiten Sie die Ausgabe in eine Datei um und prüfen Sie sie nach Belieben. sort -k1nr <root.du-inodes | headwird Ihnen die größten Straftäter erzählen.


Das Skript gibt Fehler: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, ich verstehe, ich habe eine Gawk-Besonderheit benutzt, die in anderen Versionen nicht funktioniert. Ich habe einen Backslash hinzugefügt, den ich gemäß POSIX für notwendig halte.
Gilles 'SO- hör auf böse zu sein'

14

Sie können mit diesem Skript überprüfen:

#!/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

Dies druckt die Top-10-Unterverzeichnisse nach Anzahl der Dateien. Wenn Sie ein Top-x wünschen, ändern Sie headmit head -n x, wobei xeine natürliche Zahl größer als 0 ist.

Führen Sie dieses Skript mit Root-Rechten aus, um 100% sichere Ergebnisse zu erzielen:

top-bushy-ordner


2019: angehoben 10: read: Illegal option -d... hat die -dFlagge von der readHoffnung befreit, dass nichts Schlimmes passieren wird. Lass es dich wissen, wenn es zu Ende ist ...
Williams

3

Oft schneller als zu finden, wenn Ihre Suchdatenbank auf dem neuesten Stand ist:

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

Dadurch wird die gesamte Suchdatenbank gesichert, alles nach dem letzten '/' im Pfad entfernt und durch Sortieren und "uniq -c" die Anzahl der Dateien / Verzeichnisse pro Verzeichnis ermittelt. "sort -n" wurde an tail weitergeleitet, um die zehn Verzeichnisse mit den meisten Dingen darin zu erhalten.


+1: die locate-Datenbank zu benutzen ist eine sehr nette Idee!
Max Beikirch

Wenn Sie locate aus irgendeinem Grund nicht verwenden können, führen Sie zunächst einen Befehl aus und weisen Sie find /path/to/parent -xdev > filelistsed an, Eingaben aus dieser Liste zu lesen.
Gerrit

1

Ein weiterer Vorschlag:

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

Verwenden Sie diese Suchvorgänge, um die größten Dateien auf Ihrem Server zu finden.

Finden Sie Dateien über 1 GB

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

Finden Sie Dateien über 100 MB

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

Finden Sie Dateien über 10 MB

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

Der erste Teil ist der Befehl find, der das Flag "-size" verwendet, um Dateien mit unterschiedlichen Größen in Kilobyte zu finden.

Das letzte Bit am Ende, das mit "-exec" beginnt, ermöglicht die Angabe eines Befehls, den wir für jede gefundene Datei ausführen möchten. Hier der Befehl "ls -lh", der alle Informationen enthält, die beim Auflisten des Inhalts eines Verzeichnisses angezeigt werden. Das h gegen Ende ist besonders hilfreich, da es die Größe jeder Datei in einem für Menschen lesbaren Format ausgibt.


2
Sein Problem ist die hohe Inode-Auslastung, die auf viele kleinere Dateien hinweist, nicht auf große.
UpTheCreek

0

Dies funktionierte für mich, als der andere auf Android durch die Shell gescheitert ist:

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

0

Ich nutze gerne so etwas wie du --inodes -d 1ein Verzeichnis zu finden, das entweder rekursiv oder direkt viele Dateien enthält.

Diese Antwort gefällt mir auch: https://unix.stackexchange.com/a/123052

Für die Faulen von uns ist hier der Kern davon:

du --inodes -S | sort -rh | sed -n \
    '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.