Configuring Out-Of-Memory Killer in Linux for PostgreSQL

Configuring Out-Of-Memory Killer in Linux for PostgreSQL

Ko Linux strežnik baze podatkov nepričakovano preneha delovati, je treba ugotoviti vzrok. Vzrokov je lahko več. Na primer, SIGSEGV — napaka v backend strežniku. A to je redko. Pogosteje se preprosto zmanjša prostor na disku ali pomnilnik. Če zmanjka prostora na disku, je edina rešitev osvoboditi prostor in znova zagnati bazo podatkov.

Out-Of-Memory Killer

Ko strežnika ali proces zmanjka pomnilnika, Linux ponudi 2 rešitvi: zrušiti celoten sistem ali končati proces (aplikacijo), ki porabi pomnilnik. Seveda je bolje končati proces in rešiti OS pred nepričakovanim izklopom. Na kratko, Out-Of-Memory Killer je proces, ki konča aplikacijo, da bi zaščitil jedro pred zrušitvijo. Žrtvuje aplikacijo, da ohrani delovanje OS. Najprej se pogovorimo o tem, kako OOM deluje in kako ga nadzorovati, nato pa si poglejmo, kako OOM Killer odloča, katero aplikacijo končati.

Ena glavnih nalog Linuxa je dodeljevanje pomnilnika procesom, ko ga ti zahtevajo. Običajno proces ali aplikacija od OS zahteva pomnilnik, sam pa ga ne uporablja v celoti. Če bo OS dodeljeval pomnilnik vsem, ki ga zahtevajo, a ga ne nameravajo uporabiti, bo zelo hitro zmanjkalo pomnilnika in sistem bo odpovedal. Da bi to preprečili, OS rezervira pomnilnik za proces, dejansko pa ga ne dodeli. Pomnilnik se dodeli le, ko ga proces dejansko namerava uporabiti. Zgodi se, da OS nima prostega pomnilnika, vendar zaklene pomnilnik za proces, in ko ga proces potrebuje, ga OS dodeli, če lahko. Slaba stran tega je, da včasih OS rezervira pomnilnik, vendar v kritičnem trenutku prostega pomnilnika ni, kar povzroči zrušitev sistema. OOM igra pomembno vlogo v tej situaciji in zaključi procese, da zaščiti jedro pred paničnim izklopom. Ko se proces PostgreSQL prisilno zaključi, se v dnevniku prikaže sporočilo:

Out of Memory: Killed process 12345 (postgres).

Če je v sistemu premalo pomnilnika in ga ni mogoče osvoboditi, se pokliče funkcija out_of_memory. V tej fazi ostane le še eno - dokončati enega ali več procesov. OOM-killer mora takoj končati proces ali lahko počakam? Očitno, da ko se pokliče out_of_memory, je to povezano z čakanjem na vhodno-izhodno operacijo ali swap stran v disk. Zato mora OOM-killer najprej opraviti preglede in na njihovi podlagi odločiti, kateri proces naj konča. Če so vsi spodaj navedeni pregledi pozitivni, bo OOM končal proces.

Izbira procesa

Ko zmanjka pomnilnika, se pokliče funkcija out_of_memory(). V njej je funkcija select_bad_process(), ki dobi oceno od funkcije badness(). Na udaru bo badness() najslabši

  1. Proces je izbran po določenih pravilih.
  2. Jedru je potrebna neka osnova pomnilnika zase.
  3. Treba je osvoboditi veliko pomnilnika.
  4. Ni treba končati procesov, ki porabijo malo pomnilnika.
  5. Treba je končati najmanj procesov.

