Rimuovere in blocco una directory di grandi dimensioni su uno ZFS senza attraversarla in modo ricorsivo


9

Voglio rimuovere una directory che contiene grandi quantità di dati. Questo è il mio array di backup, che è un filesystem ZFS , un intervallo lineare, un singolo pool chiamato "san". San è montato, /san quindi desidero rimuovere bulk / san / thispc / certainFolder

$ du -h -d 1 certainFolder/
1.2T    certainFolder/

Invece di me devo aspettare, rm -rf certainFolder/non posso semplicemente distruggere l'handle in quella directory in modo che sia sovrascrivibile (anche con lo stesso nome dir se ho scelto di ricrearlo) ??

Quindi, per esempio, non sapendo molto su zfs fs mgmnt interno, in particolare su come mappa le directory, ma se trovassi quella mappa dire per esempio, e rimossi le voci giuste per esempio, la directory non verrebbe più visualizzata e lo spazio che la directory precedentemente conteneva deve essere rimosso anche da un qualche tipo di audit.

C'è un modo semplice per farlo, anche se su un ext3 fs, o è già quello che il comando di rimozione ricorsiva deve fare in primo luogo, cioè sfogliare e modificare i giornali?

Spero solo di fare qualcosa del genere kill thisDirin cui rimuova semplicemente un qualche tipo di ID, e poof la directory non viene più visualizzata ls -lae i dati sono ancora lì sul disco ovviamente, ma lo spazio verrà ora riutilizzato ( sovrascritto), perché ZFS è così bello?

Voglio dire, penso che zfs sia davvero così bello, come possiamo farlo? Idealmente? strofinarsi le mani :-)

Il mio caso d'uso specifico (oltre al mio amore per zfs) è la gestione del mio archivio di backup. Questa directory di backup viene trasferita tramite freefilesync (AWESOME PROG) sul mio box di Windows a una condivisione di file smb, ma ha anche una directory di versione dove vanno i vecchi file. Sto eliminando le directory di livello superiore che risiedono nel backup principale, che sono state copiate nella versione - ad esempio /san/version/someStuff, come una pulizia bimestrale rm -rf /san/version/someStuff/*da un terminale putty, ora devo aprire un altro terminale; non voglio farlo ogni volta, sono stanco di dover monitorare inutilmente rm -rf.

Voglio dire, forse dovrei impostare il comando per rilasciare solo la maniglia, quindi stampare su STD, potrebbe essere carino. Più realisticamente , ricrea il set di dati in pochi secondi zfs destroy san/version; zfs create -p -o compression=on san/versiondopo i pensieri della risposta di @Gilles.


