Out-Of-Memory Killer ynstelle yn Linux foar PostgreSQL

Out-Of-Memory Killer ynstelle yn Linux foar PostgreSQL

As in databanktsjinner ûnferwachts yn Linux stopet, moatte jo de reden fine. D'r kinne ferskate redenen wêze. Bygelyks, SIGSEGV - mislearring fanwege in brek yn 'e backend-tsjinner. Mar dit is seldsum. Meastentiids rinne jo gewoan út skiifromte of ûnthâld. As jo ​​gjin skiifromte hawwe, is d'r mar ien útwei - romte frijmeitsje en de databank opnij starte.

Out-Of-Memory Killer

As in server of proses sûnder ûnthâld rint, biedt Linux 2 oplossingen: crashe it hiele systeem of beëinigje it proses (applikaasje) dat it ûnthâld opsmyt. It is fansels better om it proses te beëinigjen en it OS te bewarjen fan crashen. Yn in notedop is Out-Of-Memory Killer in proses dat in applikaasje deadet om de kernel te bewarjen fan crashen. It offeret de applikaasje op om it OS rinnend te hâlden. Litte wy earst beprate hoe't OOM wurket en hoe't jo it kinne kontrolearje, en dan sjen hoe't OOM Killer beslút hokker applikaasje te beëinigjen.

Ien fan 'e haadtaken fan Linux is om ûnthâld te allocearjen oan prosessen as se der om freegje. Typysk freget in proses of applikaasje ûnthâld fan it OS, mar brûkt it net folslein. As it OS ûnthâld jout oan elkenien dy't der om freget, mar hat gjin plannen om it te brûken, sil it ûnthâld heul gau oprinne en sil it systeem mislearje. Om dit te foarkommen, reservearret it OS ûnthâld foar it proses, mar makket it net eins frij. Unthâld wurdt allinich tawiisd as in proses it eins sil brûke. It bart dat it OS gjin frije ûnthâld hat, mar it jout ûnthâld ta oan in proses, en as in proses it nedich is, allocearret it OS it as it kin. It neidiel is dat soms it OS ûnthâld reservearret, mar op it krekte momint is d'r gjin frije ûnthâld, en it systeem crasht. OOM spilet in wichtige rol yn dit senario en beëiniget prosessen om foar te kommen dat de kernel panyk makket. As in PostgreSQL-proses twongen wurdt om te beëinigjen, ferskynt in berjocht yn it log:

Out of Memory: Killed process 12345 (postgres).

As it systeem leech is op ûnthâld en it kin net befrijd wurde, wurdt de funksje neamd out_of_memory. Op dit stadium hat se mar ien ding te dwaan - ien of mear prosessen foltôgje. Moat OOM-killer it proses fuortendaliks beëinigje of kin it wachtsje? Fansels, as out_of_memory wurdt neamd, komt it troch it wachtsjen op in I / O-operaasje of paging nei skiif. Dêrom moat de OOM-moardner earst kontrôles útfiere en op grûn dêrfan beslute dat it proses beëinige wurde moat. As alle kontrôles hjirûnder posityf binne, sil OOM it proses beëinigje.

Proses seleksje

As ûnthâld rint út, de funksje neamd out_of_memory(). It hat in funksje select_bad_process(), dy't in evaluaasje krijt fan 'e funksje badness(). It "slimste" proses sil rjochte wurde. Funksje badness() kiest in proses neffens bepaalde regels.

  1. De kernel hat wat minimum ûnthâld foar himsels nedich.
  2. Jo moatte in protte ûnthâld frijmeitsje.
  3. D'r is gjin ferlet om prosessen te beëinigjen dy't lyts ûnthâld brûke.
  4. Minimum prosessen moatte wurde foltôge.
  5. Komplekse algoritmen dy't de kâns op foltôging fergrutsje foar dy prosessen dy't de brûker sels foltôgje wol.

Nei it foltôgjen fan al dizze kontrôles ûndersiket OOM de skoare (oom_score). OOM jout oom_score elk proses, en dan fermannichfâldigje dizze wearde mei it bedrach fan ûnthâld. Prosessen mei gruttere wearden binne wierskynliker slachtoffer fan 'e OOM Killer. Prosessen dy't ferbûn binne mei de root-brûker hawwe in legere skoare en wurde minder wierskynlik twongen om te beëinigjen.

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

De Postgres proses ID is 3813, dus yn in oare shell is it mooglik om de skoare te krijen mei dizze kernelparameter oom_score:

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

