Zmanjkalo je pomnilnika: OOM killer, ukaz free in ustvarjanje datoteke swap

Linux Branje: 3 min

Če se na strežniku nepričakovano ustavi MariaDB, PHP-FPM ali druga storitev in spletna stran vrne napako povezave s podatkovno bazo, je pogost vzrok, da je zmanjkalo pomnilnika. Takrat del jedra Linux z imenom OOM killer (Out Of Memory killer) izbere proces, ki porablja veliko pomnilnika, in ga ustavi, da sistem kot celota ostane delujoč. To je največkrat prav strežnik podatkovnih baz.

Koliko je prostega pomnilnika?

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

Nizka vrednost v stolpcu free sama po sebi ni težava: Linux prosti pomnilnik uporablja kot predpomnilnik (buff/cache) in ga po potrebi sprosti. Resnično razpoložljiv pomnilnik pokaže stolpec available. Če ta trajno pade pod nekaj odstotkov skupnega pomnilnika in ni swapa (Swap: 0B), je strežnik izpostavljen OOM killerju.

Sledi OOM killerja

Ali je proces ustavil OOM killer, razkrijejo sporočila jedra:

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

Resnična vrstica s testnega računalnika z 2 GB pomnilnika brez swapa, kjer je med veliko sistemsko posodobitvijo pomnilnik porabil dnf:

Out of memory: Killed process 16943 (dnf) total-vm:1802676kB, anon-rss:1486780kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:3104kB oom_score_adj:0

V oklepaju je ime ustavljenega programa, anon-rss pa njegov dejansko porabljeni pomnilnik (tu pribl. 1,4 GB). dmesg kot navaden uporabnik ni berljiv („read kernel buffer failed: Operation not permitted”), zato ga zaženi s sudo.

Več o branju dnevnikov: Branje dnevniških datotek v Linuxu.

Kaj porablja pomnilnik?

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

Stolpca %MEM in RSS (v kilobajtih) pokažeta, koliko pomnilnika zaseda kateri proces. Interaktivno ga lahko spremljaš z ukazom top ali htop (s tipko M razvrstiš po pomnilniku), glej: Spremljanje procesov z ukazoma top in htop.

Najpogostejši vzroki:

  • MariaDB/MySQL: innodb_buffer_pool_size je glede na pomnilnik strežnika nastavljen previsoko. Na manjšem VPS mu daj največ 40–50 % skupnega pomnilnika, če na istem računalniku teče tudi spletni strežnik.
  • PHP-FPM: vrednost pm.max_children je previsoka. Vsak proces PHP lahko porabi 50–150 MB pomnilnika, zato 20 vzporednih procesov zlahka zasede več gigabajtov.
  • Podivjana skripta, puščanje pomnilnika ali nenadno povečan promet (bot, napad).

Ustvarjanje datoteke swap

Swap je prostor na disku, kamor lahko jedro zapiše redko uporabljane strani pomnilnika (glej: Kaj je swap v Linuxu?). Je počasnejši od pomnilnika, zato ne nadomesti premajhnega RAM-a, ob nenadnih konicah pa da čas in lahko prepreči, da bi OOM killer ustavil podatkovno bazo.

Preveri, ali swap že obstaja:

swapon --show

Če ukaz ne izpiše ničesar, ustvari na primer 2-GB datoteko swap:

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

Da ostane tudi po ponovnem zagonu, jo dodaj v datoteko /etc/fstab:

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

Preverjanje:

swapon --show
free -h
NAME      TYPE SIZE USED PRIO
/swapfile file   2G   0B   -2

V preizkusu se je po zgornji 2-GB datoteki swap ista posodobitev, ki jo je prej ustavil OOM killer, izvedla brezhibno, datoteka swap pa je ostala aktivna tudi po ponovnem zagonu.

Kako velik naj bo? Na VPS z 1–4 GB pomnilnika običajno zadošča 1–2 GB swapa. Pred tem se z ukazom df -h / prepričaj, da je na disku dovolj prostega prostora.

Swappiness

Vrednost vm.swappiness (0–100) določa, kako rado jedro uporablja swap. Privzeta vrednost je odvisna od distribucije in nastavljenega profila: na računalniku, nameščenem s cloud image AlmaLinux 9, je bila v preizkusu 30 (sysctl vm.swappiness). Na strežniku jo je dobro nastaviti nizko, da se swapa dotakne le ob resnični potrebi:

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

Če je swap ves čas v uporabi

Če je po free -h swap trajno poln in je strežnik počasen (v izpisu top je vrednost wa visoka), ima strežnik premalo pomnilnika. Takrat zmanjšaj porabo pomnilnika zgornjih storitev ali preidi na večji paket (glej: Kako povečam vire svojega paketa VPS?).

Na deljenem gostovanju pomnilnik za vsak račun omejuje CloudLinux; tam doseganje omejitve pomnilnika običajno povzroči napako 500 ali 503, glej: Omejitve virov CloudLinux.

Nazaj: Linux – članki (76)