Elfogy a swap de mitől?

Fórumok

Van egy gép, amire zabbix agent van telepítve. Naponta pár alkalommal szól, hogy kevés a swap. Ha belépek a gépre (11.2 RELEASE) akkor tényleg:


# swapinfo -h
Device 512-blocks Used Avail Capacity
/dev/ada0p3 4194304 1.7G 274M 87%
/dev/ada1p3 4194304 1.7G 315M 85%
Total 8388608 3.4G 589M 86%

Kérdés, hogy mi használja?


48 processes: 2 running, 45 sleeping, 1 zombie
CPU: 35.6% user, 0.0% nice, 13.2% system, 1.8% interrupt, 49.4% idle
Mem: 2634M Active, 18M Inact, 13G Wired, 287M Free
ARC: 10G Total, 2892M MFU, 6819M MRU, 113M Anon, 50M Header, 578M Other
9017M Compressed, 9321M Uncompressed, 1.03:1 Ratio
Swap: 4096M Total, 3649M Used, 446M Free, 89% Inuse, 28M In, 94M Out

PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
63999 postgres 1 26 0 4267M 2394M select 1 5:40 14.70% postgres
65324 www 54 20 0 5709M 193M nanslp 1 0:32 0.27% jsvc
65335 postgres 1 22 0 4249M 128M select 0 0:11 9.63% postgres
65328 postgres 1 20 0 4253M 119M select 3 0:11 0.15% postgres
65373 postgres 1 20 0 4249M 64704K select 0 0:10 0.00% postgres
65330 postgres 1 20 0 4249M 55588K select 2 0:07 0.00% postgres
63989 postgres 1 20 0 4241M 53772K select 2 0:01 0.09% postgres
63988 postgres 1 20 0 4241M 38740K select 1 0:00 0.00% postgres
65326 postgres 1 20 0 4243M 37428K select 1 0:00 0.00% postgres
65329 postgres 1 20 0 4243M 37408K select 3 0:00 0.00% postgres
65327 postgres 1 20 0 4243M 37196K select 3 0:00 0.00% postgres
63991 postgres 1 20 0 4241M 35672K select 2 0:00 0.00% postgres
63986 postgres 1 20 0 4241M 35596K select 2 0:00 0.00% postgres
63990 postgres 1 20 0 4241M 35516K select 0 0:00 0.01% postgres
63993 postgres 1 20 0 4241M 35376K select 1 0:00 0.00% postgres

A többi processz nem foglal sok memóriát.

A következők a kérdések:

* A postgresql.conf-ban shared_mem -nek 4GB van megadva. Az én értelmezésem szerint ez shared, tehát a top ugyan minden processzhez kb 4GB-ot jelez ki, de ez valójában csak egyszer 4GB. Jól gondolom?
* A top első sora szerint 13GB Wired memória van. Ebben a gépben egyébként 16GB van, szóval hová lett a maradék 4GB? (Bizonyosan nem az integrált videókártyára ment el, ezt megnéztem.)
* Hogyan tudnám meg kitalálni hogy pontosan melyik process swap-ol? Vagy ez egy hülye kérdés és kérdezősködés helyett vegyek ramot. :-)

Köszönöm,

Laci

Hozzászólások

Ja igen és lényegi kérdést kihagytam. Ha a 4GB-ot tényleg megosztják egymás között, akkor a top alapján sehogy nem jön ki a lefoglalt 13GB. Ha viszont nem osztják meg, akkor meg bőven 40GB fölötti érték jön ki, ami lehetetlen.

Szóval akkor hogy van ez?

Az általad adott listábol kimásoltam az adatokat.

Mem: 2634M Active, 18M Inact, 13G Wired, 287M Free

Ha összeadod, akkor ez bizony 16GB, abban nincsen hiba.

Ezen felül a telepításnél BSD-sek azt szokták javasolni, hogy a swap mérete a fizikai memória két és félszerese legyen. (2,5 * 16GB = 40GB). Ez valószínüleg nem fog ilyen hamar elfogyni, még ilyen memóriazabáló alkalmazások esetén sem.

Nem lehet, hogy a postgres-ben akadt be valami folyamat (vagy lekérdezés), ami ezt a problémát okozhatja?

============================================
"Share what you know. Learn what you don't."

