Newsgroup: it.comp.os.linux.sys
Titolo: ZFS: delete hardlink

Qualcuno di voi che usa ZFS può dirmi quanto impiega a cancellare una directory con *MILIONI* di hardlinks ? (un backup di rsnapshot su un server con circa 5 milioni di file, dove buona parte, direi 4 milioni, sono invariati rispetto al giorno prima e quindi hardlinkati)
 
XFS impiega mooooooooooooooooooooolto tempo, delle ore, tant'è che devo usare rsync per sincronizzare una directory vuota sulla directory piena (rsync va *MOLTO*, *MOLTO*, *MOLTO* più veloce di "rm", circa 1 ora e mezzo contro 2 ore e 45 di rm)

 XFS impiega mooooooooooooooooooooolto tempo, delle ore, tant'è che devo usare rsync per sincronizzare una directory vuota sulla directory piena (rsync va *MOLTO*, *MOLTO*, *MOLTO* più veloce di "rm", circa 1 ora e mezzo contro 2 ore e 45 di rm)
 
non saprei, ma una ricerca veloce mi ha portato su questo link:
http://unix.stackexchange.com/questions/219786/bulk-remove-a-large-directory-on-a-zfs-without-traversing-it-recursively
 
 
ZFS ha sta cosa dell'async destroy (e' una "feature" da attivare, non credo sia attiva di default) per dataset/snapshots/ecc. che permette di eliminare il "mount point" istantaneamente, e poi ZFS in background recupera lo spazio, ma non credo funzioni sulle directory, per questo nel link dicono di fare uno snapshot, cancellare la directory (che e' veloce perche' non recupera nessuno spazio) e poi distruggere lo snapshot (che viene fatto in background).
 
Mai provato pero'.
 
Se ti metti a fare un po' di test fai sapere come si comporta ;)
 
Ciao Jack

 directory con *MILIONI* di hardlinks ?
 
Sinceramente non saprei. Puoi provare ad adattare questo e a farlo girare prima
su XFS e poi su ZFS (per la cronaca, su XFS, find . -type f -delete ci mette
4 minuti, mentre su ext4 ci mette 39 minuti): 
http://pastebin.com/FdyWxFjE
 
 
Enrico

 4 minuti, mentre su ext4 ci mette 39 minuti): 
http://pastebin.com/FdyWxFjE
 
 
E' lo stesso test fatto da me tempo fa, prima di decidere di usare rsync al posto di "rm" per la cancellazione dei vecchi pool di rsnapshot (eccetto per il fatto che te usi "-r" mentre io "-a", ma non dovrebbe cambiare nulla)
 
Ma come è visibile dal tuo link, la soluzione perl è di qualche ordine di grandezza più rapida delle altre, ma non elimina le sottodirectory.
 
Potrei farla andare parametrizzata, del tipo:
 
 find -type d | xargs 
cancella.pl
 
 
o meglio ancora (non sono capace) fare in modo che quello script cancelli in maniera ricorsiva tutta la directory.
 
Adesso vedo cosa riesco a tirar fuori dal cappello.

 o meglio ancora (non sono capace) fare in modo che quello script cancelli in maniera ricorsiva tutta la directory.
 
Sto facendo un test con "rmtree" da Fileutils.
La differenza, stando a strace, rispetto ad "unlink" è che quest'ultimo fa prima lo stat di tutti i file della directory (dovuto al glob) e poi fa l'unlink brutale di tutti i file, rmtree invece sembra che faccia stat+unlink file per file, directory per directory e credo che questa procedura sia meno ottimizzata.
tant'è che l'unlink di mezzo milione di hardlink impiega 0 secondi, mentre il mio attuale rmtree su una directory con complessivi 5 milioni di hardlink (e moltissime directory, però) sta impiegando più di 20 minuti ed è al 20%)

 Sto facendo un test con "rmtree" da Fileutils.
 
153 minuti.
 
La cancellazione di ieri, dello stesso server, fatta con rsync, ha impiegato circa 2 ore o poco più. Le due cancellazioni non sono ovviamente identiche, ma di sicuro tra ieri ed oggi non è stata scritta una mole di dati da giustificare oltre mezzora in più di cancellazione.
 
Quindi: rsync è più veloce di "rmtree" di perl, mentre "unlink" di perl è il più veloce di tutti a cancellare il contenuto di una intera directory.
 
Quale può essere un buon sistema per cancellare, ricorsivamente, una intera directory usando "unlink" ? Tempo che a portare via tempo sia proprio lo stat+chdir sulle singole directory

 directory usando "unlink" ?
 
L'internet consiglia xargs rm -f:
 
[enrico@alice test]$ time for i in $(seq 1 500000); do echo testing >> $i.txt; done
 
real    1m0.167s
user    0m8.397s
sys     0m49.421s
[enrico@alice test]$ time find ./ -type f -print0 | xargs -0 rm -f              
real    0m32.365s
user    0m1.184s
sys     0m30.551s
[enrico@alice test]$ time for i in $(seq 1 500000); do echo testing >> $i.txt; done
 
real    0m59.306s
user    0m8.284s
sys     0m49.371s
[enrico@alice test]$ time perl -e 'for(<*>){((stat)[9]<(unlink))}'
 
real    0m33.201s
user    0m1.581s
sys     0m29.153s
[enrico@alice test]$
 
Nota che i test li ho fatti proprio su ZFS (in raidz)
 
Enrico

 L'internet consiglia xargs rm -f:
 
L'internet ti consiglia male.
Premesso che stai cancellando da una singola directory (stando al tuo primo for), se faccio find+xargs, prima lui deve parsare tutta la directory e poi ne inizia la cancellazione. A quel punto è sicuramente più efficace un "find --delete", che cancella contestualmente alla scansione