Debuguj brak pamięci za pomocą / var / log / messages

42

W moim dzienniku wiadomości znajduje się następujący raport:

kernel: Out of memory: Kill process 9163 (mysqld) score 511 or sacrifice child
kernel: Killed process 9163, UID 27, (mysqld) total-vm:2457368kB, anon-rss:816780kB, file-rss:4kB

Nie ma znaczenia, czy ten problem jest httpd, mysqldalbo postfix, ale jestem ciekaw, w jaki sposób można kontynuować debugowania problemu.

Jak mogę uzyskać więcej informacji o tym, dlaczego PID 9163 został zabity i nie jestem pewien, czy Linux gdzieś przechowuje historię dla zakończonych PID.

Jeśli tak się stanie w pliku dziennika wiadomości, w jaki sposób krok po kroku rozwiążesz ten problem?

# free -m

             total       used       free     shared    buffers     cached
Mem:          1655        934        721          0         10         52
-/+ buffers/cache:        871        784
Swap:          109          6        103`
ibedelovski
źródło
w których pojawiają się wszystkie wiadomości dotyczące problemu dmesg?
Stark07
Przydatne informacje na temat OOM - linux-mm.org/OOM_Killer .
slm

Odpowiedzi:

57

Jądro zarejestruje kilka rzeczy, zanim to się stanie, ale większość z nich prawdopodobnie nie będzie dostępna, w /var/log/messageszależności od (r)syslogdkonfiguracji. Próbować:

grep oom /var/log/*
grep total_vm /var/log/*

Ten pierwszy powinien pojawić się kilka razy, a drugi tylko w jednym lub dwóch miejscach. To jest plik, który chcesz obejrzeć.

Znajdź oryginalny wiersz „Brak pamięci” w jednym z plików, który również zawiera total_vm. Trzydzieści sekund do minuty (może być więcej, może być mniej) przed tą linią znajdziesz coś takiego:

kernel: foobar invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0

Powinieneś także znaleźć tabelę gdzieś pomiędzy tą linią a linią „Brak pamięci” z takimi nagłówkami:

[ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name

To może niewiele powiedzieć, niż już wiesz, ale pola są następujące:

  • pid Identyfikator procesu.
  • identyfikator użytkownika.
  • tgid Identyfikator grupy wątków.
  • total_vm Wykorzystanie pamięci wirtualnej (na stronach 4 kB)
  • rss Wykorzystanie pamięci rezydentnej (na stronach 4 kB)
  • nr_ptes Wpisy w tabeli stron
  • swapents Zamień wpisy
  • oom_score_adj Zwykle 0; niższa liczba wskazuje, że proces będzie mniej podatny na śmierć po wywołaniu zabójcy OOM.

Możesz w większości zignorować nr_ptesi swapentschociaż uważam, że są to czynniki decydujące o tym, kto zostanie zabity. Niekoniecznie jest to proces wykorzystujący najwięcej pamięci, ale najprawdopodobniej tak jest. Aby uzyskać więcej informacji na temat procesu wyboru, zobacz tutaj . Zasadniczo proces, który kończy się najwyższym wynikiem oom, zostaje zabity - taki jest „wynik” podany w wierszu „Brak pamięci”; niestety inne wyniki nie są zgłaszane, ale ta tabela zawiera pewne wskazówki dotyczące czynników.

Ponownie, prawdopodobnie nie zrobi to więcej niż tylko wyjaśnienie oczywistości: system zabrakło pamięci i mysqldzostał wybrany, aby umrzeć, ponieważ zabicie go uwolniłoby najwięcej zasobów . Nie oznacza mysqldto, że robi coś złego. Możesz spojrzeć na tabelę, aby sprawdzić, czy coś innego nie poszło w tym czasie poza linię, ale może nie być wyraźnego winowajcy: w systemie może zabraknąć pamięci tylko dlatego, że źle oceniłeś lub źle skonfigurowałeś uruchomione procesy.

Złotowłosa
źródło
5
dmesgjest tam, gdzie jest to gwarantowane. Będzie to możliwe tylko /var/logwtedy, gdy demon syslog będzie czytał /dev/kmsg(co zwykle robi).
Patrick,
2
@Patrick To zależy od tego, kiedy idziesz szukać. Jeśli jest zapisany w jednym z normalnych dzienników plików (powinien być, lub zrobiłeś coś głupiego za pomocą loggera), będzie tam przez długi czas, podczas gdy do tego momentu, jeśli OP chce zdiagnozować problem, który wystąpił wczoraj lub dzień wcześniej itp. rekord może już nie być dmesgobecny, nawet jeśli system był uruchomiony.
Złotowłosa
6

Kluczem do tego jest sama wiadomość - Brak pamięci . Kiedy jądro Linuksa jest pozbawione pamięci wirtualnej (fizycznej pamięci RAM i wymiany), zacznie zabijać procesy i dokładnie to się tutaj wydarzyło. Wygląda na to, że mysqldzużywał ponad 2 GB pamięci wirtualnej.

Ile pamięci RAM i wymiany ma system? Rozważę dodanie dodatkowej pamięci RAM lub, jeśli to niemożliwe, dodanie dodatkowej wymiany. Jako szybką poprawkę, która przynajmniej zapobiegnie zakończeniu procesów, możesz dodać plik wymiany.

Aktualizacja: Patrząc na ilość pamięci RAM, możesz od razu zobaczyć problem. Masz ~ 1,6 GB pamięci RAM i 100 MB wymiany, ale MySQL zużywa znacznie więcej pamięci RAM niż to. To wyjaśnia, dlaczego procesy są kończone.

mjturner
źródło
total used free shared buffers cached Mem: 1655 934 721 0 10 52 -/+ buffers/cache: 871 784 Swap: 109 6 103 jest to wyjście pamięci w tym samym czasie, gdy proces został zabity
ibedelovski
Czy możesz to wkleić w oryginalnej wiadomości, zachowując formatowanie? Ułatwiłoby to czytanie.
mjturner
Nie jestem naprawdę dobry w formatowaniu ... ale już
wklejam