Cordiali saluti, ho eseguito questo comando per creare i set di dati che sto utilizzando attualmente .. `zfs create dataset -p -o compression=on yourPoolName/BackupRootDir/hostNameYourPc/somesubdir
Brian Thomas

Si prega di accettare una risposta se si è risolto il problema descritto nella domanda originale. Il problema che hai appena aggiunto alla tua domanda sembra essere piuttosto diverso, quindi dovrebbe essere posto in una nuova domanda.
jlliagre,

Risposte:


12

Il tracciamento dei blocchi liberati è inevitabile in qualsiasi file system decente e ZFS non fa eccezione . In ZFS esiste tuttavia un modo semplice per ottenere una cancellazione della directory quasi istantanea "rimandando" la pulizia sottostante. È tecnicamente molto simile al suggerimento di Gilles ma è intrinsecamente affidabile senza richiedere codice aggiuntivo.

Se si crea un'istantanea del proprio file system prima di rimuovere la directory, la rimozione della directory sarà molto rapida perché non sarà necessario esplorare / liberare nulla al suo interno, facendo ancora riferimento a tale snapshot. È quindi possibile distruggere l'istantanea in background in modo da recuperare gradualmente lo spazio.

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

ok, non ho familiarità con le istantanee. questo potrebbe aiutarmi. ho cancellato / spostato tutto il giorno ancora. Ho creato set di dati non solo per la directory di backup principale, ma anche per le directory di livello superiore, ognuna che inizia con il nome host e alcuni livelli principali .., quindi ho un po 'di flessibilità lì per distruggere e ricreare un pool, ma non è perfetto , poiché non desidero sempre eliminare l'intera directory del pool, dovrei crearne ancora di più e questo è un sacco di creazione di set di dati, quindi mi piace il tuo suggerimento per questo motivo!
Brian Thomas,

4
Se disponibile, feature@async_destroypotrebbe anche aiutare ad accelerare questo (dal punto di vista di un utente o amministratore) se abilitato; vedi zpool get all $pool. Si noti che almeno alla fine ho osservato, se è in corso una distruzione in corso sull'importazione del pool , tale distruzione diventa sincrona e l'importazione del pool non termina fino al termine della distruzione. Fai attenzione se devi riavviare!
un CVn,

Ho un cliente con un freenas che ha perso la connessione SMB su grandi cancellazioni. Dopo aver abilitato le istantanee periodiche (e la rimozione automatica) il problema "è scomparso". la liberazione dello spazio richiede più tempo in background, ma la condivisione SMB rimane sempre accessibile.
Martin Seitl

6

Quello che stai chiedendo è impossibile. O, più precisamente, c'è un costo da pagare quando si elimina una directory e i suoi file; se non lo paghi al momento della cancellazione, dovrai pagarlo altrove.

Non stai semplicemente rimuovendo una directory, sarebbe quasi istantanea. Stai rimuovendo una directory e tutti i file al suo interno e allo stesso modo rimuovendo anche ricorsivamente tutte le sue sottodirectory. Rimuovere un file significa decrementare il conteggio dei collegamenti e quindi contrassegnare le sue risorse (i blocchi utilizzano per i contenuti dei file e i metadati dei file e l'inode se il filesystem utilizza una tabella di inode) come libero se il conteggio dei collegamenti raggiunge 0 e il file non lo è Aperto. Questa è un'operazione che deve essere eseguita per ogni file nella struttura di directory, quindi il tempo impiegato è almeno proporzionale al numero di file.

Potresti ritardare il costo di contrassegnare le risorse come libere. Ad esempio, esistono filesystem raccolti in modo inutile, in cui è possibile rimuovere una directory senza rimuovere i file in essa contenuti. Un'esecuzione del Garbage Collector rileverà i file che non sono raggiungibili tramite la struttura di directory e li contrassegnerà come liberi. Fare rm -f directory; garbage-collectsu un filesystem garbage collection fa le stesse cose dirm -rfsu un filesystem tradizionale, con diversi trigger. Esistono pochi filesystem raccolti in modo inutile perché il GC è una complessità aggiuntiva che raramente è necessaria. Il tempo GC potrebbe arrivare in qualsiasi momento, quando il filesystem ha bisogno di alcuni blocchi liberi e non ne trova nessuno, quindi le prestazioni di un'operazione dipendono dalla storia passata, non solo dall'operazione, che di solito è indesiderabile. Dovresti eseguire il Garbage Collector solo per ottenere l'effettiva quantità di spazio libero.

Se vuoi simulare il comportamento del GC su un normale filesystem, puoi farlo:

mv directory .DELETING; rm -rf .DELETING &

(Ho omesso molti dettagli importanti come il controllo degli errori, la resilienza alla perdita di potenza, ecc.) Il nome della directory diventa immediatamente inesistente; lo spazio viene progressivamente recuperato.

Un approccio diverso per evitare di pagare il costo durante la rimozione senza GC sarebbe quello di pagarlo durante l'allocazione. Contrassegnare l'albero delle directory come eliminato e passare attraverso le directory eliminate durante l'allocazione dei blocchi. Ciò sarebbe difficile da conciliare con i collegamenti reali, ma su un filesystem senza collegamenti fissi, può essere fatto con un aumento dei costi di O (1) nell'allocazione. Tuttavia ciò renderebbe un'operazione molto comune (creazione o ingrandimento di un file) più costosa, con l'unico vantaggio di un'operazione relativamente rara (rimozione di un grande albero di directory) più economica.

È possibile rimuovere in blocco un albero di directory se quell'albero è stato memorizzato come proprio pool di blocchi. (Nota: sto usando la parola "pool" in un significato diverso dal "pool di archiviazione" di ZFS. Non so quale sia la terminologia corretta.) Potrebbe essere molto veloce. Ma cosa fai con lo spazio libero? Se lo riassegni a un altro pool, questo ha un costo, anche se molto meno dell'eliminazione dei file singolarmente. Se si lascia lo spazio come spazio di riserva inutilizzato, non è possibile recuperarlo immediatamente. Avere un singolo pool per un albero di directory significa costi aggiuntivi per aumentare o ridurre la dimensione di quel pool (al volo o esplicitamente). Rendere l'albero il proprio pool di archiviazione aumenta anche il costo dello spostamento dei file dentro e fuori l'albero.


Ok ottima risposta! La prima metà è completamente soddisfacente su un sistema normale. ZFS ha qualche asso nella manica, per esempio non c'è bisogno di formattarlo, quindi se ho distrutto il pool, cosa che penso che farò la prossima volta è solo rendere il pool (plurale) come dovrei, quindi ti scompare il radar all'istante, e quello spazio è immediatamente disponibile. Immagino che sto provando a ricrearlo su zfs, su una directory all'interno di un pool, e penso che dal momento che non è un pool stesso, la sua natura diventa più standard e il metodo che hai citato sembra applicarsi in quel caso. interessante.
Brian Thomas,

Penso che sia lì che ho fatto il mio errore, ho letto un articolo ieri sera, vedrò se riesco a trovarlo, che dimostra che le piscine dovrebbero essere usate come dir limitate a ~ 18.446.744 Trilioni di piscine al massimo sull'FS. se creo le mie directory di backup superiori come pool ciascuna, quando il backup va a scriverle, la directory sarà già intatta, il che è un pool facilmente eliminabile. Se il pool non esistesse, il backup creerà semplicemente la directory e la piscina non sarà vista nel zfs list. Fino ad allora, sperando che qualcun altro abbia qualche input su come eliminare in blocco ZFS in un sottodiretto di un pool. :-)
Brian Thomas

Inoltre, quando ho letto la tua prima risposta, il mio primo pensiero è stato; "DESTRA!", "Il costo"! questo è quello che stavo toccando quando stavo parlando di eliminare le voci del diario. così come sospettavo. maledettamente! Tuttavia, sei sulla strada giusta. Andiamo a trovare qualcosa qui, quindi possiamo mettere insieme una sceneggiatura che lo farà forse ... un pensiero :-)
Brian Thomas

Brian, fai attenzione a non confondere zpools e set di dati. Sebbene non vi sia effettivamente alcun limite di codice fisso raggiungibile sul numero di zpool che è possibile creare, si sarà rapidamente limitati dal numero di dispositivi sottostanti (ad esempio partizioni) disponibili sulla propria macchina. Inoltre, avere pool dedicati a singole directory annullerà alcune preziose funzionalità di zfs e renderà le operazioni di spostamento molto più lente.
jlliagre,

su questo commento che hai fatto qui @Gilles "Ma cosa fai con lo spazio libero? Se lo riassegni a un altro pool, questo ha un costo, anche se molto meno dell'eliminazione dei file singolarmente" non sono sicuro, ma non penso che ci è un penalista a creare un nuovo pool, penso di affrontarlo solo durante il tempo di scrittura. non ha mai bisogno di essere partizionato per lo stesso motivo .. credo che questo sia lo stesso meccanismo ..
Brian Thomas

1

Se deve essere veloce, generi una nuova directory temporanea, mvla directory sottostante e quindi elimino in modo ricorsivo il temporaneo:

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

gestisce e rimuove gli errori di compressione?
Brian Thomas,

1
Questo non è molto diverso dal suggerimento di Gilles e ha lo stesso difetto. Se il sistema operativo viene riavviato o il rmcomando non viene completato per qualche altro motivo, la directory fantasma viene lasciata non cancellata.
jlliagre,

ah giusto, ma il & è nuovo per me, questo è parte del puzzle ... volevo liberarmi della maniglia. comunque sì hai ragione, non voglio quella spazzatura se c'è un problema ..
Brian Thomas

@BrianThomas &semplicemente fa da sfondo al processo, quindi puoi continuare a fare altre cose nella stessa shell mentre l'eliminazione è in esecuzione (soggetto a eventuali penali di prestazione rilevanti).
un CVn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.