Hajdan, HDD-vel megtapasztaltam egy fókuszban nem lévő szervernél, hogy mit jelent az, amikor a 2-szeres szorzóval létrehozott swap teljesen ki van használva: a virtuális terminálon leütött minden karakter után percnyi várakozást a megjelenésre. Viszont a gép életben maradt az egyik júzer bugosan cronba tolt szkriptje által produkált bő 400-as load mellett is.

2 fölötti szorzónál még kevésbé lett volna reszponzív, viszont ahol a gépnek bármi áron, de életben kell maradnia extrém körülmények között is, annak is lehet értelme. SSD-vel még inkább, a messze kisebb késleltetések miatt.

Hogy az ember a saját munkagépére nem csinál ma nem hogy kétszeres, de egyszeres swapot sem, annak az az oka, hogy terheltebb guinál már minimális lapcserélgetés is utálatossá teszi a munkát.
Azért ha valaki úgy gondolja, hogy az utolsó, még nem mentett bájtok fontosabbak annál, mint hogy egy megőrült processz miatt bármi OOM-mel elszálljon, mégis csak odateszi azt a párgigányi swapot, és fegyelmezi magát, hogy ne árassza el a virtuális deszktopjait csak azért, mert vannak és lehet.

Nem akadt be semmi, amit a postgresql.conf -ban megadsz shared_buffers -nek azt induláskor lefoglalja. A processzek megosztják egymás között, ezért elvileg az indokolt lenne, hogy a top-ban minden egyes postmaster mellett 4GB res olvasható. De ha ez megosztott, akkor mi foglalja a többit? Ha pedig nem megosztott akkor főleg nem értem, mert akkor a 10+ postgres processz 40GB-ot foglal ami lehetetlen.

Egyébként valószínűleg az lesz hogy leveszem a shared_buffers-t 3GB-ra hogy nehogy bepánikoljon a kernel, és szólok a tulajnak hogy vegyen memóriát.

De akkor is szeretném tudni, hogy mi foglal még? (Vagy hogy mit értettem félre ebből, ami sokkal valószínűbb.)

Nem értek hozzá egyáltalán, csak matekoztam egy kicsit:

//65335 postgres 1 22 0 4249M 128M select 0 0:11 9.63% postgres
128 +
//65328 postgres 1 20 0 4253M 119M select 3 0:11 0.15% postgres
119 +
//65373 postgres 1 20 0 4249M 64704K select 0 0:10 0.00% postgres
//65330 postgres 1 20 0 4249M 55588K select 2 0:07 0.00% postgres
4249 +
//63989 postgres 1 20 0 4241M 53772K select 2 0:01 0.09% postgres
//63988 postgres 1 20 0 4241M 38740K select 1 0:00 0.00% postgres
4241 +
//65326 postgres 1 20 0 4243M 37428K select 1 0:00 0.00% postgres
//65329 postgres 1 20 0 4243M 37408K select 3 0:00 0.00% postgres
//65327 postgres 1 20 0 4243M 37196K select 3 0:00 0.00% postgres
4243 +
/* Ez az érték (4241) már volt egyszer, így nem adom hozzá:
63991 postgres 1 20 0 4241M 35672K select 2 0:00 0.00% postgres
63986 postgres 1 20 0 4241M 35596K select 2 0:00 0.00% postgres
63990 postgres 1 20 0 4241M 35516K select 0 0:00 0.01% postgres
63993 postgres 1 20 0 4241M 35376K select 1 0:00 0.00% postgres
*/
=
12.980

Nem több szálon fut és csak a szállak osztoznak a memórián? Vagy többször fut? (A swap ebből nem derül ki persze...)

Ahh értem tehát azokat vetted egy csoportba, amik pontosan egyforma méretet foglalnak. Ügyes, de kimaradt az első postgres processz (4267M), plusz kimaradt a tomcat ami magában megevett több mint 5000M-t. Azokkal együtt kb. 25GB annyi meg nincs.

Az is lehet, hogy ez a megosztott memória csak "félig" megosztott: minden processz memória használatának csak egy része shared, a többi nem. Ha ez így van, akkor nincs elég infó ahhoz, hogy kiszámoljuk.

A shared_buffers-t levettem 3GB-ra és ez történt:

44 processes: 2 running, 42 sleeping
CPU: 3.9% user, 0.0% nice, 0.3% system, 0.2% interrupt, 95.6% idle
Mem: 716M Active, 117M Inact, 148K Laundry, 13G Wired, 2155M Free
ARC: 10G Total, 2685M MFU, 7134M MRU, 385K Anon, 50M Header, 580M Other
9036M Compressed, 9413M Uncompressed, 1.04:1 Ratio
Swap: 4096M Total, 10M Used, 4085M Free

PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
75881 www 54 20 0 5710M 548M nanslp 0 0:21 1.75% jsvc
75890 postgres 1 21 0 3201M 171M select 0 0:15 0.77% postgres
76066 postgres 1 20 0 3201M 162M select 1 0:06 0.73% postgres
75894 postgres 1 22 0 3199M 169M CPU2 2 0:06 11.70% postgres
75899 postgres 1 20 0 3199M 159M select 3 0:03 0.00% postgres
75891 postgres 1 20 0 3193M 100M select 1 0:00 0.00% postgres
76593 postgres 1 20 0 3193M 102M select 2 0:00 0.18% postgres
76471 postgres 1 20 0 3193M 102M select 2 0:00 0.00% postgres
75893 postgres 1 20 0 3193M 99M select 2 0:00 0.00% postgres
75892 postgres 1 20 0 3193M 99M select 2 0:00 0.00% postgres
75859 postgres 1 20 0 3191M 99M select 0 0:00 0.00% postgres
75862 postgres 1 20 0 3191M 98984K select 1 0:00 0.01% postgres
75864 postgres 1 20 0 3191M 98824K select 3 0:00 0.00% postgres
75857 postgres 1 20 0 3191M 98716K select 2 0:00 0.02% postgres
75860 postgres 1 20 0 3191M 98636K select 1 0:00 0.00% postgres
75861 postgres 1 20 0 3191M 98632K select 2 0:00 0.00% postgres

Szóval ez nagyon úgy néz ki hogy a 3191M az pontosan a 3GB shared_buffers-nek felel meg. A swap most egyáltalán nincs használva. Viszont most is azt írja ki hogy 13GB wired, amit még mindig nem értek. A "wired" memory leírása szerint ez "Memory in use by the Kernel. This memory cannot be swapped out."

Na jó végülis probléma megoldva, csak nem lettem okosabb. :-)

Átrendeztem:

Figyeld a PID-eket:

//PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
//75881 www 54 20 0 5710M 548M nanslp 0 0:21 1.75% jsvc
5710 +

//75890 postgres 1 21 0 3201M 171M select 0 0:15 0.77% postgres
//75894 postgres 1 22 0 3199M 169M CPU2 2 0:06 11.70% postgres
//75899 postgres 1 20 0 3199M 159M select 3 0:03 0.00% postgres
//75891 postgres 1 20 0 3193M 100M select 1 0:00 0.00% postgres
//75893 postgres 1 20 0 3193M 99M select 2 0:00 0.00% postgres
//75892 postgres 1 20 0 3193M 99M select 2 0:00 0.00% postgres
//75859 postgres 1 20 0 3191M 99M select 0 0:00 0.00% postgres
//75862 postgres 1 20 0 3191M 98984K select 1 0:00 0.01% postgres
//75864 postgres 1 20 0 3191M 98824K select 3 0:00 0.00% postgres
//75857 postgres 1 20 0 3191M 98716K select 2 0:00 0.02% postgres
//75860 postgres 1 20 0 3191M 98636K select 1 0:00 0.00% postgres
//75861 postgres 1 20 0 3191M 98632K select 2 0:00 0.00% postgres
(max) 3201 +

//76593 postgres 1 20 0 3193M 102M select 2 0:00 0.18% postgres
//76471 postgres 1 20 0 3193M 102M select 2 0:00 0.00% postgres
//76066 postgres 1 20 0 3201M 162M select 1 0:06 0.73% postgres
(max) 3201
=12.112 (+ a többi processz van ~1 GB?)

Ezek osztoznának a memórián?

Előző:

//PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
//65324 www 54 20 0 5709M 193M nanslp 1 0:32 0.27% jsvc
5709 +

//65335 postgres 1 22 0 4249M 128M select 0 0:11 9.63% postgres
//65328 postgres 1 20 0 4253M 119M select 3 0:11 0.15% postgres
//65373 postgres 1 20 0 4249M 64704K select 0 0:10 0.00% postgres
//65330 postgres 1 20 0 4249M 55588K select 2 0:07 0.00% postgres
//65326 postgres 1 20 0 4243M 37428K select 1 0:00 0.00% postgres
//65329 postgres 1 20 0 4243M 37408K select 3 0:00 0.00% postgres
//65327 postgres 1 20 0 4243M 37196K select 3 0:00 0.00% postgres
(max) 4253 +

