Jak zrobić `rm` szybciej na ext3 / linux?

32

Mam system plików ext3 podłączony z domyślnymi opcjami. Na nim mam jakieś ~ 100 GB plików.

Usunięcie dowolnego z takich plików zajmuje dużo czasu (8 minut) i powoduje duży ruch io, co zwiększa obciążenie serwera.

Czy jest jakiś sposób, aby RM nie był tak destrukcyjny?


źródło
4
Zasadniczo żadna stąd metoda nie działała, więc opracowaliśmy własną. Opisał to tutaj: depesz.com/index.php/2010/04/04/how-to-remove-backups

Odpowiedzi:

14

Najciekawsza odpowiedź została pierwotnie pochowana w komentarzu do pytania. Oto odpowiedź pierwszej klasy, aby uczynić ją bardziej widoczną:

Zasadniczo żadna stąd metoda nie działała, więc opracowaliśmy własną. Opisałem to tutaj: http://www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ - depesz 6 kwietnia 10 o 15:15

Łącze to jest niezwykle dokładną analizą poszukiwań i odkrycia wykonalnego rozwiązania.

Uwaga:

Artykuł mówi:

Jak widać, użyłem -c2 -n7opcji jonizacji, które wydają się rozsądne.

co jest prawdą, ale użytkownik TafT mówi, że jeśli nie chcesz żadnych zakłóceń, -c3„bezczynność” byłaby lepszym wyborem niż -c2„najlepszy wysiłek”. Kiedyś -c3budował w tle i stwierdził, że działa dobrze, nie powodując, że kompilacja będzie czekać wiecznie. Jeśli naprawdę używasz 100% IO, -c3usunięcie nigdy nie pozwoli na ukończenie, ale nie spodziewa się, że to właśnie masz na podstawie sprawdzonego testu.

Matt McClure
źródło
18

Uaktualnij do ext4 lub innego nowoczesnego systemu plików korzystającego z rozszerzeń. Ponieważ ext3 używa schematu bloków pośrednich, a nie zakresów, usuwanie dużych plików nieuchronnie wymaga dużo pracy.

janneb
źródło
6

Możesz spróbować jonice . Nie przyspieszy to, ale może sprawić, że będzie mniej szkodliwe.

Wstrzymano do odwołania.
źródło
4

Pod względem wydajności użycie jednego rm na plik nie jest optymalne, ponieważ wymaga rozwidlenia i wykonania dla każdego rm.

Zakładając, że masz plik list.txt zawierający pliki, które chcesz usunąć, byłby bardziej wydajny, ale nadal będzie powolny:

xargs -i rm {} < list.txt

Innym podejściem byłoby: nice -20 xargs -i rm {} < list.txt
(zajmie to mniej czasu, ale znacznie wpłynie na twój system :)

lub

Nie wiem, jak szybko by to było, ale:

mv <file-name> /dev/null 

lub

Utwórz specjalny punkt montowania z szybkim systemem plików (za pomocą urządzenia pętli?), Użyj go do przechowywania i usuwania swoich ogromnych plików.
(być może przenieś pliki tam, zanim je usuniesz, może jest to szybsze, a może po prostu odmontuj je, gdy chcesz, aby pliki zniknęły)

lub

cat /dev/null > /file/to/be/deleted(więc ma teraz rozmiar zero) i jeśli chcesz, żeby zniknął właśnie rm -rf <file>teraz

a nawet lepiej

upuść kota i po prostu zrób # > /file/to/be/emptied


źródło
Cóż, usuwam 1 plik, więc nie ma narzutu.
1

Miałem problemy z usunięciem katalogu w rozsądnym tempie, okazało się, że proces blokował dysk i tworzył stos procesów próbujących uzyskać dostęp do dysku. ionice nie działało, po prostu nadal używało 99% IO dysku i blokowało wszystkie pozostałe procesy.

Oto kod Python, który działał dla mnie. Usuwa 500 plików na raz, a następnie robi 2-sekundową przerwę, aby umożliwić innym procesom wykonanie pracy, a następnie kontynuuje. Działa świetnie.

import os, os.path
import time

for root, dirs, files in os.walk('/dir/to/delete/files'):
    file_num = 0
    for f in files:
        fullpath = os.path.join(root, f)
        os.remove(fullpath)
        if file_num%500 == 1:
            time.sleep(2)
            print "Deleted %i files" % file_num
        file_num = file_num + 1
