podivné problémy s alokací paměti / CentOS 6.2 na VPS

Tomas Vondra tv na fuzzy.cz
Neděle Únor 26 19:17:56 CET 2012


Ahoj,

narazil jsem na hodně divné problémy s alokací paměti na jednom
linuxovém VPS. Dosavadní pokusy bohužel nevedly k odhalení příčin.

VPS je "malé" - má jenom 512MB paměti, 1 CPU, je na něm CentOS 6.2 s
aktuálním kernelem (2.6.32-220.4.2.el6.x86_64, zkoušel jsem i původní
2.6.32-71.el6.x86_64). Nainstalován je na něm celkem standardní stack,
tj. apache, php, postgresql, postfix, dovecot, memcached, ssh. V zásadě
žádná exotika (všechno z oficiálních repositářů, jenom postfix a
postgresql jsou bokem). Nijak zvlášť vytížený není.

Podrobnější logy (víc dat než je uvedeno dále) jsem dal sem:

  http://pastebin.com/1kU6xeNQ

Naráželi jsme na problémy s I/O vytížením (dalšími VPS), takže jsme se
domluvili na migraci na jiný fyzický stroj - po migraci se začaly
projevovat problémy s alokací paměti při startu a běhu služeb ačkoliv
podle free je paměti volné dost:

[root na vps audit]# free
         total       used       free     shared    buffers     cached
Mem:    502728     294224     208504          0      18604     163608
-/+ buffers/cache: 112012     390716
Swap:        0          0          0

tj. cca 200MB volno, ale apache procesy padají na segfaultech buď už při
forku:

  [16:49:51 2012] [error] (12)Cannot allocate memory: fork: Unable to
                          fork new process
  [16:51:17 2012] [notice] child pid 2577 exit signal Segmentation
                           fault (11)

nebo během vyřizování požadavků:

  [26 16:30:16 2012] [error] [client 66.249.72.1] PHP Fatal error:  Out
  of memory (allocated 262144) (tried to allocate 523800 bytes) in
  Unknown on line 0

přitom PHP má povolenou paměť 32 MB, takže tím to nebude. Podobně se
chová PostgreSQL:

  16:42:01 CET pid=2504 db=xxxxxx-drupal user=xxxxxx FATAL:  out of
               memory
  16:42:01 CET pid=2504 db=xxxxxx-drupal user=xxxxxx DETAIL:  Failed on
               request of size 2488.
  16:42:01 CET pid=2438 db= user= LOG:  could not fork new process for
               connection: Nelze alokovat paměť
  16:42:01 CET pid=2438 db= user= 4f4a5247.986:21 LOG:  could not fork
               new process for connection: Nelze alokovat paměť

Absolutně mne nenapadá čím by to mohlo být / jak to opravit. Přitom ale
podle free/vmstat je celou dobu volných cca 200MB paměti, takže ty alloc
chyby nechápu a nikdy jsem se s něčím takovým myslím nesetkal.

Co je ještě záhadnější je že po přidání swapfile to najednou začalo
fungovat a přitom podle vmstat/free se swap vůbec nepoužívá ... a ještě
ke všemu pak nejde odpojit kvůli chybě v alokaci paměti.

  # dd if=/dev/zero of=swap.img bs=1024 count=409600
  # mkswap swap.img
  # swapon swap.img

  ... start sluzeb apod ...

  # swapon -s

    Filename             Type        Size    Used    Priority
    /root/swap.img       file        399992  0       -1

  # free
           total     used     free   shared  buffers   cached
    Mem:  503412   294192   209220        0    11740    99980
    -/+ buffers/cache: 182472   320940
    Swap: 399992        0   399992

  # swapoff swap.img
    swapoff: swap.img: swapoff selhal: Nelze alokovat paměť

Napadá někoho možná příčina tohoto chování?

To že se tyto problémy neobjevovaly už dříve je možná způsobeno právě
tím swapem - před časem jsem tam ručně připojil swap kvůli upgrade
kernelu (depmod padal na OOM) a ten se při rebootu odpojil.

Na systému je zapnutý SELinux, nicméně ten problémy zřejmě nepůsobí (v
audit logu jsou jenom informace o tom že došlo k segfaultu procesu,
jinak nic podezřelého).

Jinak je to standardní instalace CentOSu, jediné co jsme tam "štelovali"
je nastavení shared segmentů v sysctl.conf kvůli databázi. Aktuálně je tam:

  kernel.shmmax = 68719476736
  kernel.shmall = 134217728
  vm.swappiness = 0
  vm.overcommit_memory = 2

což je myslím OK ... nějaké napady?

díky
Tomáš


Další informace o konferenci Linux