OOM Killer zabija rzeczy dużą ilością (?) Wolnej pamięci RAM

11

Zabójca OOM wydaje się zabijać rzeczy, mimo że w moim systemie jest więcej niż wystarczająca ilość wolnej pamięci RAM:

Wykres wykorzystania pamięci (Pełna rozdzielczość)

Wykres wykorzystania IO (Pełna rozdzielczość)

Po 27 minutach i 408 procesach system zaczął ponownie odpowiadać. Uruchomiłem go ponownie około godzinę później i wkrótce potem wykorzystanie pamięci wróciło do normy (dla tej maszyny).

Po inspekcji na moim pudełku działa kilka interesujących procesów:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
[...snip...]
root      1399 60702042  0.2 482288 1868 ?     Sl   Feb21 21114574:24 /sbin/rsyslogd -i /var/run/syslogd.pid -c 4
[...snip...]
mysql     2022 60730428  5.1 1606028 38760 ?   Sl   Feb21 21096396:49 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock
[...snip...]

Ten konkretny serwer działa od ok. 8 godzin, a są to jedyne dwa procesy, które mają takie ... nieparzyste wartości. Podejrzewam, że dzieje się „coś innego”, potencjalnie związane z tymi nie-zmysłowymi wartościami. Mówiąc konkretnie, myślę, że system uważa , że brakuje pamięci, podczas gdy w rzeczywistości tak nie jest. W końcu uważa, że ​​rsyslogd konsekwentnie używa 55383984% CPU, podczas gdy teoretyczne maksimum w tym systemie wynosi 400%.

Jest to w pełni aktualna instalacja CentOS 6 (6.2) z 768 MB pamięci RAM. Będziemy wdzięczni za wszelkie sugestie, jak dowiedzieć się, dlaczego tak się dzieje.

edycja: dołączanie vm. sysctl tunables .. Gram z swapiness (co widać po 100), a także uruchamiam absolutnie okropny skrypt, który zrzuca moje bufory i pamięć podręczną (widoczne przez vm.drop_caches 3) + synchronizuje dysk co 15 minut. Właśnie dlatego po ponownym uruchomieniu buforowane dane wzrosły do ​​nieco normalnego rozmiaru, ale potem szybko spadły. Rozumiem, że posiadanie pamięci podręcznej jest bardzo dobrą rzeczą, ale dopóki się tego nie dowiem ...

Interesujące jest również to, że podczas gdy mój plik strony urósł podczas wydarzenia, osiągnął jedynie ~ 20% całkowitego możliwego wykorzystania, co nie jest charakterystyczne dla prawdziwych zdarzeń OOM. Na drugim końcu spektrum dysk oszalał w tym samym okresie, co jest charakterystyczne dla zdarzenia OOM, gdy plik strony jest w grze.

sysctl -a 2>/dev/null | grep '^vm':

vm.overcommit_memory = 1
vm.panic_on_oom = 0
vm.oom_kill_allocating_task = 0
vm.extfrag_threshold = 500
vm.oom_dump_tasks = 0
vm.would_have_oomkilled = 0
vm.overcommit_ratio = 50
vm.page-cluster = 3
vm.dirty_background_ratio = 10
vm.dirty_background_bytes = 0
vm.dirty_ratio = 20
vm.dirty_bytes = 0
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000
vm.nr_pdflush_threads = 0
vm.swappiness = 100
vm.nr_hugepages = 0
vm.hugetlb_shm_group = 0
vm.hugepages_treat_as_movable = 0
vm.nr_overcommit_hugepages = 0
vm.lowmem_reserve_ratio = 256   256     32
vm.drop_caches = 3
vm.min_free_kbytes = 3518
vm.percpu_pagelist_fraction = 0
vm.max_map_count = 65530
vm.laptop_mode = 0
vm.block_dump = 0
vm.vfs_cache_pressure = 100
vm.legacy_va_layout = 0
vm.zone_reclaim_mode = 0
vm.min_unmapped_ratio = 1
vm.min_slab_ratio = 5
vm.stat_interval = 1
vm.mmap_min_addr = 4096
vm.numa_zonelist_order = default
vm.scan_unevictable_pages = 0
vm.memory_failure_early_kill = 0
vm.memory_failure_recovery = 1

