Sette opp Out-Of-Memory Killer i Linux for PostgreSQL

Sette opp Out-Of-Memory Killer i Linux for PostgreSQL

Når en databaseserver avsluttes uventet i Linux, må du finne årsaken. Det kan være flere årsaker. For eksempel, SIGSEGV — feil på grunn av en feil i backend-serveren. Men dette er sjeldent. Oftest går du rett og slett tom for diskplass eller minne. Hvis du går tom for diskplass, er det bare én vei ut – frigjør plass og start databasen på nytt.

Ut-av-minnet morder

Når en server eller prosess går tom for minne, tilbyr Linux to løsninger: krasj hele systemet eller avslutt prosessen (applikasjonen) som spiser opp minnet. Det er selvfølgelig bedre å avslutte prosessen og redde OS fra å krasje. I et nøtteskall er Out-Of-Memory Killer en prosess som dreper et program for å redde kjernen fra å krasje. Det ofrer applikasjonen for å holde operativsystemet i gang. La oss først diskutere hvordan OOM fungerer og hvordan man kontrollerer det, og deretter se hvordan OOM Killer bestemmer hvilket program som skal avsluttes.

En av hovedoppgavene til Linux er å allokere minne til prosesser når de ber om det. Vanligvis ber en prosess eller applikasjon om minne fra operativsystemet, men bruker det ikke fullt ut. Hvis operativsystemet gir ut minne til alle som ber om det, men ikke har planer om å bruke det, vil minnet snart gå tom og systemet vil svikte. For å unngå dette reserverer operativsystemet minne for prosessen, men slipper det faktisk. Minne tildeles bare når en prosess faktisk skal bruke det. Det hender at operativsystemet ikke har ledig minne, men det tildeler minne til en prosess, og når en prosess trenger det, tildeler OS det hvis det kan. Ulempen er at noen ganger reserverer operativsystemet minne, men til rett tid er det ikke ledig minne, og systemet krasjer. OOM spiller en viktig rolle i dette scenariet og avslutter prosesser for å forhindre at kjernen får panikk. Når en PostgreSQL-prosess blir tvunget til å avslutte, vises en melding i loggen:

Out of Memory: Killed process 12345 (postgres).

Hvis systemet har lite minne og det ikke kan frigjøres, kalles funksjonen opp out_of_memory. På dette stadiet har hun bare én ting igjen å gjøre – fullføre en eller flere prosesser. Bør OOM-killer avslutte prosessen umiddelbart eller kan den vente? Åpenbart, når out_of_memory kalles, er det på grunn av venting på en I/O-operasjon eller personsøking til disk. Derfor må OOM-morderen først utføre kontroller og, basert på dem, bestemme at prosessen må avsluttes. Hvis alle sjekkene nedenfor er positive, vil OOM avslutte prosessen.

Prosessvalg

Når minnet går tom, kalles funksjonen opp out_of_memory(). Den har en funksjon select_bad_process(), som mottar en evaluering fra funksjonen badness(). Den "verste" prosessen vil bli målrettet. Funksjon badness() velger en prosess i henhold til visse regler.

  1. Kjernen trenger et minimumsminne for seg selv.
  2. Du må frigjøre mye minne.
  3. Det er ikke nødvendig å avslutte prosesser som bruker lite minne.
  4. Minimumsprosesser må fullføres.
  5. Komplekse algoritmer som øker sjansene for gjennomføring for de prosessene som brukeren selv ønsker å fullføre.

Etter å ha fullført alle disse kontrollene, undersøker OOM poengsummen (oom_score). OOM tildeler oom_score hver prosess, og multipliserer deretter denne verdien med mengden minne. Prosesser med større verdier er mer sannsynlig å bli offer for OOM-morderen. Prosesser knyttet til root-brukeren har lavere poengsum og er mindre sannsynlig at de blir tvunget til å avslutte.

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

Postgres prosess ID er 3813, så i et annet skall er det mulig å få poengsummen ved å bruke denne kjerneparameteren oom_score:

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

