
Når en databaseserver i Linux uventet afsluttes, er det nødvendigt at finde årsagen. Der kan være flere grunde. For eksempel, SIGSEGV — et sammenbrud på grund af en fejl i backend-serveren. Men dette er sjældent. Oftest er det bare, fordi der ikke er mere plads på disken eller hukommelse. Hvis der ikke er plads på disken, er der kun én udvej - frigøre plads og genstarte databasen.
Out-Of-Memory Killer
Når en server eller proces løber tør for hukommelse, tilbyder Linux 2 løsninger: enten at bringe hele systemet ned eller at afslutte den proces (applikation), der bruger hukommelsen. Det er selvfølgelig bedst at afslutte processen og redde OS fra en nødafbrydelse. Kort sagt, Out-Of-Memory Killer er en proces, der afslutter en applikation for at redde kernen fra at fejle. Den ofrer applikationen for at bevare OS's funktion. Lad os først diskutere, hvordan OOM fungerer, og hvordan man kontrollerer det, og derefter se, hvordan OOM Killer beslutter, hvilken applikation der skal afsluttes.
En af hovedopgaverne for Linux er at tildele hukommelse til processer, når de beder om det. Normalt anmoder en proces eller applikation OS om hukommelse, men bruger den ikke fuldt ud. Hvis OS bare udleverer hukommelse til alle, der beder om det, men ikke planlægger at bruge den, vil hukommelsen hurtigt løbe tør, og systemet vil fejle. For at undgå dette reserverer OS hukommelse til processen, men udleverer den faktisk ikke. Hukommelsen tildeles kun, når processen virkelig skal bruge den. Det sker, at OS ikke har nogen ledig hukommelse, men den reserverer hukommelse til processen, og når processen har brug for det, tildeler OS det, hvis det kan. Ulempen er, at nogle gange reserverer OS hukommelse, men på det nødvendige tidspunkt er der ikke ledig hukommelse, og systemet fejler. OOM spiller en vigtig rolle i dette scenarie og afslutter processer for at beskytte kernen mod panik. Når processen PostgreSQL tvangsmæssigt afsluttes, vises følgende meddelelse i loggen:
Out of Memory: Killed process 12345 (postgres).Hvis der er lidt hukommelse i systemet, og det ikke er muligt at frigøre mere, kaldes funktionen out_of_memory. På dette tidspunkt er der kun én ting tilbage for den — at afslutte en eller flere processer. Skal OOM-killer afslutte processen straks, eller kan man vente? Det er tydeligt, at når out_of_memory kaldes, skyldes det ventetid på en I/O-operation eller sideudveksling til disk. Derfor skal OOM-killer først udføre kontroller og basere sin beslutning på dem for at afgøre, hvilken proces der skal afsluttes. Hvis alle nedenstående kontroller give positive resultater, afslutter OOM processen.
Valg af proces
Når hukommelsen slipper op, kaldes funktionen out_of_memory(). I denne findes funktionen select_bad_process(), som modtager en score fra funktionen badness(). Den 'dårligste' proces rammes. Funktionen badness() vælger processen baseret på bestemte regler.
- Kernen har brug for et minimum af hukommelse for sig selv.
- Der skal frigøres meget hukommelse.
- Processer, der bruger lidt hukommelse, skal ikke afsluttes.
- Der skal afsluttes mindst et antal processer.
- Komplekse algoritmer, der øger chancerne for at afslutte de processer, som brugeren selv ønsker at afslutte.
Efter at have udført alle disse kontroller, analyserer OOM scoren (oom_score). OOM tildeler oom_score hver proces en score, som derefter ganges med hukommelsesmængden. Processer med højere værdier har større chance for at blive ofre for OOM Killer. Processer tilknyttet privilegerede brugere har en lavere score og mindre chance for tvangsafslutning.
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3813
(1 række)Postgres-proces-ID'et er 3813, så i et andet shell kan man få scoren ved at bruge dette kernelparameter oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2Hvis du slet ikke ønsker, at OOM-Killer skal afslutte processen, er der en anden kernelparameter: oom_score_adj. Tildel et stort negativt værd for at sænke chancerne for, at din vigtige proces afsluttes.
sudo echo -100 > /proc/3813/oom_score_adjFor at indstille værdien oom_score_adj, indstil OOMScoreAdjust i serviceblokken:
[Service]
OOMScoreAdjust=-1000Eller brug oomprotect i kommandoen rcctl.
rcctl set servicename oomprotect -1000Tvangsafslutning af proces
Når en eller flere processer allerede er valgt, kalder OOM-Killer funktionen oom_kill_task(). Denne funktion sender et afslutningssignal til processen. I tilfælde af hukommelsesmangel oom_kill() kalder denne funktion for at sende SIGKILL-signalet til processen. En meddelelse registreres i kernelens log.
Out of Memory: Dræbt proces [pid] [navn].Sådan kontrollerer du OOM-Killer
I Linux kan OOM-Killer aktiveres og deaktiveres (selvom det ikke anbefales at deaktivere det). Brug parameteren til at aktivere eller deaktivere det vm.oom-kill. For at aktivere OOM-Killer i kørsel, udfør kommandoen sysctl.
sudo -s sysctl -w vm.oom-kill=1For at deaktivere OOM-Killer, angiv værdien 0 i denne samme kommando:
sudo -s sysctl -w vm.oom-kill=0Resultatet af denne kommando bevares ikke permanent, men kun indtil den første genstart. Hvis du har brug for mere vedholdenhed, skal du tilføje denne linje til filen /etc/sysctl.conf:
echo vm.oom-kill=1 >> /etc/sysctl.confEn anden måde at aktivere og deaktivere på er at skrive variablen panic_on_oom. Værdien kan altid kontrolleres i /proc.
$ cat /proc/sys/vm/panic_on_oom
0Hvis værdien sættes til 0, så når hukommelsen løber tør, vil der ikke være kernel panic.
$ echo 0 > /proc/sys/vm/panic_on_oomHvis værdien sættes til 1, så når hukommelsen løber tør, vil der ske kernel panic.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer kan ikke kun aktiveres og deaktiveres. Det er allerede nævnt, at Linux kan reservere mere hukommelse til processer end hvad der er tilgængeligt, men ikke allokere den, og denne adfærd styres af Linux-kernens parameter. Dette styres af variablen vm.overcommit_memory.
Her kan der angives følgende værdier:
0: kernen beslutter selv, om den skal reservere for meget hukommelse. Dette er standardværdien i de fleste versioner af Linux.
1: kernen vil altid reservere ekstra hukommelse. Dette er risikabelt, da hukommelsen kan løbe tør, fordi processer sandsynligvis en dag vil kræve det angivne.
2: kernen vil ikke reservere mere hukommelse, end der er angivet i parameteren overcommit_ratio.
I denne parameter angiver du procentdelen af hukommelse, der er tilladt for overreservations. Hvis der ikke er plads til det, allokeres der ikke hukommelse, og der vil blive nægtet reservation. Dette er den sikreste mulighed, der anbefales til PostgreSQL. OOM-Killer påvirkes også af en anden faktor — swap-muligheden, som styres af variablen cat /proc/sys/vm/swappinessDisse værdier angiver kernen, hvordan den skal håndtere sideudveksling. Jo højere værdien er, jo mindre er sandsynligheden for, at OOM vil afslutte processen, men på grund af input/output-operationer påvirker dette databasen negativt. Omvendt, jo lavere værdien er, jo højere er sandsynligheden for, at OOM-Killer griber ind, men så er databaseydelsen også bedre. Standardværdien er 60, men hvis hele databasen kan være i hukommelsen, er det bedre at indstille værdien til 1.
Resumé
Lad dig ikke skræmme af "killer" i OOM-Killer. I dette tilfælde vil killeren være din systems redningsmand. Den "dræber" de mest problematiske processer og redder systemet fra katastrofal nedlukning. For at undgå at skulle bruge OOM-Killer til at afslutte PostgreSQL, indstil vm.overcommit_memory værdien til 2. Dette garanterer ikke, at OOM-Killer ikke vil gribe ind, men det reducerer sandsynligheden for, at PostgreSQL-processen bliver tvunget til at afsluttes.
Kilde: habr.com
