Ich möchte ein Verzeichnis entfernen, in dem sich große Datenmengen befinden. Dies ist mein Backup-Array, bei dem es sich um ein ZFS- Dateisystem mit linearer Spanne und einem einzelnen Pool namens "san" handelt. San ist gemountet, /san
also möchte ich / san / thispc / CertainFolder in großen Mengen entfernen
$ du -h -d 1 certainFolder/
1.2T certainFolder/
Anstatt dass ich warten muss, rm -rf certainFolder/
kann ich das Handle in diesem Verzeichnis nicht einfach zerstören, damit es überschrieben werden kann (auch unter demselben Verzeichnisnamen, wenn ich es neu erstellen möchte)?
Zum Beispiel, weil ich nicht viel über zfs fs internal mgmnt weiß, wie es Verzeichnisse abbildet, aber wenn ich diese Zuordnung finden würde, z. B. und die richtigen Einträge für z. B. entfernen würde, würde das Verzeichnis nicht mehr angezeigt und der Speicherplatz, den das Verzeichnis früher enthielt muss auch aus irgendeiner Art von Prüfung entfernt werden.
Gibt es eine einfache Möglichkeit, dies zu tun, selbst wenn es sich um eine ext3- Datei handelt, oder muss der rekursive Entfernungsbefehl dies bereits tun, dh Journale durchsuchen und bearbeiten?
Ich hoffe nur, dass ich etwas tun kann, bei dem kill thisDir
einfach eine Art ID entfernt wird und das Verzeichnis nicht mehr angezeigt wird ls -la
und die Daten offensichtlich noch auf dem Laufwerk vorhanden sind, aber der Speicherplatz wird jetzt wiederverwendet ( überschrieben), weil ZFS einfach so cool ist?
Ich denke, zfs ist wirklich so cool. Wie können wir das machen? Im Idealfall? Hände aneinander reiben :-)
Mein spezieller Anwendungsfall (neben meiner Liebe zu zfs) ist die Verwaltung meines Backup-Archivs. Dieses Sicherungsverzeichnis wird über freefilesync (AWESOME PROG) auf meiner Windows-Box an eine SMB-Dateifreigabe gesendet, verfügt jedoch auch über ein Versionsverzeichnis, in dem alte Dateien gespeichert werden. Ich lösche Verzeichnisse der obersten Ebene, die sich in der Hauptsicherung befinden und in die Version kopiert wurden - z. B. /san/version/someStuff
als zweimonatliche Bereinigung rm -rf /san/version/someStuff/*
von einem Kitt-Terminal. Jetzt muss ich ein anderes Terminal öffnen. Ich möchte das nicht jedes Mal tun, ich bin es leid, rm -rf unnötig überwachen zu müssen.
Ich meine, vielleicht sollte ich den Befehl so einstellen, dass nur das Handle losgelassen und dann auf Standard gedruckt wird, das könnte schön sein. Realistischer : Erstellen Sie den Datensatz in wenigen Sekunden zfs destroy san/version; zfs create -p -o compression=on san/version
nach den Gedanken aus der Antwort von @Gilles neu.
zfs create dataset -p -o compression=on yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
Antworten:
Das Verfolgen freigegebener Blöcke ist in jedem anständigen Dateisystem unvermeidbar, und ZFS ist keine Ausnahme . Unter ZFS gibt es jedoch eine einfache Möglichkeit, das Verzeichnis fast sofort zu löschen, indem die zugrunde liegende Bereinigung "verschoben" wird. Es ist dem Vorschlag von Gilles technisch sehr ähnlich, aber von Natur aus zuverlässig, ohne dass zusätzlicher Code erforderlich ist.
Wenn Sie vor dem Entfernen des Verzeichnisses einen Snapshot Ihres Dateisystems erstellen, erfolgt das Entfernen des Verzeichnisses sehr schnell, da unter diesem Verzeichnis nichts untersucht / freigegeben werden muss, auf das der Snapshot weiterhin verweist. Sie können den Schnappschuss dann im Hintergrund zerstören, damit der Speicherplatz schrittweise wiederhergestellt wird.
quelle
feature@async_destroy
kann dies auch beschleunigt werden (aus Sicht eines Benutzers oder Administrators), wenn es aktiviert ist. siehezpool get all $pool
. Beachten Sie, dass zumindest im letzten ich sah, wenn es ein anstehendes im Gange zerstören auf Pool importieren , dann ist das zerstören wird synchron und der Pool Import wird nicht beenden , bis die Oberflächen zerstören. Achten Sie darauf, wenn Sie neu starten müssen!Was Sie verlangen, ist unmöglich. Genauer gesagt fallen beim Löschen eines Verzeichnisses und seiner Dateien Kosten an. Wenn Sie es zum Zeitpunkt der Löschung nicht bezahlen, müssen Sie es woanders bezahlen.
Sie entfernen nicht nur ein Verzeichnis - das wäre fast augenblicklich. Sie entfernen ein Verzeichnis und alle darin enthaltenen Dateien und entfernen rekursiv ebenfalls alle Unterverzeichnisse. Das Entfernen einer Datei bedeutet, dass die Anzahl der Links verringert und anschließend die Ressourcen (die Blöcke, die für Dateiinhalte und Dateimetadaten verwendet werden, und der Inode, wenn das Dateisystem eine Inode-Tabelle verwendet) als frei markiert werden, wenn die Anzahl der Links 0 erreicht und die Datei nicht öffnen. Dies ist eine Operation, die für jede Datei im Verzeichnisbaum ausgeführt werden muss, sodass die dafür benötigte Zeit mindestens proportional zur Anzahl der Dateien ist.
Sie können die Kosten für die Kennzeichnung der Ressourcen als kostenlos verzögern. Beispielsweise gibt es durch Müll gesammelte Dateisysteme, in denen Sie ein Verzeichnis entfernen können, ohne die darin enthaltenen Dateien zu entfernen. Ein Lauf des Garbage Collector erkennt die Dateien, die über die Verzeichnisstruktur nicht erreichbar sind, und markiert sie als frei. Das Ausführen
rm -f directory; garbage-collect
auf einem durch Müll gesammelten Dateisystem führt die gleichen Aktionen aus wierm -rf
auf einem traditionellen Dateisystem mit verschiedenen Triggern. Es gibt nur wenige durch Müll gesammelte Dateisysteme, da der GC eine zusätzliche Komplexität darstellt, die selten benötigt wird. Die GC-Zeit kann jederzeit kommen, wenn das Dateisystem einige freie Blöcke benötigt und keine findet, sodass die Leistung eines Vorgangs von der Vergangenheit abhängt und nicht nur von dem Vorgang, der normalerweise unerwünscht ist. Sie müssten den Garbage Collector ausführen, um die tatsächliche Menge an freiem Speicherplatz zu erhalten.Wenn Sie das GC-Verhalten in einem normalen Dateisystem simulieren möchten, können Sie Folgendes tun:
(Ich habe viele wichtige Details wie Fehlerprüfung, Ausfallsicherheit usw. weggelassen.) Der Verzeichnisname wird sofort nicht mehr vorhanden. Der Raum wird schrittweise zurückgefordert.
Ein anderer Ansatz, um zu vermeiden, dass die Kosten während des Entfernens ohne GC bezahlt werden, besteht darin, sie während der Zuweisung zu bezahlen. Markieren Sie den Verzeichnisbaum als gelöscht und gehen Sie beim Zuweisen von Blöcken durch gelöschte Verzeichnisse. Das wäre schwer mit Hardlinks zu vereinbaren, aber auf einem Dateisystem ohne Hardlinks kann dies mit einer Erhöhung der O (1) -Kosten bei der Zuweisung erfolgen. Dies würde jedoch eine sehr häufige Operation (Erstellen oder Vergrößern einer Datei) teurer machen, wobei der einzige Vorteil eine relativ seltene Operation (Entfernen eines großen Verzeichnisbaums) ist.
Sie können einen Verzeichnisbaum in großen Mengen entfernen, wenn dieser Baum als eigener Blockpool gespeichert ist. (Hinweis: Ich verwende das Wort "Pool" in einer anderen Bedeutung als der "Speicherpool" von ZFS. Ich weiß nicht, wie die richtige Terminologie lautet.) Das kann sehr schnell gehen. Aber was machst du mit dem freien Speicherplatz? Wenn Sie es einem anderen Pool zuweisen, ist dies mit Kosten verbunden, die jedoch viel geringer sind als das Löschen von Dateien einzeln. Wenn Sie den Speicherplatz als nicht genutzten Reservebereich belassen, können Sie ihn nicht sofort zurückfordern. Ein einzelner Pool für einen Verzeichnisbaum bedeutet zusätzliche Kosten, um die Größe dieses Pools zu erhöhen oder zu verringern (entweder im laufenden Betrieb oder explizit). Wenn Sie den Baum zu einem eigenen Speicherpool machen, erhöhen sich auch die Kosten für das Verschieben von Dateien in den und aus dem Baum.
quelle
zfs list
. Bis dahin hofft man, dass jemand anderes einen Beitrag dazu leistet, wie man ZFS in einem Unterverzeichnis eines Pools in großen Mengen löscht. :-)Wenn es schnell gehen muss, generiere ich ein neues temporäres Verzeichnis,
mv
das Verzeichnis darunter, und lösche dann rekursiv das temporäre:quelle
rm
Befehl aus einem anderen Grund nicht ausgeführt werden, bleibt das Phantomverzeichnis nicht gelöscht.&
einfach einen Hintergrund für den Prozess durch, sodass Sie während des Löschvorgangs weiterhin andere Aufgaben in derselben Shell ausführen können (vorbehaltlich relevanter Leistungseinbußen).