
Ko se v Linux Strežnik baze podatkov se nepričakovano prekine in ugotoviti je treba vzrok. Razlogov je lahko več. Na primer, SIGSEGV — napaka zaradi hrošča v zalednem strežniku. Ampak to je redko. Najpogosteje preprosto zmanjka prostora na disku ali pomnilnika. Če vam zmanjka prostora na disku, obstaja samo en izhod - sprostite prostor in znova zaženite bazo podatkov.
Ubijalec brez spomina
Ko ti strežnika ali pa procesu zmanjka pomnilnika, Linux Ubijalec zaradi pomanjkanja pomnilnika (Out-Of-Memory Killer) ponuja dve rešitvi: sesutje celotnega sistema ali prekinitev procesa (aplikacije), ki porablja pomnilnik. Seveda je bolje prekiniti proces in rešiti operacijski sistem pred sesutjem. Skratka, ubijalec zaradi pomanjkanja pomnilnika je proces, ki prekine aplikacijo, da reši jedro pred sesutjem. Žrtvuje aplikacijo, da ohrani delovanje operacijskega sistema. Najprej si oglejmo, kako deluje ubijanje zaradi pomanjkanja pomnilnika (OOM) in kako ga nadzorovati, nato pa si poglejmo, kako se ubijalec zaradi pomanjkanja pomnilnika (OOM Killer) odloči, katere aplikacije bo prekinil.
Ena glavnih nalog Linux — Dodeli pomnilnik procesom, ko ga zahtevajo. Običajno proces ali aplikacija zahteva pomnilnik od operacijskega sistema, vendar ga ne uporabi v celoti. Če operacijski sistem dodeli pomnilnik vsem, ki ga zahtevajo, vendar ga ne nameravajo uporabiti, bo sistemu hitro zmanjkalo pomnilnika in sistem se bo sesul. Da bi to preprečil, operacijski sistem rezervira pomnilnik za proces, vendar ga dejansko ne dodeli. Pomnilnik se dodeli le, ko ga proces dejansko namerava uporabiti. Včasih operacijski sistem nima prostega pomnilnika, vendar ga dodeli procesu, in ko ga proces potrebuje, ga operacijski sistem dodeli, če lahko. Slaba stran je, da operacijski sistem včasih rezervira pomnilnik, vendar ga po potrebi ni na voljo, kar povzroči sesutje sistema. OOM igra v tem scenariju ključno vlogo, saj prekine procese, da prepreči paniko jedra. Ko je proces PostgreSQL prisilno prekinjen, se v dnevniku prikaže naslednje sporočilo:
Out of Memory: Killed process 12345 (postgres).Če sistemu primanjkuje pomnilnika in ga ni mogoče sprostiti, se funkcija pokliče out_of_memory. Na tej stopnji ji preostane le še ena stvar - dokončati enega ali več procesov. Ali naj OOM-killer takoj prekine postopek ali lahko počaka? Očitno je, da se pri klicu out_of_memory pojavi čakanje na V/I operacijo ali ostranjevanje na disk. Zato mora OOM killer najprej opraviti preverjanja in se na podlagi njih odločiti, da je treba proces prekiniti. Če so vsa spodnja preverjanja pozitivna, bo OOM prekinil postopek.
Izbira procesa
Ko zmanjka pomnilnika, se funkcija pokliče out_of_memory(). Ima funkcijo select_bad_process(), ki prejme oceno funkcije badness(). Usmerjen bo "najslabši" proces. funkcija badness() izbere postopek po določenih pravilih.
- Jedro potrebuje nekaj minimalnega pomnilnika zase.
- Sprostiti morate veliko pomnilnika.
- Procesov, ki uporabljajo malo pomnilnika, ni treba prekiniti.
- Dokončati je treba minimalne procese.
- Kompleksni algoritmi, ki povečajo možnosti dokončanja za tiste procese, ki jih uporabnik sam želi dokončati.
Ko opravi vsa ta preverjanja, OOM pregleda rezultat (oom_score). OOM dodeli oom_score vsak proces in nato to vrednost pomnoži s količino pomnilnika. Procesi z večjimi vrednostmi bodo bolj verjetno žrtev OOM Killerja. Procesi, povezani s korenskim uporabnikom, imajo nižjo oceno in je manj verjetno, da bodo prisiljeni prekiniti.
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3813
(1 row)ID procesa Postgres je 3813, tako da je v drugi lupini mogoče dobiti rezultat s tem parametrom jedra oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2Če ne želite, da OOM-Killer sploh uniči proces, obstaja še ena možnost jedra: oom_score_adj. Dodajte veliko negativno vrednost, da zmanjšate možnosti za dokončanje procesa, ki ga cenite.
sudo echo -100 > /proc/3813/oom_score_adjZa nastavitev vrednosti oom_score_adj, nastavite OOMScoreAdjust v servisnem bloku:
[Service]
OOMScoreAdjust=-1000Ali uporabite oomprotect v ekipi rcctl.
rcctl set <i>servicename</i> oomprotect -1000Prisilna prekinitev procesa
Ko je eden ali več procesov že izbranih, OOM-Killer pokliče funkcijo oom_kill_task(). Ta funkcija pošlje procesu zaključni signal. V primeru pomanjkanja spomina oom_kill() Pokliče to funkcijo, da procesu pošlje signal SIGKILL. V dnevnik jedra se zapiše sporočilo.
Out of Memory: Killed process [pid] [name].Kako nadzirati OOM-Killer
В Linux OOM-Killer lahko omogočite ali onemogočite (čeprav slednje ni priporočljivo). Če ga želite omogočiti ali onemogočiti, uporabite parameter vm.oom-kill. Če želite omogočiti OOM-Killer med izvajanjem, zaženite ukaz sysctl.
sudo -s sysctl -w vm.oom-kill = 1Če želite onemogočiti OOM-Killer, podajte vrednost 0 v istem ukazu:
sudo -s sysctl -w vm.oom-kill = 0Rezultat tega ukaza ne bo shranjen za vedno, ampak le do prvega ponovnega zagona. Če potrebujete več vztrajnosti, dodajte to vrstico v datoteko /etc/sysctl.conf:
echo vm.oom-kill = 1 >>/etc/sysctl.confDrug način omogočanja in onemogočanja je pisanje spremenljivke panic_on_oom. Vrednost je vedno mogoče preveriti /proc.
$ cat /proc/sys/vm/panic_on_oom
0Če nastavite vrednost na 0, potem ko zmanjka pomnilnika, ne bo panike jedra.
$ echo 0 > /proc/sys/vm/panic_on_oomČe nastavite vrednost na 1, se bo, ko zmanjka pomnilnika, pojavila panika jedra.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer je mogoče vklopiti in izklopiti, kot smo že omenili. Linux lahko rezervira več pomnilnika za procese, kot je na voljo, vendar ga dejansko ne dodeli, in to vedenje nadzoruje parameter jedra LinuxZa to je odgovorna spremenljivka. vm.overcommit_memory.
Zanj lahko določite naslednje vrednosti:
0: Jedro samo odloči, ali bo rezerviralo preveč pomnilnika. To je privzeta vrednost v večini različic. Linux.
1: Jedro bo vedno rezerviralo dodatni pomnilnik. To je tvegano, saj lahko zmanjka pomnilnika, saj ga bodo najverjetneje nekoč procesi zahtevali.
2: jedro ne bo rezerviralo več pomnilnika, kot je navedeno v parametru overcommit_ratio.
S tem parametrom določite odstotek pomnilnika, ki je dovoljen za preveč rezerviran. Če zanj ni prostora, se pomnilnik ne dodeli in rezervacija bo zavrnjena. To je najvarnejša možnost, priporočena za PostgreSQL. Na OOM-Killer vpliva še en element - zmožnost zamenjave, ki jo nadzira spremenljivka cat /proc/sys/vm/swappiness. Te vrednosti povedo jedru, kako ravnati s strani. Višja kot je vrednost, manjša je verjetnost, da bo OOM prekinil proces, vendar zaradi V/I operacij negativno vpliva na bazo podatkov. In obratno – nižja kot je vrednost, večja je verjetnost posega OOM-Killer, vendar je tudi zmogljivost baze podatkov večja. Privzeta vrednost je 60, a če se celotna zbirka podatkov prilega pomnilniku, je bolje, da vrednost nastavite na 1.
Rezultati
Naj vas "morilec" v OOM-Killerju ne prestraši. V tem primeru bo morilec rešitelj vašega sistema. "Ubije" najhujše procese in reši sistem pred sesutjem. Da bi se izognili uporabi OOM-Killer za prekinitev PostgreSQL, nastavite na vm.overcommit_memory vrednost 2. To ne zagotavlja, da OOM-Killerju ne bo treba posredovati, vendar bo zmanjšalo verjetnost prisilne prekinitve procesa PostgreSQL.
Vir: www.habr.com
