Konfigurera Out-Of-Memory Killer i Linux för PostgreSQL

Konfigurera Out-Of-Memory Killer i Linux för PostgreSQL

När en databasserver avslutas oväntat i Linux måste du hitta orsaken. Det kan finnas flera anledningar. Till exempel, SIGSEGV — fel på grund av en bugg i backend-servern. Men detta är sällsynt. Oftast får du helt enkelt slut på diskutrymme eller minne. Om du får slut på diskutrymme finns det bara en väg ut - frigör utrymme och starta om databasen.

Out-of-Memory Killer

När en server eller process tar slut på minne, erbjuder Linux två lösningar: krascha hela systemet eller avsluta processen (applikationen) som äter upp minnet. Det är naturligtvis bättre att avsluta processen och rädda operativsystemet från att krascha. I ett nötskal, Out-Of-Memory Killer är en process som dödar ett program för att rädda kärnan från att krascha. Det offrar applikationen för att hålla OS igång. Låt oss först diskutera hur OOM fungerar och hur man kontrollerar det, och sedan se hur OOM Killer bestämmer vilket program som ska avslutas.

En av Linuxs huvuduppgifter är att allokera minne till processer när de ber om det. Vanligtvis begär en process eller applikation minne från operativsystemet, men använder det inte fullt ut. Om operativsystemet ger ut minne till alla som ber om det men inte har några planer på att använda det, kommer minnet snart att ta slut och systemet kommer att misslyckas. För att undvika detta reserverar operativsystemet minne för processen, men släpper det faktiskt inte. Minne tilldelas endast när en process faktiskt kommer att använda det. Det händer att operativsystemet inte har ledigt minne, men det tilldelar minne till en process, och när en process behöver det, tilldelar OS det om det kan. Nackdelen är att ibland reserverar operativsystemet minne, men vid rätt tidpunkt finns det inget ledigt minne, och systemet kraschar. OOM spelar en viktig roll i detta scenario och avslutar processer för att förhindra att kärnan får panik. När en PostgreSQL-process tvingas avslutas, visas ett meddelande i loggen:

Out of Memory: Killed process 12345 (postgres).

Om systemet har ont om minne och det inte kan frigöras, anropas funktionen out_of_memory. I det här skedet har hon bara en sak kvar att göra – slutföra en eller flera processer. Ska OOM-killer avsluta processen omedelbart eller kan den vänta? Uppenbarligen, när out_of_memory anropas beror det på att man väntar på en I/O-operation eller sökning till disk. Därför måste OOM-mördaren först utföra kontroller och utifrån dem besluta att processen måste avslutas. Om alla kontroller nedan är positiva kommer OOM att avsluta processen.

Processval

När minnet tar slut anropas funktionen out_of_memory(). Den har en funktion select_bad_process(), som får en utvärdering från funktionen badness(). Den "värsta" processen kommer att riktas mot. Fungera badness() väljer en process enligt vissa regler.

  1. Kärnan behöver lite minne för sig själv.
  2. Du måste frigöra mycket minne.
  3. Det finns inget behov av att avsluta processer som använder lite minne.
  4. Minsta processer måste slutföras.
  5. Komplexa algoritmer som ökar chanserna till slutförande för de processer som användaren själv vill slutföra.

Efter att ha genomfört alla dessa kontroller undersöker OOM poängen (oom_score). OOM tilldelar oom_score varje process och multiplicerar sedan detta värde med mängden minne. Processer med större värden är mer benägna att falla offer för OOM Killer. Processer associerade med root-användaren har lägre poäng och är mindre sannolikt att tvingas avslutas.

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

Postgres process-ID är 3813, så i ett annat skal är det möjligt att få poängen med denna kärnparameter oom_score:

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

Om du inte vill att OOM-Killer ska döda processen alls, finns det ett annat kärnalternativ: oom_score_adj. Lägg till ett stort negativt värde för att minska chanserna att slutföra en process som du värdesätter.

sudo echo -100 > /proc/3813/oom_score_adj

För att ställa in ett värde oom_score_adj, ställ in OOMScoreAdjust i serviceblocket:

[Service]
OOMScoreAdjust=-1000

Eller använd oomprotect i ett lag rcctl.

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

Framtvinga avslutande av en process

När en eller flera processer redan är valda 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 en SIGKILL-signal till processen. Ett meddelande skrivs till kärnloggen.

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

Hur man styr OOM-Killer

På Linux kan du aktivera eller inaktivera OOM-Killer (även om det senare inte rekommenderas). För att aktivera eller inaktivera använd parametern vm.oom-kill. För att aktivera OOM-Killer vid körning, kör kommandot sysctl.

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

För att inaktivera OOM-Killer, ange värdet 0 i samma kommando:

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

Resultatet av detta kommando kommer inte att sparas för alltid, utan bara tills den första omstarten. Om du behöver mer uthållighet, lägg till den här raden i filen /etc/sysctl.conf:

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

Ett annat sätt att aktivera och inaktivera är att skriva en variabel panic_on_oom. Värdet kan alltid checkas in /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Om du ställer in värdet till 0 kommer det inte att uppstå någon kärnpanik när minnet tar slut.

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

Om du ställer in värdet till 1 kommer en kärnpanik att uppstå när minnet tar slut.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer kan inte bara slås på och av. Vi har redan sagt att Linux kan reservera mer minne för processer än vad som är tillgängligt utan att faktiskt allokera det, och detta beteende styrs av en Linux-kärnaparameter. Variabeln är ansvarig för detta vm.overcommit_memory.

Du kan ange följande värden för det:

0: Kärnan själv bestämmer om den ska reservera för mycket minne. Detta är standard på de flesta versioner av Linux.
1: Kärnan kommer alltid att reservera extra minne. Detta är riskabelt, eftersom minnet kan ta slut, eftersom processerna troligen kommer att kräva det en dag.
2: kärnan kommer inte att reservera mer minne än vad som anges i parametern overcommit_ratio.

Med den här parametern anger du den procentandel av minnet som får vara överreserverat. Om det inte finns plats för det tilldelas inget minne och reservationen kommer att nekas. Detta är det säkraste alternativet som rekommenderas för PostgreSQL. OOM-Killer påverkas av ett annat element - växlingsförmågan, som styrs av variabeln cat /proc/sys/vm/swappiness. Dessa värden talar om för kärnan hur man hanterar personsökning. Ju högre värde, desto mindre sannolikt är det att OOM kommer att avsluta processen, men på grund av I/O-operationer har det en negativ inverkan på databasen. Och vice versa - ju lägre värde, desto högre är sannolikheten för OOM-Killer-intervention, men databasprestandan är också högre. Standardvärdet är 60, men om hela databasen får plats i minnet är det bättre att sätta värdet till 1.

Resultat av

Låt inte "mördaren" i OOM-Killer skrämma dig. I det här fallet kommer mördaren att bli ditt systems räddare. Det "dödar" de värsta processerna och räddar systemet från att krascha. För att undvika att behöva använda OOM-Killer för att avsluta PostgreSQL, ställ in på vm.overcommit_memory värde 2. Detta garanterar inte att OOM-Killer inte behöver ingripa, men det kommer att minska sannolikheten för att tvinga PostgreSQL-processen att avslutas.

Källa: will.com

Lägg en kommentar