edytuj: i dołączając pierwszą wiadomość OOM ... po bliższym przyjrzeniu się, mówi ona, że ​​coś wyraźnie wyszło z siebie, by zjeść całą moją przestrzeń wymiany.

Feb 21 17:12:49 host kernel: mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
Feb 21 17:12:51 host kernel: mysqld cpuset=/ mems_allowed=0
Feb 21 17:12:51 host kernel: Pid: 2777, comm: mysqld Not tainted 2.6.32-71.29.1.el6.x86_64 #1
Feb 21 17:12:51 host kernel: Call Trace:
Feb 21 17:12:51 host kernel: [<ffffffff810c2e01>] ? cpuset_print_task_mems_allowed+0x91/0xb0
Feb 21 17:12:51 host kernel: [<ffffffff8110f1bb>] oom_kill_process+0xcb/0x2e0
Feb 21 17:12:51 host kernel: [<ffffffff8110f780>] ? select_bad_process+0xd0/0x110
Feb 21 17:12:51 host kernel: [<ffffffff8110f818>] __out_of_memory+0x58/0xc0
Feb 21 17:12:51 host kernel: [<ffffffff8110fa19>] out_of_memory+0x199/0x210
Feb 21 17:12:51 host kernel: [<ffffffff8111ebe2>] __alloc_pages_nodemask+0x832/0x850
Feb 21 17:12:51 host kernel: [<ffffffff81150cba>] alloc_pages_current+0x9a/0x100
Feb 21 17:12:51 host kernel: [<ffffffff8110c617>] __page_cache_alloc+0x87/0x90
Feb 21 17:12:51 host kernel: [<ffffffff8112136b>] __do_page_cache_readahead+0xdb/0x210
Feb 21 17:12:51 host kernel: [<ffffffff811214c1>] ra_submit+0x21/0x30
Feb 21 17:12:51 host kernel: [<ffffffff8110e1c1>] filemap_fault+0x4b1/0x510
Feb 21 17:12:51 host kernel: [<ffffffff81135604>] __do_fault+0x54/0x500
Feb 21 17:12:51 host kernel: [<ffffffff81135ba7>] handle_pte_fault+0xf7/0xad0
Feb 21 17:12:51 host kernel: [<ffffffff8103cd18>] ? pvclock_clocksource_read+0x58/0xd0
Feb 21 17:12:51 host kernel: [<ffffffff8100f951>] ? xen_clocksource_read+0x21/0x30
Feb 21 17:12:51 host kernel: [<ffffffff8100fa39>] ? xen_clocksource_get_cycles+0x9/0x10
Feb 21 17:12:51 host kernel: [<ffffffff8100c949>] ? __raw_callee_save_xen_pmd_val+0x11/0x1e
Feb 21 17:12:51 host kernel: [<ffffffff8113676d>] handle_mm_fault+0x1ed/0x2b0
Feb 21 17:12:51 host kernel: [<ffffffff814ce503>] do_page_fault+0x123/0x3a0
Feb 21 17:12:51 host kernel: [<ffffffff814cbf75>] page_fault+0x25/0x30
Feb 21 17:12:51 host kernel: Mem-Info:
Feb 21 17:12:51 host kernel: Node 0 DMA per-cpu:
Feb 21 17:12:51 host kernel: CPU    0: hi:    0, btch:   1 usd:   0
Feb 21 17:12:51 host kernel: CPU    1: hi:    0, btch:   1 usd:   0
Feb 21 17:12:51 host kernel: CPU    2: hi:    0, btch:   1 usd:   0
Feb 21 17:12:51 host kernel: CPU    3: hi:    0, btch:   1 usd:   0
Feb 21 17:12:51 host kernel: Node 0 DMA32 per-cpu:
Feb 21 17:12:51 host kernel: CPU    0: hi:  186, btch:  31 usd:  47
Feb 21 17:12:51 host kernel: CPU    1: hi:  186, btch:  31 usd:   0
Feb 21 17:12:51 host kernel: CPU    2: hi:  186, btch:  31 usd:   0
Feb 21 17:12:51 host kernel: CPU    3: hi:  186, btch:  31 usd: 174
Feb 21 17:12:51 host kernel: active_anon:74201 inactive_anon:74249 isolated_anon:0
Feb 21 17:12:51 host kernel: active_file:120 inactive_file:276 isolated_file:0
Feb 21 17:12:51 host kernel: unevictable:0 dirty:0 writeback:2 unstable:0
Feb 21 17:12:51 host kernel: free:1600 slab_reclaimable:2713 slab_unreclaimable:19139
Feb 21 17:12:51 host kernel: mapped:177 shmem:84 pagetables:12939 bounce:0
Feb 21 17:12:51 host kernel: Node 0 DMA free:3024kB min:64kB low:80kB high:96kB active_anon:5384kB inactive_anon:5460kB active_file:36kB inactive_file:12kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:14368kB mlocked:0kB dirty:0kB writeback:0kB mapped:16kB shmem:0kB slab_reclaimable:16kB slab_unreclaimable:116kB kernel_stack:32kB pagetables:140kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:8 all_unreclaimable? no
Feb 21 17:12:51 host kernel: lowmem_reserve[]: 0 741 741 741
Feb 21 17:12:51 host kernel: Node 0 DMA32 free:3376kB min:3448kB low:4308kB high:5172kB active_anon:291420kB inactive_anon:291536kB active_file:444kB inactive_file:1092kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:759520kB mlocked:0kB dirty:0kB writeback:8kB mapped:692kB shmem:336kB slab_reclaimable:10836kB slab_unreclaimable:76440kB kernel_stack:2520kB pagetables:51616kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:2560 all_unreclaimable? yes
Feb 21 17:12:51 host kernel: lowmem_reserve[]: 0 0 0 0
Feb 21 17:12:51 host kernel: Node 0 DMA: 5*4kB 4*8kB 2*16kB 0*32kB 0*64kB 1*128kB 1*256kB 1*512kB 0*1024kB 1*2048kB 0*4096kB = 3028kB
Feb 21 17:12:51 host kernel: Node 0 DMA32: 191*4kB 63*8kB 9*16kB 2*32kB 0*64kB 1*128kB 1*256kB 1*512kB 1*1024kB 0*2048kB 0*4096kB = 3396kB
Feb 21 17:12:51 host kernel: 4685 total pagecache pages
Feb 21 17:12:51 host kernel: 4131 pages in swap cache
Feb 21 17:12:51 host kernel: Swap cache stats: add 166650, delete 162519, find 1524867/1527901
Feb 21 17:12:51 host kernel: Free swap  = 0kB
Feb 21 17:12:51 host kernel: Total swap = 523256kB
Feb 21 17:12:51 host kernel: 196607 pages RAM
Feb 21 17:12:51 host kernel: 6737 pages reserved
Feb 21 17:12:51 host kernel: 33612 pages shared
Feb 21 17:12:51 host kernel: 180803 pages non-shared
Feb 21 17:12:51 host kernel: Out of memory: kill process 2053 (mysqld_safe) score 891049 or a child
Feb 21 17:12:51 host kernel: Killed process 2266 (mysqld) vsz:1540232kB, anon-rss:4692kB, file-rss:128kB
Kyle Brantley
źródło
Można zapewnić wyjście sysctl -a 2>/dev/null | grep '^vm'?
Patrick
Dodany. Mam nadzieję, że ty (lub ktoś) znajdziesz coś, za czym tęskniłem.
Kyle Brantley,
Jedyną rzeczą, która na mnie wyskakuje, jest overcommit_memoryotoczenie. Ustawienie go na 1 nie powinno powodować takiego zachowania, ale nigdy wcześniej nie musiałem ustawiać go na „zawsze przesadzaj”, więc nie ma tam zbyt dużego doświadczenia. Patrząc na inne dodane przez ciebie notatki, powiedziałeś, że zamiana została wykorzystana tylko w 20%. Jednak według dziennika wysypisko OOM, Free swap = 0kB. Zdecydowanie myślał, że zamiana została wykorzystana w 100%.
Patrick

