
NĂ€r en databasserver i Linux ovĂ€ntat kraschar, mĂ„ste man hitta orsaken. Det kan finnas flera orsaker. Till exempel, SIGSEGV â ett krasch pĂ„ grund av en bugg i backend-servern. Men det Ă€r sĂ€llsynt. Oftast tar bara diskutrymmet eller minnet slut. Om diskutrymmet tar slut, finns det ingen annan vĂ€g â man mĂ„ste frigöra utrymme och starta om databasen.
Out-Of-Memory Killer
NÀr en servern eller process fÄr slut pÄ minne, erbjuder Linux 2 lösningar: att krascha hela systemet eller avsluta den process (applikation) som förbrukar minnet. Det Àr givetvis bÀttre att avsluta processen och rÀdda operativsystemet frÄn en krasch. Kort sagt, Out-Of-Memory Killer Àr en process som avslutar applikationen för att rÀdda kÀrnan frÄn att krascha. Den offrar applikationen för att bevara operativsystemets funktion. LÄt oss först diskutera hur OOM fungerar och hur den kan kontrolleras, och sedan titta pÄ hur OOM Killer bestÀmmer vilken applikation som ska avslutas.
En av de viktigaste uppgifterna för Linux Àr att tilldela minne till processer nÀr de begÀr det. Vanligtvis begÀr en process eller applikation minne frÄn operativsystemet, men de utnyttjar det inte helt. Om operativsystemet ger minne till alla som ber om det, men som inte planerar att anvÀnda det, kommer minnet snart att ta slut och systemet kommer att falla. För att undvika detta reserverar operativsystemet minnet för processen, men ger det faktiskt inte ut. Minne tilldelas först nÀr processen verkligen ska anvÀnda det. Det hÀnder att operativsystemet inte har nÄgot ledigt minne, men det reserverar minnet för processen, och nÀr processen behöver det, tilldelar operativsystemet det, om det kan. Nackdelen Àr att ibland reserverar operativsystemet minne, men vid behov finns det inget ledigt minne, och systemet kraschar. OOM spelar en viktig roll i detta scenario och avslutar processer för att skydda kÀrnan frÄn panik. NÀr en PostgreSQL-process avslutas tvingat, visas ett meddelande i loggen:
Out of Memory: Killed process 12345 (postgres).Om det finns lite minne i systemet och det inte gÄr att frigöra, anropas funktionen out_of_memory. Vid det hÀr steget ÄterstÄr det bara för den att avsluta en eller flera processer. OOM-killer bör avsluta processen omedelbart eller kan man vÀnta? Det Àr uppenbart att nÀr out_of_memory anropas handlar det om att vÀnta pÄ I/O-operationer eller att byta ut sidor till disk. DÀrför bör OOM-killer först göra kontroller och baserat pÄ dem besluta vilken process som ska avslutas. Om alla kontroller nedan ger ett positivt resultat kommer OOM att avsluta processen.
Val av process
NÀr minnet tar slut anropas funktionen out_of_memory(). Den har en funktion select_bad_process(), som fÄr en bedömning frÄn funktionen badness(). Den mest "dÄliga" processen kommer att vÀljas. Funktionen badness() vÀljer processer enligt specifika regler.
- KÀrnan behöver en viss mÀngd minne för sig sjÀlv.
- Det behövs för att frigöra mycket minne.
- Det Àr inte nödvÀndigt att avsluta processer som anvÀnder lite minne.
- Minst nÄgra processer bör avslutas.
- Komplexa algoritmer som ökar chansen att avsluta de processer som anvÀndaren sjÀlv vill avsluta.
Efter att ha genomfört alla dessa kontroller analyserar OOM bedömningen (oom_score). OOM tilldelar oom_score varje process ett vÀrde och multiplicerar sedan detta vÀrde med mÀngden minne. Processer med högre vÀrden har större chans att bli offer för OOM Killer. Processer som Àr kopplade till privilegierade anvÀndare har en lÀgre bedömning och mindre chans att bli tvÄngsavslutade.
postgres=# SELECT pg_backend_pid();
pg_backend_pidÂ
----------------
    3813
