Entfernen Sie ein großes Verzeichnis in einem ZFS, ohne es rekursiv zu durchlaufen


9

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 thisDireinfach eine Art ID entfernt wird und das Verzeichnis nicht mehr angezeigt wird ls -laund 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/someStuffals 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/versionnach den Gedanken aus der Antwort von @Gilles neu.


Zu Ihrer Information, ich habe diesen Befehl ausgeführt, um die Datensätze zu erstellen, die ich derzeit verwende. `zfs create dataset -p -o compression=on yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
Brian Thomas

Bitte akzeptieren Sie eine Antwort, wenn Sie das in Ihrer ursprünglichen Frage beschriebene Problem gelöst haben. Das Problem, das Sie gerade an Ihre Frage anhängen, sieht ganz anders aus und sollte daher unbedingt in einer neuen Frage gestellt werden.
Jlliagre

Antworten:


12

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.

d=yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
zfs snapshot ${d}@quickdelete && { 
    rm -rf /${d}/certainFolder
    zfs destroy ${d}@quickdelete & 
}

ok, ich war mit Schnappschüssen nicht vertraut. das könnte mir helfen. Ich habe den ganzen Tag noch gelöscht / verschoben. Ich habe Datensätze nicht nur für das Hauptsicherungsverzeichnis erstellt, sondern auch für Verzeichnisse der obersten Ebene, die jeweils mit dem Hostnamen beginnen, und einige oberste Ebenen. Daher habe ich ein wenig Flexibilität, um einen Pool einfach zu zerstören und neu zu erstellen, aber er ist nicht perfekt , weil ich nicht immer das gesamte Pool-Verzeichnis löschen möchte, müsste ich noch mehr erstellen, und das ist eine Menge Dataset-Erstellung, also mag ich Ihren Vorschlag aus diesem Grund!
Brian Thomas

4
Wenn verfügbar, feature@async_destroykann dies auch beschleunigt werden (aus Sicht eines Benutzers oder Administrators), wenn es aktiviert ist. siehe zpool 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!
Ein CVn

Ich habe einen Kunden mit einem Freenas, der bei großen Löschvorgängen die SMB-Verbindung verloren hat. Nach dem Aktivieren von regelmäßigen Schnappschüssen (und dem automatischen Entfernen) ist das Problem "verschwunden". Die Freigabe des Speicherplatzes dauert im Hintergrund länger, aber die SMB-Freigabe bleibt jederzeit verfügbar.
Martin Seitl

6

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-collectauf einem durch Müll gesammelten Dateisystem führt die gleichen Aktionen aus wierm -rfauf 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:

mv directory .DELETING; rm -rf .DELETING &

(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.


Ok tolle Antwort! Die erste Hälfte davon ist auf einem normalen System völlig zufriedenstellend. ZFS hat einige Tricks im Ärmel, zum Beispiel muss es nicht formatiert werden. Wenn ich also den Pool zerstört habe, was ich beim nächsten Mal tun werde, ist nur Pools (Plural) so zu machen, wie ich es soll, dann verschwindet ti das Radar sofort, und dieser Platz ist sofort verfügbar. Ich denke, ich versuche, das auf dem zfs, in einem Verzeichnis innerhalb eines Pools, neu zu erstellen, und ich denke, da es kein Pool selbst ist, wird die Art des Pools standardisierter, und die von Ihnen erwähnte Methode scheint in diesem Fall anzuwenden. interessant.
Brian Thomas

Ich denke, hier habe ich meinen Fehler gemacht. Ich habe gestern Abend einen Artikel gelesen. Ich sehe nicht, ob ich ihn finden kann. Er zeigt, dass Pools wie Dirs verwendet werden sollten, die auf maximal 18.446.744 Billionen Pools auf dem FS begrenzt sind. Wenn ich meine oberen Sicherungsverzeichnisse jeweils als Pools erstelle und die Sicherung in sie schreibt, ist das Verzeichnis bereits in Takt, was ein leicht löschbarer Pool ist. Wenn der Pool nicht vorhanden war, erstellt die Sicherung nur das Verzeichnis und Der Pool wird im nicht gesehen 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. :-)
Brian Thomas

Als ich Ihre erste Antwort las, war mein erster Gedanke: "RICHTIG!", "Die Kosten"! Das habe ich angesprochen, als ich über das Löschen von Journaleinträgen sprach. so wie ich vermutet habe. verflixt! Sie sind jedoch auf dem richtigen Weg. Lassen Sie uns hier etwas einfallen, damit wir ein Skript zusammenstellen können, das dies vielleicht tut ... ein Gedanke :-)
Brian Thomas

Brian, pass auf, dass du Zpools und Datensätze nicht verwirrst. Zwar gibt es in der Tat keine erreichbare, fest codierte Begrenzung für die Anzahl der Zpools, die Sie erstellen können, doch werden Sie schnell durch die Anzahl der zugrunde liegenden Geräte (z. B. Partitionen) begrenzt, die auf Ihrem Computer verfügbar sind. Darüber hinaus werden Pools, die einzelnen Verzeichnissen zugeordnet sind, einige wertvolle zfs-Funktionen zunichte machen und Verschiebungsvorgänge erheblich verlangsamen.
Jlliagre

zu diesem Kommentar, den Sie hier gemacht haben @Gilles "Aber was machen Sie mit dem freien Speicherplatz? Wenn Sie ihn einem anderen Pool zuweisen, hat das Kosten, obwohl viel weniger als das Löschen von Dateien einzeln", bin ich mir nicht sicher, aber ich denke nicht dort ist eine Strafe, wenn ein neuer Pool erstellt wird. Ich denke, ich beschäftige mich nur während der Schreibzeit damit. muss nie aus dem gleichen Grund partitioniert werden .. Ich glaube, das ist der gleiche Mechanismus ..
Brian Thomas

1

Wenn es schnell gehen muss, generiere ich ein neues temporäres Verzeichnis, mvdas Verzeichnis darunter, und lösche dann rekursiv das temporäre:

t=`mktemp -d`
mv certainFolder $t/
rm -rf $t &

Hat der & Entfernungsgriff oder Squash-Fehler?
Brian Thomas

1
Dies unterscheidet sich nicht wirklich von Gilles 'Vorschlag und hat den gleichen Fehler. Sollte das Betriebssystem neu gestartet werden oder der rmBefehl aus einem anderen Grund nicht ausgeführt werden, bleibt das Phantomverzeichnis nicht gelöscht.
Jlliagre

ahh richtig, aber das & ist neu für mich, das ist ein Teil des Puzzles ... ich wollte den Griff loswerden. aber ja dein Recht, ich will diesen Müll nicht, wenn es ein Problem gibt ..
Brian Thomas

@BrianThomas führt &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).
Ein CVn
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.