Odpowiedzi:

13

Właśnie spojrzałem na zrzut dziennika logów i kwestionuję dokładność tego wykresu. Zwróć uwagę na pierwszą linię „Node 0 DMA32”. Mówi ona free:3376kB, min:3448kBi low:4308kB. Ilekroć wartość swobodna spada poniżej niskiej wartości, kswapd powinien zacząć zamieniać rzeczy, dopóki wartość ta nie wzrośnie powyżej wysokiej wartości. Ilekroć wolne spadnie poniżej wartości minimalnej, system zasadniczo zawiesza się, dopóki jądro nie przywróci wartości powyżej wartości minimalnej. Ten komunikat wskazuje również, że swap został całkowicie wykorzystany tam, gdzie jest napisany Free swap = 0kB.
Zasadniczo uruchomił się kswapd, ale swap był pełny, więc nie mógł nic zrobić, a wartość pages_free wciąż była niższa od wartości pages_min, więc jedyną opcją było rozpoczęcie zabijania rzeczy, dopóki nie odzyska strony.
Zdecydowanie zabrakło ci pamięci.

http://web.archive.org/web/20080419012851/http://people.redhat.com/dduval/kernel/min_free_kbytes.html ma naprawdę dobre wyjaśnienie, jak to działa. Zobacz sekcję „Implementacja” u dołu.