(1 rad)Postgres-processens ID Àr 3813, sÄ i ett annat terminalfönster kan man fÄ bedömningen med hjÀlp av detta kÀrnparameter oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2Om du helt och hÄllet inte vill att OOM-Killer ska avsluta processen finns det en annan kÀrnparameter: oom_score_adj. LÀgg till ett stort negativt vÀrde för att minska chansen att din viktiga process avslutas.
sudo echo -100 > /proc/3813/oom_score_adjFör att stÀlla in vÀrdet oom_score_adj, stÀll in OOMScoreAdjust i serviceblocket:
[Service]
OOMScoreAdjust=-1000Eller anvÀnd oomprotect i kommandot rcctl.
rcctl set servicename oomprotect -1000Tvinga avslut av process
NÀr en eller flera processer redan har valts, anropar OOM-Killer funktionen oom_kill_task(). Denna funktion skickar en avslutningssignal till processen. Vid minnesbrist oom_kill() anropar denna funktion för att skicka SIGKILL-signalen till processen. Ett meddelande loggas i kÀrnan.
Ut ur minne: Processen [pid] [name] dödades.Hur man kontrollerar OOM-Killer
I Linux kan OOM-Killer aktiveras och inaktiveras (Àven om det sistnÀmnda inte rekommenderas). För att aktivera eller inaktivera, anvÀnd parametern vm.oom-kill. För att aktivera OOM-Killer i körningsmiljön, kör kommandot sysctl.
sudo -s sysctl -w vm.oom-kill=1För att inaktivera OOM-Killer, ange vÀrdet 0 i samma kommando:
sudo -s sysctl -w vm.oom-kill=0Resultatet av detta kommando kommer inte att sparas permanent, utan endast till den första omstarten. Om mer bestÀndighet behövs, lÀgg till denna rad i filen /etc/sysctl.conf:
echo vm.oom-kill=1 >> /etc/sysctl.confEtt annat sÀtt att aktivera och inaktivera Àr att skriva variabeln panic_on_oom. VÀrdet kan alltid kontrolleras med /proc.
$ cat /proc/sys/vm/panic_on_oom
0Om vÀrdet sÀtts till 0, kommer det inte att bli nÄgon kernel panic nÀr minnet tar slut.
$ echo 0 > /proc/sys/vm/panic_on_oomOm vÀrdet sÀtts till 1, kommer det att intrÀffa en kernel panic nÀr minnet tar slut.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer kan inte bara aktiveras och inaktiveras. Vi har redan nÀmnt att Linux kan reservera mer minne för processer Àn som faktiskt finns, men inte tilldela det, och detta beteende styrs av Linux-kÀrnans parameter. Denna hanteras av variabeln vm.overcommit_memory.
För denna kan följande vÀrden anges:
0: KÀrnan bestÀmmer sjÀlv om det Àr vettigt att reservera för mycket minne. Detta vÀrde Àr standard i de flesta versioner av Linux.
1: KÀrnan kommer alltid att reservera extra minne. Detta Àr riskabelt, eftersom minnet kan ta slut, eftersom processerna troligtvis kommer att begÀra det reserverade nÄgon gÄng.
2: KÀrnan kommer inte att reservera mer minne Àn vad som anges i parametern overcommit_ratio.
I detta parameter anger du den procentandel av minnet som tillÄts för överkompensation. Om det inte finns nÄgot utrymme för det, kommer minnet inte att tilldelas och överkompensationen kommer att nekas. Detta Àr det sÀkraste alternativet, rekommenderat för PostgreSQL. OOM-Killer pÄverkas ocksÄ av en annan faktor - swapmöjligheten, som hanteras av variabeln cat /proc/sys/vm/swappiness. Dessa vÀrden indikerar för kÀrnan hur man behandlar sidutbyte. Ju högre vÀrde, desto mindre sannolikhet att OOM avslutar processen, men pÄ grund av in- och utdataoperationer pÄverkar detta databasen negativt. OmvÀnt, ju lÀgre vÀrde, desto högre sannolikhet för ingrepp frÄn OOM-Killer, men databasen presterar ocksÄ bÀttre. StandardvÀrdet Àr 60, men om hela databasen fÄr plats i minnet Àr det bÀttre att stÀlla in vÀrdet till 1.
Sammanfattning
LÄt er inte skrÀmmas av "killer" i OOM-Killer. I det hÀr fallet kommer killern att vara rÀddaren för ert system. Den "dödar" de mest problematiska processerna och rÀddar systemet frÄn krash. För att undvika att behöva anvÀnda OOM-Killer för att avsluta PostgreSQL, stÀll in för vm.overcommit_memory vÀrdet 2. Det garanterar inte att OOM-Killer inte behöver ingripa, men det minskar sannolikheten för att PostgreSQL-processen tvingas avslutas.
KĂ€lla: habr.com