Nick Woodhams
źródło
1
Wypróbuj na plikach 100G + w systemie plików ext3. Problem dotyczy rozmiaru pojedynczego pliku, a nie liczby plików.
W twoim przypadku wygląda na to, że to nie zadziała. Ale miałem mnóstwo małych plików. Dzięki za opinie.
Nick Woodhams,
1

Moje dwa centy.

Mam już ten problem. „W skrypcie sekwencyjnym, który musi działać szybko, proces usuwa wiele plików”. Więc „rm” sprawi, że prędkość skryptu zbliży się do czasu oczekiwania / wykonania IO.

Aby przyspieszyć, dodałem inny proces (skrypt bash) uruchamiany na crona .. jak śmieciarz usuwa wszystkie pliki z określonego katalogu.

Następnie zaktualizowałem oryginalny skrypt, zastępując „rm” przez mv do „folderu śmieci” (zmień nazwę pliku, dodając licznik na końcu jego nazwy, aby uniknąć kolizji).

To działa dla mnie, skrypt działa co najmniej 3 razy szybciej. ale działa dobrze tylko wtedy, gdy folder śmieci i oryginalny plik znajdują się w tym samym punkcie podłączenia (to samo urządzenie), aby uniknąć kopiowania pliku. (mv na tym samym urządzeniu zużywa mniej IO niż rm)

Mam nadzieję, że to pomoże ..

Emmanuel Devaux
źródło
0

Zauważ też, że odpowiedź Dennisa Williamsona, który sugeruje jonice jako obejście obciążenia, zadziała tylko wtedy, gdy twoje urządzenie blokowe korzysta z harmonogramu CFQ io.

famzah
źródło
0

Możesz spróbować utworzyć pętlowy system plików do przechowywania kopii zapasowych.

# dd if=/dev/zero of=/path/to/virtualfs bs=100M count=1024 # 100 MB * 1024 = 100 GB
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

Następnie, jeśli chcesz wyczyścić kopie zapasowe:

# umount /mnt/backups
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

Presto! Cały wirtualny system plików jest usuwany w ciągu kilku chwil.

amfetamachina
źródło
nie rozwiązuje problemu, ponieważ działałoby tylko, gdybym chciał usunąć wszystkie kopie zapasowe z danego systemu plików.
0

Możesz używać wielogłowicowego xargs

find . -type f | xargs -P 30 rm -rf 

gdzie 30 to liczba wątków, które chcesz utworzyć. Jeśli używasz zera, system tworzy maksymalną liczbę wątków dostępnych dla użytkownika wykonującego zadanie.

Juan Carlos
źródło
1
findma -deleteopcję, która jest znacznie lepszą alternatywą.
Ariel,
0

mv <nazwa_pliku> / dev / null

/ dev / null to plik, a nie katalog. Nie można przenieść pliku do pliku, ponieważ istnieje ryzyko zastąpienia go.

Utwórz specjalny punkt montowania z szybkim systemem plików (za pomocą urządzenia pętli?), Użyj go do przechowywania i usuwania swoich ogromnych plików. (być może przenieś pliki tam, zanim je usuniesz, może jest to szybsze, a może po prostu odmontuj je, gdy chcesz, aby pliki zniknęły)

Nie sądzę, żeby to było praktyczne. Zużyłby niepotrzebnie więcej I / O niż PO.

Felipe Alvarez
źródło
-1

/ dev / null to plik, a nie katalog. Nie można przenieść pliku do pliku, ponieważ istnieje ryzyko zastąpienia go.

W rzeczywistości jest to urządzenie i wszystkie zapisane na nim dane są odrzucane, więc mv <file> /dev/nullma to sens

Z Wikipedii, bezpłatnej encyklopedii
W systemach uniksopodobnych / dev / null lub urządzenie zerowe to specjalny plik, który odrzuca wszystkie zapisane na nim dane (ale informuje, że operacja zapisu się powiodła) i nie dostarcza danych do żadnego procesu, który czyta z niego (natychmiast uzyskując EOF). [1]


źródło
1
To źle i NIESAMOWICIE niebezpieczne. / dev / null to urządzenie, które jest specjalnym obiektem podobnym do pliku. Jeśli jesteś rootem, „mv / some / file / dev / null” USUWA specjalne urządzenie / dev / null i przeniesie tam twój plik! Więc następnym razem, gdy ktoś spróbuje użyć / dev / null, użyje prawdziwego pliku zamiast urządzenia i nastąpi katastrofa. (Gdy Wikipedia mówi, że „odrzuca wszystkie zapisane do niej dane”, oznacza to, że „cat / some / file> / dev / null” przeczyta / some / file i odrzuci dane, które czytasz, ale to nie wpłynie na oryginalny plik).
user9876,