Patrick
źródło
1
Zatem OP naprawdę potrzebuje po prostu więcej pamięci RAM ...
ewwhite
więcej ram, lub dowiedzieć się, co je.
Patrick
Umieszczam linie na tym wykresie bardzo dokładnie. Zatrzymał rejestrowanie danych ~ 1-2m przed zabiciem pierwszego procesu i wznowił rejestrowanie danych ~ 4-5m po zabiciu ostatniego procesu. W tym momencie zakładam się, że jakiś proces całkowicie zwariował i zaczął przerzucać mój plik stronicowania - gdy w końcu wszystko uzyskał, zabijał również procesy, które funkcjonalnie kończyły się z pliku stronicowania, i dlatego, gdy dane zostały zwrócone, plik strony został podniesiony, ale nie pełny. Mile widziane są sugestie, jak ustalić, co to robi!
Kyle Brantley,
@KyleBrantley Jakie wartości wyciągasz, aby wygenerować wykres? Jedną z wad systemu pamięci wirtualnej systemu Linux jest brak konkretnej definicji „wolnego”. Istnieje kilkanaście sposobów definiowania „wolnej pamięci”. O ile kswapd ma znaczenie, to wartość page_free. Jeśli chodzi o darmową zamianę, nie wiem, jaką wartość możesz czytać, która byłaby tak daleko. Jedynym sposobem, aby naprawdę zobaczyć, co zjada pamięć, jest rejestrowanie ciągłych migawek wszystkich procesów na pudełku i zobacz, co zużywa całą pamięć, gdy zabójca oom zaczyna wariować.
Patrick
2
Tak, zabrakło mi pamięci. Skończyło się na przeszukiwaniu dzienników i stwierdzeniu, że moje procesy potomne Apache były wielokrotnie zabijane, co doprowadziło mnie do wniosku, że miałem funkcjonalnie nieskończone procesy potomne, które można rozpocząć. Wystarczyło zautomatyzowane boty blogspamowe wysyłające do hosta wiele żądań / sekundę, aby się przewrócił. Poprawianie apache rozwiązało wszystko.
Kyle Brantley,
3

Pozbądź się skryptu drop_caches. Ponadto powinieneś opublikować odpowiednie części swojego dmesgi /var/log/messageswyników pokazujące wiadomości OOM.

Aby jednak zatrzymać to zachowanie, polecam wypróbowanie tego sysctlstrojenia. Jest to system RHEL / CentOS 6 i wyraźnie działa na ograniczonych zasobach. Czy to maszyna wirtualna?

Spróbuj zmodyfikować /proc/sys/vm/nr_hugepagesi sprawdź, czy problemy nadal występują. Może to być problem fragmentacji pamięci, ale sprawdź, czy to ustawienie robi różnicę. Aby zmienić na stałe, dodaj vm.nr_hugepages = valuedo /etc/sysctl.confi uruchom sysctl -pponownie plik konfiguracyjny ...

Zobacz także: Interpretacja komunikatów o błędach alokacji strony w kryptycznym jądrze

