„Of-Of-Memory Killer“ nustatymas sistemoje „Linux“, skirtas PostgreSQL

„Of-Of-Memory Killer“ nustatymas sistemoje „Linux“, skirtas PostgreSQL

Kai „Linux“ duomenų bazės serveris netikėtai išsijungia, turite rasti priežastį. Gali būti keletas priežasčių. Pavyzdžiui, SIGSEGV — gedimas dėl galinio serverio klaidos. Bet tai reta. Dažniausiai jums tiesiog pritrūksta vietos diske arba atminties. Jei trūksta vietos diske, yra tik viena išeitis – atlaisvinkite vietos ir paleiskite duomenų bazę iš naujo.

Išsenkančios atminties žudikas

Kai serverio ar proceso atmintis baigiasi, Linux siūlo 2 sprendimus: sugriauti visą sistemą arba nutraukti procesą (programą), einantį atmintį. Žinoma, geriau nutraukti procesą ir išsaugoti OS nuo gedimo. Trumpai tariant, „Of-Of-Memory Killer“ yra procesas, kuris užmuša programą, kad apsaugotų branduolį nuo strigimo. Ji aukoja programą, kad OS veiktų. Pirmiausia aptarkime, kaip OOM veikia ir kaip jį valdyti, o tada pažiūrėkime, kaip OOM Killer nusprendžia, kurią programą nutraukti.

Viena iš pagrindinių Linux užduočių yra skirti atmintį procesams, kai jie to prašo. Paprastai procesas arba programa reikalauja atminties iš OS, bet ne iki galo jos išnaudoja. Jei OS išduos atmintį visiems, kurie jos prašo, bet neketina jos naudoti, labai greitai atmintis baigsis ir sistema suges. Kad to išvengtų, OS rezervuoja atmintį procesui, bet iš tikrųjų jos neatleidžia. Atmintis paskirstoma tik tada, kai procesas iš tikrųjų ketina ją naudoti. Būna, kad OS neturi laisvos atminties, bet procesui priskiria atmintį, o kai procesui jos reikia, OS, jei gali, ją paskiria. Neigiama yra tai, kad kartais OS rezervuoja atmintį, tačiau reikiamu momentu laisvos atminties nebelieka ir sistema sugenda. OOM šiame scenarijuje atlieka svarbų vaidmenį ir nutraukia procesus, kad branduolys nepanikuotų. Kai PostgreSQL procesas yra priverstas nutraukti, žurnale pasirodo pranešimas:

Out of Memory: Killed process 12345 (postgres).

Jei sistemoje mažai atminties ir jos negalima atlaisvinti, iškviečiama funkcija out_of_memory. Šiame etape jai liko tik vienas dalykas – užbaigti vieną ar kelis procesus. Ar OOM-killer turėtų nedelsiant nutraukti procesą, ar gali palaukti? Akivaizdu, kad kai iškviečiama out_of_memory, tai yra dėl laukimo, kol bus atlikta įvesties / išvesties operacija arba ieškoma puslapių į diską. Todėl OOM žudikas pirmiausia turi atlikti patikrinimus ir jais remdamasis nuspręsti, kad procesą reikia nutraukti. Jei visi toliau pateikti patikrinimai yra teigiami, OOM nutrauks procesą.

Proceso pasirinkimas

Kai baigiasi atmintis, funkcija iškviečiama out_of_memory(). Ji turi funkciją select_bad_process(), kuris gauna įvertinimą iš funkcijos badness(). Bus nukreiptas „blogiausias“ procesas. Funkcija badness() parenka procesą pagal tam tikras taisykles.

  1. Branduoliui reikia tam tikros minimalios atminties.
  2. Reikia atlaisvinti daug atminties.
  3. Nereikia nutraukti procesų, kurie naudoja mažai atminties.
  4. Reikia atlikti minimalius procesus.
  5. Sudėtingi algoritmai, padidinantys tų procesų, kuriuos pats vartotojas nori užbaigti, užbaigimo tikimybę.

Atlikęs visus šiuos patikrinimus, OOM patikrina balą (oom_score). OOM priskiria oom_score kiekvieną procesą, o tada šią reikšmę padaugina iš atminties kiekio. Didesnių verčių procesai greičiausiai taps OOM Killer aukomis. Procesai, susiję su pagrindiniu vartotoju, turi mažesnį balą ir yra mažiau tikėtina, kad jie bus priversti nutraukti.

postgres=# SELECT pg_backend_pid();
pg_backend_pid 
----------------
    3813
(1 row)

Postgres proceso ID yra 3813, todėl kitame apvalkale galima gauti balą naudojant šį branduolio parametrą oom_score:

vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2