As jo ​​​​net wolle dat OOM-Killer it proses hielendal deadzje, is d'r in oare kearnopsje: oom_score_adj. Foegje in grutte negative wearde ta te ferminderjen de kânsen fan in foltôgjen fan in proses jo wearde.

sudo echo -100 > /proc/3813/oom_score_adj

Om in wearde yn te stellen oom_score_adj, set OOMScoreAdjust yn it tsjinstblok yn:

[Service]
OOMScoreAdjust=-1000

Of brûke oomprotect yn in team rcctl.

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

Force beëiniging fan in proses

As ien of mear prosessen al selektearre binne, ropt OOM-Killer de funksje op oom_kill_task(). Dizze funksje stjoert in beëinigingsinjaal nei it proses. Yn gefal fan ûnthâld tekoart oom_kill() Roept dizze funksje op om in SIGKILL-sinjaal nei it proses te stjoeren. In berjocht wurdt skreaun nei it kernel log.

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

Hoe kinne jo OOM-Killer kontrolearje

Op Linux kinne jo OOM-Killer yn- of útskeakelje (hoewol it lêste net oan te rieden is). Brûk de parameter om te aktivearjen of út te skeakeljen vm.oom-kill. Om OOM-Killer by runtime yn te skeakeljen, útfiere it kommando sysctl.

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

Om OOM-Killer út te skeakeljen, spesifisearje de wearde 0 yn itselde kommando:

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

It resultaat fan dit kommando sil net foar altyd bewarre wurde, mar allinich oant de earste herstart. As jo ​​​​mear persistinsje nedich binne, foegje dan dizze rigel ta oan it bestân /etc/sysctl.conf:

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

In oare manier om yn- en út te skeakeljen is in fariabele te skriuwen panic_on_oom. De wearde kin altyd yncheckt wurde /proc.

$ cat /proc/sys/vm/panic_on_oom
0

As jo ​​​​de wearde ynstelle op 0, dan sil d'r gjin kernel panyk wêze as it ûnthâld op is.

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

As jo ​​​​de wearde ynstelle op 1, dan sil in kernel panyk foarkomme as it ûnthâld op is.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer kin net allinich yn- en útskeakele wurde. Wy hawwe al sein dat Linux mear ûnthâld kin reservearje foar prosessen dan beskikber is sûnder it feitlik te allocearjen, en dit gedrach wurdt regele troch in Linux-kernelparameter. De fariabele is dêr ferantwurdlik foar vm.overcommit_memory.

Jo kinne de folgjende wearden dêrfoar opjaan:

0: De kernel sels beslút oft te reservearje tefolle ûnthâld. Dit is de standert op de measte ferzjes fan Linux.
1: De kearn sil altyd ekstra ûnthâld reservearje. Dit is risikofolle, om't it ûnthâld kin oprinne, om't, nei alle gedachten, ien dei de prosessen sille fereaskje.
2: de kearn sil net reservearje mear ûnthâld as oantsjutte yn de parameter overcommit_ratio.

Mei dizze parameter spesifisearje jo it persintaazje ûnthâld dat tastien is om te reservearjen. As der gjin romte foar it, gjin ûnthâld wurdt tawiisd, en it reservaat wurdt wegere. Dit is de feilichste opsje oanrikkemandearre foar PostgreSQL. OOM-Killer wurdt beynfloede troch in oar elemint - de wikselfermogen, dat wurdt regele troch de fariabele cat /proc/sys/vm/swappiness. Dizze wearden fertelle de kernel hoe't it paging kin omgean. Hoe heger de wearde, hoe minder kâns it is dat OOM it proses sil beëinigje, mar troch I/O-operaasjes hat it in negative ynfloed op de databank. En oarsom - hoe leger de wearde, hoe heger de kâns op OOM-Killer-yntervinsje, mar de databankprestaasje is ek heger. De standertwearde is 60, mar as de folsleine databank yn it ûnthâld past, is it better om de wearde op 1 yn te stellen.

Resultaten

Lit de "moardner" yn OOM-Killer jo net bang meitsje. Yn dit gefal sil de moardner de rêder fan jo systeem wêze. It "deadet" de minste prosessen en besparret it systeem fan crashing. Om foar te kommen dat jo OOM-Killer moatte brûke om PostgreSQL te beëinigjen, set op vm.overcommit_memory wearde 2. Dit garandearret net dat OOM-Killer net hoecht yn te gripen, mar it sil de kâns ferminderje om it PostgreSQL-proses te twingen om te beëinigjen.

Boarne: www.habr.com

Add a comment