//63999 postgres 1 26 0 4267M 2394M select 1 5:40 14.70% postgres
//63989 postgres 1 20 0 4241M 53772K select 2 0:01 0.09% postgres
//63988 postgres 1 20 0 4241M 38740K select 1 0:00 0.00% postgres
//63991 postgres 1 20 0 4241M 35672K select 2 0:00 0.00% postgres
//63986 postgres 1 20 0 4241M 35596K select 2 0:00 0.00% postgres
//63990 postgres 1 20 0 4241M 35516K select 0 0:00 0.01% postgres
//63993 postgres 1 20 0 4241M 35376K select 1 0:00 0.00% postgres
(max) 4267
=14.229 (-3649[swap]=10.058 ???)

Sántít egy kicsit és az is meglehet, hogy nem a max-ot kell nézni, de az órajel is árulkodó!? A postgres érdekesen foglalja le a memóriát!

Szerk.:
Ezeket találtam:
https://www.slideshare.net/AlexeyBashtanov/postgresql-and-ram-usage
http://www.interdb.jp/pg/pgsql02.html
https://stackoverflow.com/questions/32930787/understanding-postgresql-s…
(Töröm az angolt + nem értek a PostgreSQL-hez, így lehet, hogy hülyeséget linkeltem, ebben az esetben elnézést kérek!)

A postgresql shared memory, az a 4G igen osztott, nem processzenkent foglal le annyit. De ezen felul foglalhatnak a processek is, meg fognak is foglalni, mint workmem, maintenance_workmem, temp tablak, tabla cache, wal buffer stb. Ezek egy resze fix, masik resze fugg az adott query-ktol es kapcsolatok szamatol. Szoval nem olyan trivilais ennyibol kiszamolni (de minimum egy postgresql verzioszam es konfig kellene, illetve par statisztikai adat mint hany kliens csatlakozik hozza, mennyi/mekkora tablak vannak stb.), foleg ha mas (tomcat meg ki tudja mi meg) is fut a rendszerben.

De ami nalad jo esellyel eszi a memoriat ennyire az a zfs lesz:
"ARC: 10G Total, 2892M MFU, 6819M MRU, 113M Anon, 50M Header, 578M Other"

Nem probaltam freebsd-n postgres-t, szoval csak iranymutatasnak:
https://wiki.archlinux.org/index.php/ZFS#Database

Illetve altalanos zfs memoria korlatozasra:
https://wiki.archlinux.org/index.php/ZFS#ZFS_is_using_too_much_RAM

Egyébként én is hallottam hogy a ZFS és az adatbázis összehozásához speciális beállítások kellenek. Rá is kerestem annak idején mikor ezt a gépet telepítettem, és ezt találtam: https://people.freebsd.org/~seanc/postgresql/scale15x-2017-postgresql_z… de a felét se sikerült megérteni. :-)

Az smem ilyenkor kezesebb, mint az általános processzvallatók.

Még régebben találtam.

#!/bin/bash
# Get current swap usage for all running processes
# Erik Ljungstrom 27/05/2011
SUM=0
OVERALL=0
for DIR in `find /proc/ -maxdepth 1 -type d | egrep "^/proc/[0-9]"` ; do
PID=`echo $DIR | cut -d / -f 3`
PROGNAME=`ps -p $PID -o comm --no-headers`
for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'`
do
let SUM=$SUM+$SWAP
done
echo "PID=$PID - Swap used: $SUM - ($PROGNAME )"
let OVERALL=$OVERALL+$SUM
SUM=0
done
echo "Overall swap used: $OVERALL"

Nem, ez katasztrofális... az a ciklus, ahol a grep kimenetéből a második elemet awk-val kiíratja, és ezeket külön összeadja, az azért több, mint fájdalmas:

for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'`
do
let SUM=$SUM+$SWAP
done

Ahelyett, hogy simán csak ennyit írt volna:

SUM=$(awk '/Swap/ {s+=$2} END {print s}' $DIR/smaps 2>/dev/null)

Persze van még benne csúnyaság, de ez nagyon fájt...

ZFS+appserver+nem kicsi postgres egyben 16GB + 3.4GB -ra elég bátor.
A jó megoldás a RAM vétel lesz, a többi mind tüneti kezelés. Lehet a ZFS-t tuningolni, még swapot hozzáadni de ettől még jó nem lesz.
--
Gábriel Ákos