Hvis du ikke vil at OOM-Killer skal drepe prosessen i det hele tatt, er det et annet kjernealternativ: oom_score_adj. Legg til en stor negativ verdi for å redusere sjansene for å fullføre en prosess du verdsetter.

sudo echo -100 > /proc/3813/oom_score_adj

For å angi en verdi oom_score_adj, sett OOMScoreAdjust i serviceblokken:

[Service]
OOMScoreAdjust=-1000

Eller bruk oomprotect på et lag rcctl.

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

Tvinge avslutning av en prosess

Når en eller flere prosesser allerede er valgt, kaller OOM-Killer opp funksjonen oom_kill_task(). Denne funksjonen sender et avslutningssignal til prosessen. Ved minnemangel oom_kill() Kaller denne funksjonen for å sende et SIGKILL-signal til prosessen. En melding skrives til kjerneloggen.

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

Hvordan kontrollere OOM-Killer

På Linux kan du aktivere eller deaktivere OOM-Killer (selv om sistnevnte ikke anbefales). Bruk parameteren for å aktivere eller deaktivere vm.oom-kill. For å aktivere OOM-Killer under kjøretid, kjør kommandoen sysctl.

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

For å deaktivere OOM-Killer, spesifiser verdien 0 i samme kommando:

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

Resultatet av denne kommandoen vil ikke bli lagret for alltid, men bare til første omstart. Hvis du trenger mer utholdenhet, legg til denne linjen i filen /etc/sysctl.conf:

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

En annen måte å aktivere og deaktivere er å skrive en variabel panic_on_oom. Verdien kan alltid sjekkes inn /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Hvis du setter verdien til 0, vil det ikke være noen kjernepanikk når minnet går tom.

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

Hvis du setter verdien til 1, vil en kjernepanikk oppstå når minnet går tom.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer kan ikke bare slås av og på. Vi har allerede sagt at Linux kan reservere mer minne for prosesser enn det som er tilgjengelig uten å faktisk tildele det, og denne oppførselen styres av en Linux-kjerneparameter. Variabelen er ansvarlig for dette vm.overcommit_memory.

Du kan angi følgende verdier for det:

0: Kjernen bestemmer selv om den skal reservere for mye minne. Dette er standard på de fleste versjoner av Linux.
1: Kjernen vil alltid reservere ekstra minne. Dette er risikabelt, fordi minnet kan gå tom, fordi, mest sannsynlig, en dag vil prosessene kreve det.
2: kjernen vil ikke reservere mer minne enn spesifisert i parameteren overcommit_ratio.

Med denne parameteren spesifiserer du prosentandelen av minnet som er tillatt å være overreservert. Hvis det ikke er plass til det, blir det ikke tildelt noe minne, og reservasjonen vil bli avvist. Dette er det sikreste alternativet som anbefales for PostgreSQL. OOM-Killer påvirkes av et annet element - byttefunksjonen, som styres av variabelen cat /proc/sys/vm/swappiness. Disse verdiene forteller kjernen hvordan den skal håndtere personsøking. Jo høyere verdi, jo mindre sannsynlig er det at OOM vil avslutte prosessen, men på grunn av I/O-operasjoner har det en negativ innvirkning på databasen. Og omvendt - jo lavere verdi, jo høyere er sannsynligheten for OOM-Killer-intervensjon, men databaseytelsen er også høyere. Standardverdien er 60, men hvis hele databasen får plass i minnet, er det bedre å sette verdien til 1.

Resultater av

Ikke la "morderen" i OOM-Killer skremme deg. I dette tilfellet vil morderen være redningen av systemet ditt. Det "dreper" de verste prosessene og redder systemet fra å krasje. For å unngå å måtte bruke OOM-Killer for å avslutte PostgreSQL, sett til vm.overcommit_memory verdi 2. Dette garanterer ikke at OOM-Killer ikke trenger å gripe inn, men det vil redusere sannsynligheten for å tvinge PostgreSQL-prosessen til å avslutte.

Kilde: www.habr.com

Legg til en kommentar