Jei nenorite, kad OOM-Killer visiškai nužudytų procesą, yra kita branduolio parinktis: oom_score_adj. Pridėkite didelę neigiamą vertę, kad sumažintumėte tikimybę užbaigti jums vertinamą procesą.

sudo echo -100 > /proc/3813/oom_score_adj

Norėdami nustatyti vertę oom_score_adj, paslaugų bloke nustatykite OOMScoreAdjust:

[Service]
OOMScoreAdjust=-1000

Arba naudoti oomprotect komandoje rcctl.

rcctl set <i>servicename</i> oomprotect -1000

Priverstinis proceso nutraukimas

Kai jau pasirinktas vienas ar keli procesai, OOM-Killer iškviečia funkciją oom_kill_task(). Ši funkcija siunčia proceso pabaigos signalą. Esant atminties trūkumui oom_kill() Iškviečia šią funkciją, kad į procesą būtų išsiųstas SIGKILL signalas. Į branduolio žurnalą įrašomas pranešimas.

Out of Memory: Killed process [pid] [name].

Kaip valdyti OOM-Killer

Linux sistemoje galite įjungti arba išjungti OOM-Killer (nors pastarasis nerekomenduojamas). Norėdami įjungti arba išjungti, naudokite parametrą vm.oom-kill. Norėdami įjungti OOM-Killer vykdymo metu, paleiskite komandą sysctl.

sudo -s sysctl -w vm.oom-kill = 1

Norėdami išjungti OOM-Killer, nurodykite reikšmę 0 toje pačioje komandoje:

sudo -s sysctl -w vm.oom-kill = 0

Šios komandos rezultatas nebus išsaugotas amžinai, o tik iki pirmojo perkrovimo. Jei jums reikia daugiau atkaklumo, pridėkite šią eilutę prie failo /etc/sysctl.conf:

echo vm.oom-kill = 1 >>/etc/sysctl.conf

Kitas būdas įjungti ir išjungti yra rašyti kintamąjį panic_on_oom. Vertė visada gali būti patikrinta /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Jei nustatysite reikšmę į 0, tada, kai baigsis atmintis, branduolio panikos nebus.

$ echo 0 > /proc/sys/vm/panic_on_oom

Jei nustatysite reikšmę į 1, tada, kai baigsis atmintis, kils branduolio panika.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer galima ne tik įjungti ir išjungti. Jau minėjome, kad „Linux“ gali rezervuoti daugiau atminties procesams, nei yra, iš tikrųjų jos nepaskirdama, ir šį elgesį valdo „Linux“ branduolio parametras. Už tai atsakingas kintamasis vm.overcommit_memory.

Galite nurodyti šias reikšmes:

0: Branduolys pats nusprendžia, ar rezervuoti per daug atminties. Tai yra numatytoji daugumos Linux versijų.
1: Branduolys visada rezervuos papildomą atmintį. Tai rizikinga, nes gali pritrūkti atminties, nes greičiausiai vieną dieną procesai to prireiks.
2: branduolys nerezervuoja daugiau atminties nei nurodyta parametre overcommit_ratio.

Naudodami šį parametrą nurodote, kiek procentų atminties leidžiama rezervuoti per daug. Jei jai nėra vietos, atmintis neskiriama, o rezervacija bus atmesta. Tai yra saugiausia parinktis, rekomenduojama „PostgreSQL“. OOM-Killer veikia kitas elementas – keitimo galimybė, kurią valdo kintamasis cat /proc/sys/vm/swappiness. Šios reikšmės nurodo branduoliui, kaip tvarkyti puslapius. Kuo didesnė vertė, tuo mažesnė tikimybė, kad OOM nutrauks procesą, tačiau dėl I/O operacijų tai daro neigiamą poveikį duomenų bazei. Ir atvirkščiai – kuo mažesnė vertė, tuo didesnė OOM-Killer įsikišimo tikimybė, tačiau duomenų bazės našumas taip pat didesnis. Numatytoji reikšmė yra 60, bet jei visa duomenų bazė telpa atmintyje, geriau nustatyti reikšmę į 1.

rezultatai

Neleiskite, kad OOM-Killer „žudikas“ jūsų gąsdintų. Tokiu atveju žudikas bus jūsų sistemos gelbėtojas. Tai „nužudo“ blogiausius procesus ir apsaugo sistemą nuo gedimo. Kad nereikėtų naudoti OOM-Killer norint nutraukti PostgreSQL, nustatykite į vm.overcommit_memory reikšmė 2. Tai negarantuoja, kad OOM-Killer nereikės įsikišti, bet sumažins tikimybę, kad PostgreSQL procesas bus priverstas nutraukti.

Šaltinis: www.habr.com

Добавить комментарий