OOM killer nagy pagecache mellett

Helo,

kivancsi vagyok, ki mit gondol.
Adott egy bare metal szerver 16G RAM-mal, rajta egy Postgres instance. Altalaban a memoria kozel teljesen foglalt, de a free es a vmstat alapjan kb. 14.5 GB page cache, kb. 1 G pedig hasznalatban van. vm.overcommit_memory = 0 (heuristic).

Namost, az OOM killer egyszercsak lelott par Postgres processzt, mert szerinte nem volt elegendo szabad memoria.

Kerdes: miert nem takaritja ki a mmap-elt fajlokat a kernel ahelyett, hogy leolne az egyik processzt?

Egyebkent:

- az OOM killer akkor utott be, amikor egy uj (egyebkent kis memoriaigenyu) processz elindult a gepen (ClamAV)
- a memoriafragmentacio jelentos (256K folotti chunk-okbol kb. egyaltalan nem volt szabadon).

Hozzászólások

Hasonló nyűgöm volt nekem is, aztán sysctl -w vm.min_free_kbytes=1048576-től megnyugodtak a kedélyek.

Több mint 10 éve üzemeltetünk Postgres alapú rendszert rendes terheléssel, sose volt ilyen problémánk.
Nálunk 400 connection-t enged a pg, azon a kliens semmilyen módon nem tud túlfutni, a mondatod azon részét nem is igazán értem.
A PG-nek van egy olyan attributuma (most nem jut eszembe pontosan) ami a connectionök egyedi memóriája (talán work_mem).
work_mem * max_connection fizikai memorial kell legyen a rendszerben (ezt swapelni nyilván nincs értelme).

Memória fragmentáció szerintem akkor tud előfordulni ha valaki nagyon gyorsan nyit-zár-nyit-zár kapcsolatokat.
Rosszul implementált/nem használt pool handlingre gondolok, nem postgres hibára.
PG illetve kernel oldalon max. tüneti kezelést tudok elképzelni, illetve lehet hogy memória bővítés megoldaná a dolgot.
--
Gábriel Ákos
http://ixenit.com

> Nálunk 400 connection-t enged a pg, azon a kliens semmilyen módon ..

A kliensoldali conn poolra gondoltam, de ez igazabol nem relevans itt.

Megtalaltam egyebket -- van egy Postgres monitorozo mini-app a szerveren, ami a monitoring rendszernek expozal mindenfele statisztikakat. Na abban van ez:


func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
defer func(begun time.Time) {
e.duration.Set(time.Since(begun).Seconds())
}(time.Now())

e.error.Set(0)
e.totalScrapes.Inc()

db, err := sql.Open("postgres", e.dsn)
if err != nil {
log.Infoln("Error opening connection to database:", err)
e.error.Set(1)
return
}
defer db.Close()

Idiota megoldas, majd megfixaljuk (3rd party cucc), koszi a tippet.

----------------------
while (!sleep) sheep++;

-

// Happy debugging, suckers
#define true (rand() > 10)

MySQL-lel futottam bele. Bőven volt szabad RAM, az OOM killer meg folyamatosan kilőtte.

Netes kutakodás alapján ezt raktam össze.


#!/bin/bash

#pgrep -f "/usr/libexec/mysqld" | while read PID; do

ps aux | grep "mysqld.sock" | grep -v "grep" | awk '{print $2}' | while read PID; do

#    echo $PID
    echo -1000 > /proc/$PID/oom_score_adj;

done

3 hónapja megy, azóta nincs probléma.

A konkrét szerver nekem is több, mint 3 hónapja ment (inkább 2 évet), de egyszer csak gondolt egyet és olyan terhelést kapott, amire igy reagált. Ez akkortól naponta többször jelentkezett. Azóta egyszer sem. Elég határozott megoldást adott. Okosabbat nem tudtam kiguglizni, természetesen engem is érdekelne a miértje.