Wie kann man `rm` unter ext3 / linux schneller machen?

32

Ich habe ext3-Dateisystem mit Standardoptionen gemountet. Darauf habe ich einige ~ 100GB Dateien.

Das Entfernen solcher Dateien dauert lange (8 Minuten) und verursacht viel Datenverkehr, wodurch die Serverlast steigt.

Gibt es eine Möglichkeit, das rm nicht so störend zu machen?


quelle
4
Grundsätzlich hat von hier aus keine Methode funktioniert, also haben wir unsere eigene entwickelt. Beschrieben hier: depesz.com/index.php/2010/04/04/how-to-remove-backups

Antworten:

14

Die interessanteste Antwort wurde ursprünglich in einem Kommentar zu der Frage begraben. Hier ist es eine erstklassige Antwort, um es sichtbarer zu machen:

Grundsätzlich hat von hier aus keine Methode funktioniert, also haben wir unsere eigene entwickelt. Beschrieben hier: http://www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ - depesz 6. April 10 um 15:15 Uhr

Dieser Link ist eine unglaublich gründliche Analyse der Suche nach und Entdeckung einer praktikablen Lösung.

Beachten Sie auch:

Der Artikel sagt:

Wie Sie sehen, habe ich -c2 -n7Optionen für ionice verwendet, die vernünftig erscheinen.

Das ist wahr, aber Benutzer TafT sagt, wenn Sie keine Störung wollen, dann wäre -c3"untätig" eine bessere Wahl als -c2"Best-Effort". Er hat -c3im Hintergrund gebaut und festgestellt, dass es gut funktioniert, ohne dass der Build für immer warten muss. Wenn Sie wirklich zu 100% ausgelastet sind, -c3wird der Löschvorgang niemals abgeschlossen sein, er erwartet jedoch nicht, dass dies auf der Grundlage des durchgeführten Tests der Fall ist.

Matt McClure
quelle
18

Aktualisieren Sie auf ext4 oder ein anderes modernes Dateisystem, das Extents verwendet. Da ext3 das Schema für indirekte Blöcke anstelle von Extents verwendet, ist das Löschen großer Dateien unweigerlich mit viel Arbeit verbunden.

Janneb
quelle
6

Sie können ionice versuchen. Es wird es nicht schneller machen, aber es könnte es weniger störend machen.

Bis auf weiteres angehalten.
quelle
4

In Bezug auf die Effizienz ist die Verwendung eines virtuellen Raums pro Datei nicht optimal, da für jeden virtuellen Raum ein Fork und Exec erforderlich ist.

Angenommen, Sie haben eine list.txt mit den Dateien, die Sie entfernen möchten, wäre effizienter, aber es wird immer noch langsam:

xargs -i rm {} < list.txt

Ein anderer Ansatz wäre: nice -20 xargs -i rm {} < list.txt
(Dies wird weniger Zeit in Anspruch nehmen, aber Ihr System stark beeinträchtigen :)

oder

Ich weiß nicht, wie schnell das gehen würde, aber:

mv <file-name> /dev/null 

oder

Erstellen Sie einen speziellen Einhängepunkt mit einem schnellen Dateisystem (mit einem Loop-Gerät?). Verwenden Sie diesen Punkt, um Ihre riesigen Dateien zu speichern und zu löschen.
(Verschieben Sie die Dateien möglicherweise dorthin, bevor Sie sie löschen. Möglicherweise ist es schneller, oder heben Sie die Bereitstellung einfach auf, wenn die Dateien gelöscht werden sollen.)

oder

cat /dev/null > /file/to/be/deleted(so ist es Null-Größe jetzt) , und wenn Sie wollen , dass es einfach verschwinden rm -rf <file>jetzt

oder noch besser

Lass die Katze fallen und tu es einfach # > /file/to/be/emptied


quelle
Nun, ich entferne 1 Datei, so gibt es keinen Overhead.
stackoverflow.com/questions/1795370/… - überprüfen Sie dies auch
1

Ich hatte Probleme damit, das Verzeichnis mit einer angemessenen Geschwindigkeit zu löschen. Es stellte sich heraus, dass der Prozess die Festplatte sperrte und eine Anhäufung von Prozessen erstellte, die versuchten, auf die Festplatte zuzugreifen. ionice hat nicht funktioniert, es hat nur 99% der Festplatten-E / A weiter genutzt und alle anderen Prozesse gesperrt.

Hier ist der Python-Code, der für mich funktioniert hat. Es werden jeweils 500 Dateien gelöscht. Anschließend wird eine Pause von 2 Sekunden eingelegt, damit die anderen Prozesse ihre Arbeit erledigen können. Anschließend wird der Vorgang fortgesetzt. Funktioniert super.

import os, os.path
import time

for root, dirs, files in os.walk('/dir/to/delete/files'):
    file_num = 0
    for f in files:
        fullpath = os.path.join(root, f)
        os.remove(fullpath)
        if file_num%500 == 1:
            time.sleep(2)
            print "Deleted %i files" % file_num
        file_num = file_num + 1
