Usuwanie bardzo dużego pliku bez zamrażania serwera WWW

11

Na moim serwerze internetowym (działa apache, Linux CentOS), jest bardzo duży plik dziennika ( 50 Gbyte ). Ten serwer sieciowy ma w produkcji niektóre usługi sieciowe.

Kiedy próbowałem usunąć plik dziennika, serwer sieciowy nie odpowiedział przez około 10 sekund. (Czas serwisowania.)

rm -f monthly.log

Czy jest jakiś sposób, aby usunąć ten duży plik bez zamrażania apache?

Jinbom Heo
źródło

Odpowiedzi:

23

Najpierw obróć go za logrotatepomocą takiej konfiguracji:

/path/to/the/log {
    missingok
    notifempty
    sharedscripts
    daily   
    rotate 7
    postrotate
        /sbin/service httpd reload > /dev/null 2>/dev/null || true
    endscript
    compress
}

następnie utwórz zadanie cron o północy, aby usunąć obrócony plik:

30 2 * * * nice -n 19 ionice -c2 -n7 rm -f /path/to/the/log/file.1
kwanty
źródło
Czy możesz wyjaśnić, co to oznacza / robi?
mowwwalker
1
„niszczysz” i „jonizujesz” usunięcie. Przyjemnie służyło to zapewne do zapobiegania nadużywaniu procesora, ale najważniejsze jest tutaj jonice, gdzie tak naprawdę nakazujesz harmonogramowi usunięcie pliku o niższym priorytecie. -c jest dla klasy, gdzie 1 to w czasie rzeczywistym, 2 normalne i 3 bezczynne. W klasie 2 masz od 0 do 7 (IRRC), gdzie 7 jest najniższą. Jeśli nadal powoduje to problemy, uruchom go z 'ionice -c3' i powinno być w porządku.
golan
5

Aby przyspieszyć usuwanie dużych plików, możesz użyć truncatepolecenia - Powiedz, aby zmniejszyć go do zera, a następnie usuń:

 truncate -s 0  monthly.log && rm -f monthly.log

Jednak zgodnie z zaleceniami kwanty należy najpierw przeprowadzić logrotację.

Daniel t.
źródło
Czym się truncateróżni >?
kojiro
hmm dobre pytanie. Wynik jest taki sam, ale nie mam odpowiedzi, jak różnią się one wdrażaniem.
Daniel t.
truncateJest łatwiejszy w użyciu sudoniż >. Jest to również łatwiejsze dzięki find -exec.
kubańczyk
3
echo "0" > monthly.log && rm -f monthly.log
Amit Biyani
źródło
3
Po prostu >logfilenie potrzebujesz echa
9517
3

Skróciłem / wyzerowałem plik za pomocą : > /path/to/monthly.logoperacji. Następnie ewentualnie zrestartuj proces Apache i skonfiguruj rotację logów, aby zapobiec takim sytuacjom w przyszłości ...

Często się to zdarza:

Zobacz: Czy istnieje sposób na usunięcie 100 GB pliku w systemie Linux bez obciążania operacji we / wy?

W Unixie, jaki jest najlepszy sposób na zmniejszenie rozmiaru ogromnego pliku dziennika, który jest aktywnie zapisywany?

Serwer Linux nie ma miejsca

ewwhite
źródło
Nie ma potrzeby :. Możesz po prostu zrobić> /path/to/monthly.log
kojiro,
Wiem, że tak noop, ale ma to większy sens z perspektywy instruktażowej.
ewwhite
… Ale jakiś przyszły instruktor musi poprawić to nieporozumienie. No cóż, myślę, że to bezpieczeństwo pracy.
kojiro
Nie true > /path/to/monthly.logzrobiłby tego samego, a zatem jest mniej archaiczny :?
Stefan Lasiewski
Prawdopodobnie prawda ...
ewwhite
3

Jeśli nie potrzebujesz danych, skróć je, używając / dev / null:

cat /dev/null > monthly.log

Serwer WWW będzie nadal zapisywał dane do pliku po obcięciu, co pozwala uniknąć konieczności ponownego uruchamiania serwera (w przeciwieństwie do rm monthly.logusuwania pliku).

Po rozwiązaniu natychmiastowego kryzysu rozważ logrotację, jak zasugerowała Quanta. Nie chcesz, żeby to się powtórzyło. Zauważ, że pliki dziennika Apache są już domyślnie obrócone w CentOS

Rozważ także wysyłanie dzienników sieciowych przez syslog ( /usr/bin/loggerna przykład za pomocą ). Dzienniki tworzone przy użyciu syslog również zwykle mają już skonfigurowane Logrotation.

Stefan Lasiewski
źródło
5
Możesz po prostu >logfilenie potrzebować cat
user9517
2

Jeśli używasz systemu plików ext3, rozważ przejście na ext4.

Ext3 może być powolny w usuwaniu dużych plików, ponieważ przechowuje lokalizację każdego pojedynczego bloku 4k: plik 50GiB (50 * 1024 ^ 3 bajtów) zajmuje 13107200 bloków, z których każdy jest zapisany w tabeli i-węzłów jako 32-bitowy numer bloku , w sumie 50 MB danych księgowych, aby śledzić, gdzie znajduje się zawartość pliku na dysku. Ta duża lista bloków może być rozproszona na wiele bloków pośrednich , z których wszystkie muszą zostać zaktualizowane po usunięciu pliku. Prawdopodobnie przyczyną opóźnień jest próba uzyskania dostępu do wszystkich pośrednich bloków.

Z drugiej strony Ext4 przydziela pliki w „zakresach” do 128 MB. Ten plik 50GiB można zapisać w tabeli i-węzłów przy użyciu zaledwie 400 rekordów zasięgu, zamiast 13107200 pojedynczych numerów bloków, co radykalnie zmniejsza ilość operacji we / wy dysku podczas usuwania pliku.

Zauważ, że jeśli przekonwertujesz istniejący system plików ext3 w miejsce na ext4, nowe pliki zostaną przydzielone przy użyciu zakresu, ale istniejące pliki nadal będą korzystać z list bloków. Możesz użyć chattr +epolecenia, aby ponownie przydzielić istniejący plik przy użyciu zakresu; pod względem wydajności jest to porównywalne do wykonania kopii pliku, a następnie usunięcia oryginału.

Wyzard
źródło
1

Sprowadza się to do problemu z wydajnością systemu plików. Na to pytanie SO można znaleźć interesującą odpowiedź, ale zależy to raczej od używanego systemu plików. Użyłem XFS podczas tworzenia systemu plików do przechowywania setek wielogigabajtowych plików MPEG2 dla MythTV, ponieważ w tym czasie wydajność usuwania XFS była znacznie lepsza niż ext3. Mogło się znacznie zmienić w kolejnych latach.

Podoba mi się odpowiedź @ quanta. Podzielenie pliku na mniejsze części spowoduje szybsze usunięcie.

Tim Potter
źródło
1

Problem wynika, jak sądzę, z tego, że usuwasz plik z uprzywilejowanego użytkownika, który ma większy priorytet w operacjach na dysku niż użytkownik serwera WWW Apache. Niezależnie od tego, w jaki sposób chcesz usunąć plik dziennika (rm -f lub skrócić o>), powinieneś zmniejszyć jego priorytetowe operacje na dysku do minimum:

  ionice -c3 rm -f filename.log
Andriej Michałow
źródło