Configurarea Out-Of-Memory Killer în Linux pentru PostgreSQL

Configurarea Out-Of-Memory Killer în Linux pentru PostgreSQL

Când un server de baze de date Linux se închide neașteptat, trebuie să găsiți cauza. Cauzele pot fi multiple. De exemplu, SIGSEGV — o eronare cauzată de un bug în serverul de backend. Dar aceasta este o raritate. Cea mai frecventă problemă este epuizarea spațiului pe disc sau a memoriei. Dacă spațiul pe disc s-a terminat, singura soluție este să eliberați spațiu și să reporniți baza de date.

Out-Of-Memory Killer

Când server sau procesul consumă toată memoria, Linux oferă două soluții: să oprească sistemul complet sau să încheie procesul (aplicația) care consumă memorie. Este preferabil să se încheie procesul și să se salveze sistemul de operare de la o oprire neașteptată. Pe scurt, Out-Of-Memory Killer este procesul care oprește aplicația pentru a proteja nucleul de o defecțiune. El sacrifică aplicația pentru a păstra funcționalitatea sistemului de operare. Să discutăm mai întâi despre cum funcționează OOM și cum poate fi controlat, apoi să vedem cum decide OOM Killer ce aplicație să încheie.

Una dintre principalele sarcini ale Linux este să aloce memorie proceselor atunci când acestea o solicită. În mod obișnuit, un proces sau o aplicație solicită memorie de la sistemul de operare și o utilizează incomplet. Dacă sistemul de operare ar acorda memorie tuturor celor care o solicită, dar nu au de gând să o utilizeze, foarte curând s-ar termina memoria, iar sistemul ar eșua. Pentru a evita acest lucru, sistemul de operare reține memoria pentru proces, dar de fapt nu o eliberează. Memoria este alocată doar atunci când procesul intenționează realmente să o utilizeze. Se întâmplă ca sistemul de operare să nu aibă memorie liberă, dar reține memoria pentru proces, iar când procesul are nevoie de ea, sistemul de operare o alocă, dacă poate. Dezavantajul este că, uneori, sistemul de operare reține memoria, dar în momentul necesar nu există memorie liberă, iar sistemul se blochează. OOM joacă un rol important în acest scenariu și încheie procesele pentru a proteja nucleul de panică. Când un proces PostgreSQL este închis forțat, în jurnal apare mesajul:

Out of Memory: Killed process 12345 (postgres).

Dacă în sistem este puțină memorie și nu se poate elibera, se apelează funcția out_of_memory. În această etapă, singurul lucru rămas este să finalizeze unul sau mai multe procese. OOM-killer trebuie să încheie procesul imediat sau poate aștepta? Este evident că, atunci când este apelat out_of_memory, se stabilește că este vorba de așteptarea unei operațiuni de intrare-ieșire sau de swap-ul paginii pe disc. Prin urmare, OOM-killer trebuie să efectueze mai întâi verificările și, pe baza acestora, să decidă ce proces trebuie închis. Dacă toate verificările de mai jos sunt pozitive, OOM va încheia procesul.

Selectarea procesului

Când se termină memoria, este apelată funcția out_of_memory(). Aceasta conține funcția select_bad_process(), care primește o evaluare de la funcția badness(). Procesul cel mai „rău” va fi ales. Funcția badness() selectează procesul conform unor reguli specifice.

  1. Nucleul are nevoie de un minim de memorie pentru sine.
  2. Trebuie să eliberăm multă memorie.
  3. Nu este necesar să închidem procesele care consumă puțină memorie.
  4. Trebuie să închidem cel puțin câteva procese.
  5. Algoritmi complecși care cresc șansele de închidere pentru acele procese pe care utilizatorul vrea să le închidă.

După ce toate aceste verificări sunt efectuate, OOM examinează evaluarea (oom_score). OOM atribuie oom_score fiecareui proces, apoi înmulțește această valoare cu cantitatea de memorie. Procesele cu valori mari au șanse mai mari de a deveni victime ale OOM Killer. Procesele asociate cu un utilizator privilegiat au o evaluare mai mică și mai puține șanse de a fi terminate forțat.

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

Identificatorul procesului Postgres este 3813, așa că în altă legătură se poate obține evaluarea folosind acest parametru de nucleu oom_score:

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

