Elfogyott a memória: OOM killer, free parancs és swap fájl létrehozása

Ha a szerveren váratlanul leáll a MariaDB, a PHP-FPM vagy egy másik szolgáltatás, és a weboldal adatbázis-kapcsolódási hibát ad, gyakori ok, hogy elfogyott a memória. Ilyenkor a Linux kernel OOM killer (Out Of Memory killer) nevű része kiválaszt egy sok memóriát használó folyamatot, és leállítja, hogy a rendszer egésze működőképes maradjon. Ez legtöbbször éppen az adatbázis-kiszolgáló.

Mennyi a szabad memória?

free -h
               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       2.9Gi       150Mi        45Mi       800Mi       650Mi
Swap:             0B          0B          0B

A free oszlop alacsony értéke önmagában nem baj: a Linux a szabad memóriát gyorsítótárként (buff/cache) használja, és szükség esetén felszabadítja. A valóban elérhető memóriát az available oszlop mutatja. Ha ez tartósan a teljes memória néhány százaléka alá esik, és nincs swap (Swap: 0B), a szerver ki van téve az OOM killernek.

Az OOM killer nyomai

Hogy egy folyamatot az OOM killer állított-e le, a kernel üzeneteiből derül ki:

sudo journalctl -k | grep -i -E "out of memory|killed process"
sudo dmesg -T | grep -i -E "out of memory|killed process"

Egy jellemző sor:

Out of memory: Killed process 1234 (mariadbd) total-vm:2456780kB, anon-rss:1203456kB

A naplók olvasásáról bővebben: Naplófájlok olvasása Linuxon.

Mi használja a memóriát?

ps aux --sort=-%mem | head -n 15

A %MEM és az RSS (kilobájtban) oszlop mutatja, melyik folyamat mennyi memóriát foglal. Interaktívan a top vagy htop paranccsal követheti (M billentyűvel rendezhet memória szerint), lásd: Folyamatok figyelése top és htop paranccsal.

A leggyakoribb okok:

  • MariaDB/MySQL: az innodb_buffer_pool_size túl nagyra van állítva a szerver memóriájához képest. Kisebb VPS-en a teljes memória legfeljebb 40-50%-át adja neki, ha a webszerver is ugyanazon a gépen fut.
  • PHP-FPM: a pm.max_children értéke túl magas. Minden PHP folyamat 50-150 MB memóriát is használhat, így 20 párhuzamos folyamat könnyen több gigabájtot foglal.
  • Elszabadult szkript, memóriaszivárgás vagy hirtelen megugrott forgalom (bot, támadás).

Swap fájl létrehozása

A swap a lemezen lévő terület, ahová a kernel a ritkán használt memórialapokat kiírhatja (lásd: Mi az a swap a Linuxban?). Lassabb a memóriánál, ezért nem pótolja a kevés RAM-ot, de a hirtelen csúcsoknál időt ad, és megelőzheti, hogy az OOM killer leállítsa az adatbázist.

Ellenőrizze, van-e már swap:

swapon --show

Ha a parancs nem ír ki semmit, hozzon létre például egy 2 GB-os swap fájlt:

sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Hogy újraindítás után is megmaradjon, vegye fel az /etc/fstab fájlba:

echo '/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab

Ellenőrzés:

swapon --show
free -h

Mekkora legyen? 1-4 GB memóriájú VPS-en általában 1-2 GB swap elegendő. Előtte a df -h / paranccsal győződjön meg róla, hogy van elég szabad hely a lemezen.

Swappiness

A vm.swappiness érték (0-100) azt határozza meg, mennyire szívesen használja a kernel a swapot. Szerveren érdemes alacsonyra állítani, hogy csak valódi szükség esetén nyúljon hozzá:

echo 'vm.swappiness = 10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl -p /etc/sysctl.d/99-swappiness.conf

Ha a swap folyamatosan használatban van

Ha a free -h szerint a swap tartósan tele van, és a szerver lassú (a top kimenetében magas a wa érték), a szervernek kevés a memóriája. Ilyenkor csökkentse a fenti szolgáltatások memóriahasználatát, vagy váltson nagyobb csomagra (lásd: Hogyan bővíthetem VPS csomagom erőforrásait?).

Megosztott tárhelyen a memóriát a CloudLinux korlátozza fiókonként; ott a memórialimit elérése általában 500-as vagy 503-as hibát okoz, lásd: CloudLinux erőforrás limitek.