Zapleteni algoritmi, ki povečajo možnosti za zaključitev tistih procesov, ki jih uporabnik sam želi končati.Ko opravi vse te preglede, OOM preuči oceno (oom_score Ko opravi vse te preglede, OOM preuči oceno ( ). OOM dodeli

vsakemu procesu in nato pomnoži to vrednost z obsegom pomnilnika. Procesi z višjimi vrednostmi imajo večjo verjetnost, da postanejo žrtve OOM Killerja. Procesi, povezani s privilegiranimi uporabniki, imajo nižjo oceno in manjšo verjetnost prisilnega končanja.

postgres=# SELECT pg_backend_pid(); pg_backend_pid  ----------------     3813 (1 vrstica) Ko opravi vse te preglede, OOM preuči oceno (:

Identifikator procesa Postgres je 3813, zato v drugi lupini lahko pridobite oceno, ki uporablja ta parameter jedra

vagrant@vagrant:~$ sudo cat /proc/3813/oom_score 2 Če res nočete, da OOM-Killer konča proces, je še en parameter jedra:oom_score_adj

. Dodajte veliko negativno vrednost, da zmanjšate možnosti za zaključitev dragocenega procesa.

sudo echo -100 > /proc/3813/oom_score_adj Če res nočete, da OOM-Killer konča proces, je še en parameter jedra:Da določite vrednost

, nastavite OOMScoreAdjust v bloku storitve:

[Service] OOMScoreAdjust=-1000 Ali uporabite u komandi rcctl.

rcctl set servicename oomprotect -1000

Prisilno končanje procesa

Ko je eden ali več procesov že izbranih, OOM-Killer pokliče funkcijo oom_kill_task().Ta funkcija pošlje procesu signal za zaključitev. V primeru pomanjkanja pomnilnika oom_kill() pokliče to funkcijo, da pošlje procesu signal SIGKILL. V jedro se zapiše sporočilo.

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

Kako nadzorovati OOM-Killer

V Linuxu lahko vključite ali izključite OOM-Killer (čeprav to ni priporočljivo). Za vključitev in izključitev uporabite parameter vm.oom-kill. Da aktivirate OOM-Killer v času izvajanja, uporabite ukaz sysctl.

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

Da izključite OOM-Killer, navedite vrednost 0 v istem ukazu:

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

Rezultat tega ukaza se ne bo ohranil trajno, temveč le do prve ponovne zažinitve. Če potrebujete več trajnosti, dodajte to vrstico v datoteko /etc/sysctl.conf:

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

Še en način za vključitev in izključitev je, da napišete spremenljivko panic_on_oom. Vrednost lahko vedno preverite v /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Če nastavite vrednost 0, se ob izteku pomnilnika ne bo zgodil kernel panic.

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

Če nastavite vrednost 1, bo ob izteku pomnilnika prišlo do kernel panic.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer lahko ne le vključite in izključite. Že smo omenili, da Linux lahko rezervira več pomnilnika za procese, kot je na voljo, a ga ne dodeli dejansko, in s tem vedenjem upravlja parameter jedra Linuxa. Za to skrbi spremenljivka vm.overcommit_memory.

Za njo lahko navedete naslednje vrednosti:

0: jedro samo odloča, ali je vredno rezervirati preveč pomnilnika. To je privzeta vrednost v večini različic Linuxa.
1: jedro vedno rezervira dodatni pomnilnik. To je tvegano, saj lahko pomnilnik zmanjka, ker verjetno nekega dne procesi zahtevajo točno to.
2: jedro ne bo rezerviralo več pomnilnika, kot je navedeno v parameter overcommit_ratio.

V tej parametru navedete odstotek pomnilnika, za katerega je dovoljeno prekomerno rezerviranje. Če zanj ni prostora, se pomnilnik ne dodeli, rezervacijo bo zavrnjeno. To je najvarnejša možnost, priporočena za PostgreSQL. Na OOM-Killer vpliva še en element – možnost swapanja, ki jo upravlja spremenljivka cat /proc/sys/vm/swappiness. Te vrednosti jedru nakazujejo, kako obravnavati swapanje strani. Večja kot je vrednost, manjša je verjetnost, da OOM zaključi postopek, vendar zaradi operacij I/O to negativno vpliva na bazo podatkov. In obratno – manjša kot je vrednost, večja je verjetnost posredovanja OOM-Killerja, a zmogljivost baze podatkov je prav tako višja. Privzeta vrednost je 60, vendar je bolje nastaviti vrednost 1, če se cela baza podatkov prilega v pomnilnik.

Zaključki

Ne bojte se "morilca" v OOM-Killer. V tem primeru je morilec rešitelj vašega sistema. "Ubija" najbolj problematične procese in rešuje sistem pred nenadnim izklopom. Da ne boste morali uporabljati OOM-Killer za končanje PostgreSQL, nastavite vm.overcommit_memory vrednost 2. To ne zagotavlja, da OOM-Killer ne bo moral posredovati, ampak zmanjša verjetnost prisilnega zaključka procesa PostgreSQL.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster