Hintergrund: Physischer Server, ungefähr zwei Jahre alt, SATA-Laufwerke mit 7200 U / min, die an eine 3Ware-RAID-Karte angeschlossen sind, ext3 FS-Mounted Noatime und Daten = bestellt, nicht unter verrückter Last, Kernel 2.6.18-92.1.22.el5, Betriebszeit 545 Tage . Directory enthält keine Unterverzeichnisse, nur Millionen kleiner (~ 100 Byte) Dateien, einige größere (ein paar KB).
Wir haben einen Server, der in den letzten Monaten ein bisschen kuckuck gegangen ist, aber wir haben ihn erst neulich bemerkt, als er anfing, nicht in ein Verzeichnis schreiben zu können, weil er zu viele Dateien enthielt. Insbesondere hat es begonnen, diesen Fehler in / var / log / messages auszulösen:
ext3_dx_add_entry: Directory index full!
Auf der fraglichen Festplatte sind noch viele Inodes vorhanden:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda3 60719104 3465660 57253444 6% /
Ich schätze, das heißt, wir haben das Limit erreicht, wie viele Einträge in der Verzeichnisdatei selbst sein können. Keine Ahnung, wie viele Dateien das sein würden, aber wie Sie sehen können, können es nicht mehr als drei Millionen sein. Nicht dass das gut wäre, wohlgemerkt! Aber das ist Teil einer meiner Fragen: Was genau ist diese Obergrenze? Ist es einstellbar? Bevor ich angeschrien werde - ich möchte es leiser stellen ; Dieses riesige Verzeichnis verursachte alle möglichen Probleme.
Wie auch immer, wir haben das Problem in dem Code aufgespürt, der all diese Dateien generiert hat, und wir haben es korrigiert. Jetzt stecke ich beim Löschen des Verzeichnisses fest.
Ein paar Möglichkeiten hier:
rm -rf (dir)
Ich habe es zuerst versucht. Ich gab es auf und tötete es, nachdem es anderthalb Tage ohne erkennbare Auswirkungen gelaufen war.
- Unlink (2) im Verzeichnis: Auf jeden Fall eine Überlegung wert, aber die Frage ist, ob es schneller wäre, die Dateien im Verzeichnis über fsck zu löschen, als über Unlink (2). Das heißt, auf die eine oder andere Weise muss ich diese Inodes als unbenutzt markieren. Dies setzt natürlich voraus, dass ich fsck anweisen kann, keine Einträge in den Dateien in / lost + found abzulegen. ansonsten habe ich gerade mein problem verschoben. Neben all den anderen Bedenken muss ich wahrscheinlich einige interne FS-Funktionen aufrufen, nachdem ich etwas mehr darüber gelesen habe, da keine der unlink (2) -Varianten, die ich finden kann, es mir erlauben würde, nur munter zu löschen ein Verzeichnis mit Einträgen darin. Pooh.
while [ true ]; do ls -Uf | head -n 10000 | xargs rm -f 2>/dev/null; done )
Dies ist eigentlich die gekürzte Version; Die eigentliche Version, die ich gerade ausführe und die nur einige Fortschrittsberichte und einen sauberen Stopp hinzufügt, wenn die zu löschenden Dateien ausgehen, ist:
export i = 0; time (while [wahr]; do ls -Uf | head -n 3 | grep -qF '.png' || brechen; ls -Uf | head -n 10000 | xargs rm -f 2> / dev / null; exportiere i = $ (($ i + 10000)); echo "$ i ..."; getan )
Dies scheint ziemlich gut zu funktionieren. Während ich das schreibe, hat es in den letzten 30 Minuten ungefähr 260.000 Dateien gelöscht.
- Ist, wie oben erwähnt, das Limit für Verzeichniseinträge einstellbar?
- Warum hat es "echte 7m9.561s / Benutzer 0m0.001s / sys 0m0.001s" gedauert, um eine einzelne Datei zu löschen, die die erste in der Liste war, die von zurückgegeben wurde
ls -U
, und es hat vielleicht zehn Minuten gedauert , um die ersten 10.000 Einträge mit der zu löschen? Kommando in # 3, aber jetzt schleppt es sich ziemlich glücklich voran? Im Übrigen wurden 260.000 in ungefähr 30 Minuten gelöscht, aber es dauerte jetzt weitere 15 Minuten, um weitere 60.000 zu löschen. Warum die großen Geschwindigkeitsschwankungen? - Gibt es einen besseren Weg, um so etwas zu tun? Speichern Sie nicht Millionen von Dateien in einem Verzeichnis. Ich weiß, dass das albern ist, und es wäre auf meiner Uhr nicht passiert. Das Problem zu googeln und durch SF und SO zu schauen, bietet eine Menge Variationen
find
, die aus mehreren offensichtlichen Gründen nicht wesentlich schneller sein werden als mein Ansatz. Aber hat die Delete-via-Fsck-Idee irgendwelche Beine? Oder etwas ganz anderes? Ich bin gespannt darauf, über den Tellerrand (oder innerhalb der nicht bekannten Box) zu denken.
Letzte Skriptausgabe !:
2970000...
2980000...
2990000...
3000000...
3010000...
real 253m59.331s
user 0m6.061s
sys 5m4.019s
Also drei Millionen Dateien in etwas mehr als vier Stunden gelöscht.
rm -rfv | pv -l >/dev/null
. pv sollte im EPEL- Repository verfügbar sein .