ewwhite
źródło
Dodano pierwszą wiadomość o zabójcy oom. Chociaż MySQL jest najbardziej wymagającą pamięcią RAM, którą uruchomiłem, zmniejszyłem go również, aby nie przytłaczać pudełka, więc poza szalonymi wartościami, które widzę na górze, tak naprawdę nie podejrzewam tego (5,1% użycie pamięci jest w porządku, wszystko należy wziąć pod uwagę). Jest to VPS z 768 MB pamięci RAM. Przeczytam na nr_hugepages i spróbuję, dzięki!
Kyle Brantley,
@ewwhite przyznając, że wiele stronnic zabiłoby skrzynkę. W pudełku jest tylko RAM o pojemności 768 MB, a przy domyślnym hugepagesz o wartości 2 MB, który przydzieliłby 2 GB stron o dużej pojemności. Pudełko nie byłoby w stanie sobie z tym poradzić i natychmiast umarłoby.
Patrick
Zaktualizowano Wartość należy jednak zwiększyć od zera.
ewwhite
To jest jeszcze bardziej skomplikowane. Musisz ustawić uprawnienia do wielkich stron, a mysql musi być skonfigurowany do korzystania z dużych stron, w przeciwnym razie po prostu przydzielasz je bez powodu.
Patrick,
2

Brak dostępnych danych na wykresie od momentu uruchomienia zabójcy OOM do jego zakończenia. Wierzę w czasie, w którym wykres jest przerywany, że tak naprawdę zużycie pamięci gwałtownie wzrasta i nie ma już dostępnej pamięci. W przeciwnym razie zabójca OOM nie byłby używany. Jeśli obejrzysz wykres wolnej pamięci po zatrzymaniu się zabójcy OOM, zobaczysz, że spada on z wyższej wartości niż wcześniej. Przynajmniej dobrze wykonał swoją pracę, zwalniając pamięć.

Pamiętaj, że twoja przestrzeń wymiany jest prawie w pełni wykorzystana do ponownego uruchomienia. To prawie nigdy nie jest dobra rzecz i pewny znak, że pozostało mało wolnej pamięci.

Przyczyną braku danych dla tego konkretnego przedziału czasowego jest to, że system jest zbyt zajęty innymi sprawami. „Śmieszne” wartości na liście procesów mogą być wynikiem, a nie przyczyną. Nie jest to niespotykane.

Sprawdź /var/log/kern.log i / var / log / messages, jakie informacje tam znajdziesz?

Jeśli rejestrowanie również zostało zatrzymane, wypróbuj inne rzeczy, zrzucaj listę procesów do pliku co sekundę, tak samo jak informacje o wydajności systemu. Uruchom go z wysokim priorytetem, aby mógł nadal wykonywać swoją pracę (miejmy nadzieję), gdy obciążenie wzrośnie. Chociaż jeśli nie masz jądra wyprzedzającego (czasami określanego jako jądro „serwera”), możesz mieć pecha w tym względzie.

Myślę, że przekonasz się, że proces (y), które wykorzystują najwięcej procesora% w czasie, gdy zaczynają się problemy, jest (są) przyczyną. Nigdy nie widziałem, aby rsyslogd ani mysql zachowywały się w ten sposób. Bardziej prawdopodobnymi winowajcami są aplikacje Java i aplikacje sterowane GUI, takie jak przeglądarka.

aseq
źródło
W tej szczelinie nie ma danych, ponieważ obciążenie skrzyni gwałtownie wzrasta tak absurdalnie, że wszystko, łącznie z agentem monitorującym, zatrzymuje się całkowicie. Sam agent nigdy nie został zabity w okresie bliskiej śmierci, ale nie mógł również zgłosić żadnych danych z powrotem. Moja przestrzeń wymiany była właściwie w porządku. Używał ~ 130/512 MB łącznie przed ponownym uruchomieniem. rsyslogd jest skonfigurowany do raportowania dzienników do lokalizacji sieciowej, w której wszystko, co się wydarzyło, zostało zarejestrowane - a poza tym zabijało 408 procesów (niektóre z nich były dziećmi apache, które zostały zrestartowane), nic się nie wyróżniało.
Kyle Brantley
Mogę skończyć zrzucaniem kompletnej listy procesów do pliku (lub sieci) co kilka sekund, jeśli nie mogę właściwie dowiedzieć się, co się tutaj dzieje, więc dziękuję za dobry pomysł.
Kyle Brantley
Tak, powinieneś to zrobić, upewnij się, że rejestrujesz również użycie procesora przez każdy proces, spójrz na „top-b” (tryb wsadowy). Winowajcą może być proces, który przyspiesza.
aseq