Nick Woodhams
quelle
1
Probieren Sie es mit 100G + -Dateien im ext3-Dateisystem aus. Das Problem liegt in der Größe einer einzelnen Datei, nicht in der Anzahl der Dateien.
In deinem Fall klingt es so, als würde es nicht funktionieren. Aber ich hatte eine Menge kleiner Dateien. Danke für die Rückmeldung.
Nick Woodhams
1

Meine zwei Cent.

Ich habe dieses Problem bereits. "In sequentiellen Skripten, die schnell ausgeführt werden müssen, entfernt der Prozess eine Menge Dateien."

Um die Sache zu beschleunigen, habe ich einen weiteren Prozess (Bash-Skript) hinzugefügt, der per Cron gestartet wird. Wie ein Garbage Collector entfernt er alle Dateien in einem bestimmten Verzeichnis.

Dann habe ich das ursprüngliche Skript aktualisiert, indem ich das "rm" durch ein mv in einen "Garbage Folder" ersetzt habe (benennen Sie die Datei um, indem Sie am Ende des Namens einen Zähler hinzufügen, um Kollisionen zu vermeiden).

Das funktioniert bei mir, das Skript läuft mindestens 3 mal schneller. Dies funktioniert jedoch nur dann, wenn sich der Mülleimer und die Originaldatei unter demselben Einhängepunkt (demselben Gerät) befinden, um ein Kopieren der Dateien zu vermeiden. (MV auf demselben Gerät verbrauchen weniger IO als RM)

Hoffe das hilft ..

Emmanuel Devaux
quelle
0

Beachten Sie auch, dass die Antwort von Dennis Williamson, der ionice als Workaround für das Laden vorschlägt , nur funktioniert, wenn Ihr Block-Gerät den CFQ-io-Scheduler verwendet.

Famzah
quelle
0

Sie können versuchen, ein Schleifendateisystem zu erstellen, in dem Ihre Sicherungen gespeichert werden.

# dd if=/dev/zero of=/path/to/virtualfs bs=100M count=1024 # 100 MB * 1024 = 100 GB
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

Wenn Sie die Backups löschen möchten, gehen Sie wie folgt vor:

# umount /mnt/backups
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

Presto! Das gesamte virtuelle Dateisystem wird in wenigen Augenblicken gelöscht.

Amphetamachine
quelle
löst das Problem nicht, da es nur funktionieren würde, wenn ich alle Backups auf einem bestimmten Dateisystem entfernen möchte.
0

Sie können Multitheading mit Xargs verwenden

find . -type f | xargs -P 30 rm -rf 

Dabei ist 30 die Anzahl der Threads, die Sie erstellen möchten. Wenn Sie Null verwenden, erstellt das System maximale Threads, die dem Benutzer zur Verfügung stehen, der die Aufgabe ausführt.

Juan Carlos
quelle
1
findhat eine -deleteOption, die eine viel bessere Alternative ist.
Ariel
0

mv <Dateiname> / dev / null

/ dev / null ist eine Datei, kein Verzeichnis. Eine Datei kann nicht in eine Datei verschoben werden, da sonst das Risiko besteht, dass sie überschrieben wird.

Erstellen Sie einen speziellen Einhängepunkt mit einem schnellen Dateisystem (mit einem Loop-Gerät?). Verwenden Sie diesen Punkt, um Ihre riesigen Dateien zu speichern und zu löschen. (Vielleicht verschieben Sie die Dateien dorthin, bevor Sie sie löschen. Vielleicht ist es schneller oder Sie hängen sie einfach ab, wenn Sie möchten, dass die Dateien verschwunden sind.)

Ich halte das nicht für praktisch. Es würde unnötig mehr E / A verbrauchen, als das OP möchte.

Felipe Alvarez
quelle
-1

/ dev / null ist eine Datei, kein Verzeichnis. Eine Datei kann nicht in eine Datei verschoben werden, da sonst das Risiko besteht, dass sie überschrieben wird.

Eigentlich handelt es sich um ein Gerät, und alle darauf geschriebenen Daten werden verworfen, mv <file> /dev/nullwas Sinn macht

Aus Wikipedia, der freien Enzyklopädie
Unter Unix-ähnlichen Betriebssystemen ist / dev / null oder das Null-Gerät eine spezielle Datei, die alle darauf geschriebenen Daten verwirft (aber meldet, dass der Schreibvorgang erfolgreich war) und keine Daten für einen Prozess bereitstellt, der dies ausführt liest daraus (was sofort EOF ergibt). [1]


quelle
1
Das ist falsch und UNGLAUBLICH gefährlich. / dev / null ist ein Gerät, welches ein spezielles dateiähnliches Objekt ist. Wenn Sie root sind, löscht "mv / some / file / dev / null" das spezielle / dev / null-Gerät und verschiebt Ihre Datei dorthin! Wenn jemand das nächste Mal versucht, / dev / null zu verwenden, verwendet er eine echte Datei anstelle des Geräts und es kommt zu einer Katastrophe. (Wenn Wikipedia angibt, dass "alle darauf geschriebenen Daten verworfen werden", bedeutet dies, dass "cat / some / file> / dev / null" / some / file liest und die von Ihnen gelesenen Daten verwirft, dies hat jedoch keine Auswirkungen auf die Originaldatei).
User9876