Dacă nu doriți deloc ca OOM-Killer să închidă procesul, există un alt parametru de nucleu: oom_score_adj. Adăugați o valoare negativă mare pentru a reduce șansele de închidere a procesului pe care îl prețuiți.

sudo echo -100 > /proc/3813/oom_score_adj

Pentru a seta valoarea oom_score_adj, stabiliți OOMScoreAdjust în blocul de servicii:

[Service]
OOMScoreAdjust=-1000

Sau utilizați oomprotect în comanda rcctl.

rcctl set servicename oomprotect -1000

Închiderea forțată a procesului

Când unul sau mai multe procese sunt deja selectate, OOM-Killer apelează funcția oom_kill_task(). Această funcție trimite procesului un semnal de închidere. În caz de lipsă de memorie, oom_kill() apelează această funcție pentru a trimite procesului un semnal SIGKILL. Un mesaj este înregistrat în jurnalul nucleului.

Lipsă de memorie: Proces [pid] [name] ucis.

Cum să controlăm OOM-Killer

În Linux, OOM-Killer poate fi activat sau dezactivat (deși ultima acțiune nu este recomandată). Pentru a activa sau dezactiva, utilizați parametrul vm.oom-kill. Pentru a activa OOM-Killer în timpul execuției, rulați comanda sysctl.

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

Pentru a dezactiva OOM-Killer, specificați valoarea 0 în aceeași comandă:

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

Rezultatul acestei comenzi nu va persista, ci doar până la prima repornire. Dacă este nevoie de mai multă permanență, adăugați această linie în fișierul /etc/sysctl.conf:

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

O altă modalitate de a activa sau dezactiva este de a scrie variabila panic_on_oom. Valoarea poate fi verificată întotdeauna în /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Dacă setezi valoarea 0, atunci când memoria se epuizează, kernel panic nu va avea loc.

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

Dacă setezi valoarea 1, atunci când memoria se epuizează, se va întâmpla kernel panic.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer nu poate fi doar activat sau dezactivat. Am menționat deja că Linux poate rezerva pentru procese mai multă memorie decât este disponibilă, fără a o aloca efectiv, iar acest comportament este gestionat de un parametru al kernel-ului Linux. Acesta este controlat de variabila vm.overcommit_memory.

Pentru aceasta, poți specifica următoarele valori:

0: kernel-ul decide singur dacă este bine să rezerve prea multă memorie. Aceasta este valoarea implicită în majoritatea versiunilor de Linux.
1: kernel-ul va rezerva întotdeauna memorie suplimentară. Acest lucru este riscant, deoarece memoria s-ar putea termina, pentru că este foarte probabil ca, la un moment dat, procesele să solicite ce le este cuvenit.
2: kernel-ul nu va rezerva mai multă memorie decât este specificată în parametrul overcommit_ratio.

În acest parametru specifici procentul de memorie pentru care este permisă rezervarea excesivă. Dacă nu există suficient loc pentru aceasta, memoria nu se va aloca, iar rezervarea va fi refuzată. Aceasta este cea mai sigură opțiune, recomandată pentru PostgreSQL. Un alt element care influențează OOM-Killer este posibilitatea de swap, gestionată de variabila cat /proc/sys/vm/swappiness. Aceste valori indică nucleului cum să gestioneze swapul paginilor. Cu cât valoarea este mai mare, cu atât este mai puțin probabil ca OOM să finalizeze procesul, dar din cauza operațiunilor de intrare-ieșire, acest lucru afectează negativ baza de date. Pe de altă parte, cu cât valoarea este mai mică, cu atât este mai mare probabilitatea de intervenție a OOM-Killer, dar și performanța bazei de date este mai bună. Valoarea implicită este 60, dar dacă întreaga bază de date încape în memorie, este mai bine să setați valoarea la 1.

Concluzii

Nu lăsați termenul „killer” din OOM-Killer să vă sperie. În acest caz, killerul va fi salvatorul sistemului dumneavoastră. El „omoară” cele mai nedorite procese și salvează sistemul de la o închidere de urgență. Pentru a nu fi nevoie să utilizați OOM-Killer pentru a opri PostgreSQL, setați vm.overcommit_memory valoarea la 2. Aceasta nu garantează că OOM-Killer nu va trebui să intervină, dar va reduce probabilitatea de finalizare forțată a procesului PostgreSQL.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster