Kasowanie plików w bardzo dużym katalogu
Moim zadaniem było uporządkować katalog z około 250’000 plików. Miało zostać tylko 40 tysięcy określonych na liście.
Można to rozwiązać takim skryptem:
for i in $( cat pliki_do_usuniecia ); do echo $i; rm $i; done
Jednak dla takiego olbrzymiego katalogu trwało by to bardzo długo.
Moje rozwiązanie wykonywało się w czasie poniżej 1 godziny:
mkdir tmp for i in $( cat pliki_do_pozostawienia ); do echo $i; cp src/$i ./tmp/; done mv src src.0 mv tmp src
i podmiana nazwy katalogów.
Categories: Linux
mount -u -o async /thisfs
xargs rm < pliki_do_usuniecia
mount -u -o noasync /thisfs
;)
Parametry do mounta z frybzdy, nie chce mi się zaglądać do linuksowego mana, zapewne podobnie.
//m
Dzieki, za rade. Nie pomyślałem o takim wariancie.
Asynchroniczne zamontowanie katalogu, na pewno przyspieszy wykonanie skryptu. Ale, czy po każdej operacji usunięcia pliku, FS nie zechce przebudować katalogu?
Nie polecał bym tego na serwerze produkcyjnym. Tymbardzie, że w man mount można czytać:
async All I/O to the file system should be done asynchronously. This is a dangerous flag to set, and should not be used unless you are prepared to recreate the file system should your system crash.
W trybie async update’y katalogu zostaną opóźnione (wykonane hurtem, zamiast na koniec każdej zmiany) co kilkukrotnie przyśpieszy operację.
FSCK miałby ciut więcej do roboty niż zwykle gdyby w tym momencie nastąpił crash, ale zyski z przyśpieszenia i tak to rekompensują. Po wykonaniu operacji usuwam flagę async.
Nawet bez montowania w trybie async zysk masz spory – fork/exec(‘rm’) jest wykonywane dla grup plików, zamiast dla każdego pliku z osobna.
W skład takiej grupy wejdzie tyle plików, ile nazw zmieści się w buforze o wielkości ARG_MAX – 4096b.
//m