Újabb fejlemény van az ügyben. Hétvégén crash-elt a gép. Hétfőn újraindítottam. Néztem a memóriát és el voltam képedve: hirtelen lett 12GB memória, és az összes swap szabad. Eljött a következő nap, és azt látom hogy ott vagyunk ahol voltunk: elfogyott a memória, swap az egekben.

Itt van két grafikon:

https://imgur.com/a/VKzhKva
https://imgur.com/a/sKcgX8h

Megnéztem a cron-t. Nincs olyan saját cuccom, aminek 7-kor kellett volna elindulnia.

Itt a top eleje:

55 processes: 2 running, 52 sleeping, 1 zombie
CPU: 4.3% user, 0.0% nice, 1.0% system, 0.3% interrupt, 94.4% idle
Mem: 294M Active, 456M Inact, 863M Laundry, 14G Wired, 261M Free
ARC: 9756M Total, 551M MFU, 8392M MRU, 352K Anon, 238M Header, 575M Other
8183M Compressed, 21G Uncompressed, 2.61:1 Ratio
Swap: 4096M Total, 2987M Used, 1109M Free, 72% Inuse

Megint az ARC vett el 10GB-ot. Most annyi ötletem van, hogy talán egy periodic script futtatott valamit (setuid ellenőrzés???) és az zabálta föl a memóriát.

De ez teljesen olyan mintha memory leak lenne.

Szerintetek?

Ennek a sysctl-nek a default értéke a teljes elérhető memória nagysága volt. Nem tudom hogy FreeBSD 11.1 -en mi volt a default, mert ott soha nem volt ilyen probléma. Most átírtam 4G-ra:


sysctl vfs.zfs.arc_max=4294967296

Ennek a következő lett a hatása:


last pid: 37044; load averages: 0.29, 0.27, 0.29 up 1+04:50:07 11:57:02
59 processes: 2 running, 56 sleeping, 1 zombie
CPU: 2.4% user, 0.0% nice, 0.3% system, 0.4% interrupt, 96.9% idle
Mem: 620M Active, 126M Inact, 869M Laundry, 6653M Wired, 7556M Free
ARC: 3676M Total, 260M MFU, 2770M MRU, 142K Anon, 74M Header, 571M Other
2270M Compressed, 10G Uncompressed, 4.42:1 Ratio
Swap: 4096M Total, 3353M Used, 743M Free, 81% Inuse

Az ARC mérete szépen visszaesett, a wired memory mérete először még 14GB körül volt, de az is elkezdett szépen csökkenni. Egyedül a swap usage nem akar csökkeni. Még egyszer újraindítom, és meglátjuk hogy egy nap múlva mit fog mutatni.

Ami az érdekes, hogy UPDATING -ben nem láttam külön kiírva, hogy megváltozott volna a default érték, és hogy upgrade-kor ezt át kellene írni kézzel. Most épp nincs kéznél 11.1-em (mindet lecseréltem), de ha valakinek van és olvassa ezt, akkor örülnék ha megírná hogy ott mi volt a default értéke. Mert a hiba egyértelműen OS verzió váltás után jelent meg, és kíváncsi vagyok hogy én vagyok a hülye, vagy egy olyan változtatásról van szó, amit nem reklámoztak kellőképpen.

Újraindítás után:


last pid: 1755; load averages: 0.37, 0.32, 0.18 up 0+00:09:09 12:12:50
45 processes: 2 running, 43 sleeping
CPU: 4.2% user, 0.0% nice, 0.1% system, 0.2% interrupt, 95.5% idle
Mem: 701M Active, 144M Inact, 742M Wired, 14G Free
ARC: 381M Total, 137M MFU, 234M MRU, 352K Anon, 1833K Header, 8479K Other
214M Compressed, 353M Uncompressed, 1.65:1 Ratio
Swap: 4096M Total, 4096M Free

Egy nap múlva jelentkezem és kiderül hogy mit változott.

3 napos:

Swap használat nulla. Beállt, most jól viselkedik.

Érdekesség: egy másik gépben 24GB memória van, ugyan ez a BSD verzió, és ott sem volt korlátozva az ARC mérete. Az a gép teljesen máshogy viselkedik: általában 4GB alatt van az ARC használata. A felhasználás módja ugyan az (postgresql + tomcat fut rajta). Ezt nem annyira értem, de sebaj.