Gigantisches Verzeichnis unter Linux auf Laufwerk Ext3 / 4 schnell entfernen

433
Karl Damgaard Asmussen

Ich habe an einer Datendeduplizierung gearbeitet, die mich dazu zwang, das Dateisystem als Hash-Tabelle zu verwenden. Dies führte in einigen Verzeichnissen, die es wörtliche Stunden dauerte mit fast jede vernünftige Methode zu löschen (dh rm -rf, ls -f1 | xargs rm, find -delete, etc.)

Unter Ext2 / 3/4-Dateisystemen ist ein Verzeichnis eine Datei, die eine Hashtabelle enthält, die von Dateinamen bis zu Inode-Nummern reicht (in meinem Fall etwa 60 MB!). Wie ich es verstehe, laufen Laufen rm -rfund Freunde langsam, weil sie dieser Methode folgen:

Durchlaufen Sie die Hashtabelle in der Verzeichnisdatei. Für jedes gefundene Dateiname-Inode-Paar, atomar:

  1. Dekrementieren Sie die Anzahl der Namen für den Inode.
  2. Entfernen Sie den Eintrag aus der Hashtabelle.

(Das Löschen der Dateien / Inodes tritt auf, wenn der Name Count 0 erreicht und keine Programme mit Dateideskriptoren geöffnet sind, die auf diese Inodes zeigen.)

Die Namenszählung eines Inodes zu dekrementieren ist schnell.

Das Löschen einer Datei (insbesondere einer kleinen) ist ebenfalls schnell: Man bezeichnet einfach die Laufwerksblöcke, die die Datei besitzt, als frei in der Verfügbarkeitstabelle.

Die Verlangsamung entsteht, wie ich feststellen kann, beim Entfernen von Einträgen aus der Hashtabelle. Jeder Löschvorgang hat wahrscheinlich eine Chance, ein erneutes Hashing auszulösen, da ich beobachtete, wie sich die Größe der Verzeichnisdatei verringerte, wenn Dateien entfernt wurden.

Was ich frage, ist zweifach:

  • Ist meine Überlegung richtig, da es die Manipulation von Hash-Tabellen ist, die den Prozess verlangsamt?
  • Wenn ja, gibt es ein Werkzeug, das folgendes tut (und welches dadurch wahrscheinlich viel schneller ist?)

    1. Verringern Sie die Anzahl der Namen aller Inodes, die in der Verzeichnisdatei aufgeführt sind.
    2. Löschen Sie den gesamten Inhalt des gesamten Verzeichnisses auf einmal.
3

2 Antworten auf die Frage

2
miravalls

Das Löschen eines gesamten Baums ist ein teurer Vorgang, es gibt jedoch Möglichkeiten, ihn zu beschleunigen.

Haben Sie die in dieser Antwort aufgeführte Lösung und diese Antwort probiert ? rsyncscheint der schnellste zu sein, weil sie die Löschvorgänge, anstatt einfach gehen über die Liste der Dateien optimiert rm, find... tun.

Hast du diese Alternative auch ausprobiert ?

BEARBEITEN:

Bitte beachten Sie: Ich habe diese Befehle nicht getestet.

Befehle, auf die ich mich beziehe, falls die Links in der Zukunft brechen:

rsync Befehl der ersten beiden Links:

mkdir blank rsync -a --delete blank/ test/ 

Dritter Link: "Verschiebe sie in ein verstecktes Verzeichnis und entferne es dann im Hintergrund":

mkdir ../.tmp_to_remove mv -- * ../.tmp_to_remove nohup rm -rf ../.tmp_to_remove & 

Wie in dieser Antwort erläutert, geht dieser Ansatz davon aus, dass der Benutzer (selbst wenn das Entfernen sehr teuer ist), da der Löschvorgang im Hintergrund in einem anderen Baum erfolgt, die tatsächlichen Kosten möglicherweise nicht berücksichtigt. Meiner Meinung nach ist dies wahr, solange Sie nicht versuchen, Ihre bash / ssh-Sitzung zu schließen, bevor der Löschvorgang ausgeführt wird. Um dies zu beheben, habe ich nohupdem rmBefehl ein a hinzugefügt .

@ KamilMaciorowski Danke für Ihr Feedback. Ich habe meine Antwort auf Ihren Vorschlag hin aktualisiert. miravalls vor 6 Jahren 0
2
Theodore Ts'o

Das ext3 / 4-Verzeichnis ist keine Hashtabelle an sich. Es ist eigentlich ein Hash-Baum. Das heißt, der Dateiname wird gehasht und der Hash wird als Index zum Einfügen in einen B + -Baum verwendet. Der schnellste Weg zum Löschen aller Dateien besteht darin, die Dateien nach der Inode-Nummer zu sortieren, da dadurch die Datenträgersuche minimiert werden, die erforderlich sind, um die Inodes aus der Inode-Tabelle in den Speicher zu ziehen, und die Aktualisierungen der Inode-Tabelle, wenn die Dateien freigegeben werden . Dies wird auch dazu neigen, die Dateien in der Reihenfolge zu löschen, in der sie erstellt wurden, wodurch die Aktualisierung der verschiedenen Block- und Inode-Zuweisungs-Bitmaps optimiert wird. Eine weitere Sache, die Sie tun können, ist die Vergrößerung der Zeitschrift (Entfernen Sie die Zeitschrift mit tune2fs und erstellen Sie sie dann mit einer größeren Zeitschrift).

Letztendlich sollten Sie berücksichtigen, dass ein Dateisystem nicht als Datenbank optimiert ist. Wenn Sie das Dedup-Verfahren durchführen möchten, sollten Sie unbedingt die Verwendung einer Datenbank in Betracht ziehen und nicht versuchen, sie mithilfe eines Shell-Skripts zu umgehen und ein Verzeichnis als schnelle und schmutzige Datenbank zu verwenden. Wie Sie herausgefunden haben, funktioniert das nicht besonders gut ....

Theodore Ts'o beantwortet eine zufällige Frage zu ext3 / 4. Nett. :) Ich habe auch Nobelpreisträger bei Physics SE gesehen, und ich liebe es, wenn solche Dinge passieren! Vielleicht könnte der Papst von Christianity SE das besiegen, aber ich habe das (noch) nicht gesehen. Kamil Maciorowski vor 6 Jahren 0
Vielen Dank für das Aufräumen! Und ja, eine Datenbank wäre vorzuziehen gewesen; Aber das Aufsetzen zur Arbeit würde länger dauern, als es zu hacken. Ich arbeite in der Datenwissenschaft und schäme mich. Karl Damgaard Asmussen vor 6 Jahren 0