
Când în Linux Serverul bazei de date se oprește în mod neașteptat, iar cauza trebuie determinată. Pot exista mai multe motive. De exemplu, SIGSEGV — eșec din cauza unei erori în serverul backend. Dar acest lucru este rar. Cel mai adesea, pur și simplu rămâneți fără spațiu pe disc sau memorie. Dacă rămâneți fără spațiu pe disc, există o singură cale de ieșire - eliberați spațiu și reporniți baza de date.
Ucigașul fără memorie
Când Server sau procesul rămâne fără memorie, Linux Programul Out-Of-Memory Killer oferă două soluții: blocarea întregului sistem sau terminarea procesului (aplicației) care consumă memorie. Desigur, este mai bine să terminați procesul și să salvați sistemul de operare de la blocare. Pe scurt, programul Out-Of-Memory Killer este un proces care termină o aplicație pentru a salva kernelul de la blocare. Sacrifică aplicația pentru a menține sistemul de operare în funcțiune. Să discutăm mai întâi cum funcționează OOM și cum să îl controlăm, apoi să vedem cum decide OOM Killer ce aplicații să termine.
Una dintre sarcinile principale Linux — Alocați memorie proceselor atunci când acestea o solicită. De obicei, un proces sau o aplicație solicită memorie de la sistemul de operare, dar nu o utilizează complet. Dacă sistemul de operare alocă memorie tuturor celor care o solicită, dar nu intenționează să o utilizeze, sistemul va rămâne rapid fără memorie și se va bloca. Pentru a preveni acest lucru, sistemul de operare rezervă memorie pentru un proces, dar nu o alocă efectiv. Memoria este alocată numai atunci când un proces intenționează efectiv să o utilizeze. Uneori, sistemul de operare nu are memorie liberă, dar alocă memorie unui proces, iar când procesul are nevoie de ea, sistemul de operare o alocă dacă poate. Dezavantajul este că uneori sistemul de operare rezervă memorie, dar atunci când este nevoie, nu există memorie liberă, provocând o blocare a sistemului. OOM joacă un rol cheie în acest scenariu, terminând procesele pentru a preveni panicarea kernelului. Când procesul PostgreSQL este terminat forțat, apare următorul mesaj în jurnal:
Out of Memory: Killed process 12345 (postgres).Dacă sistemul are memorie scăzută și nu poate fi eliberat, funcția este apelată out_of_memory. În această etapă, ea mai are un singur lucru de făcut - să finalizeze unul sau mai multe procese. OOM-killer ar trebui să încheie imediat procesul sau poate aștepta? Evident, atunci când este apelat out_of_memory, se datorează așteptării unei operațiuni I/O sau paginare pe disc. Prin urmare, criminalul OOM trebuie mai întâi să efectueze verificări și, pe baza acestora, să decidă că procesul trebuie să fie încheiat. Dacă toate verificările de mai jos sunt pozitive, OOM va încheia procesul.
Selecția procesului
Când memoria se epuizează, funcția este apelată out_of_memory(). Are o funcție select_bad_process(), care primește o evaluare de la funcție badness(). Cel mai „prost” proces va fi vizat. Funcţie badness() selectează un proces după anumite reguli.
- Nucleul are nevoie de o memorie minimă pentru el însuși.
- Trebuie să eliberați multă memorie.
- Nu este nevoie să terminați procesele care folosesc puțină memorie.
- Procesele minime trebuie finalizate.
- Algoritmi complecși care măresc șansele de finalizare pentru acele procese pe care utilizatorul însuși dorește să le finalizeze.
După ce a finalizat toate aceste verificări, OOM examinează scorul (oom_score). OOM numește oom_score fiecare proces și apoi înmulțește această valoare cu cantitatea de memorie. Procesele cu valori mai mari au mai multe șanse să cadă victimele OOM Killer. Procesele asociate cu utilizatorul root au un scor mai mic și sunt mai puțin probabil să fie forțate să se încheie.
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3813
(1 row)ID-ul procesului Postgres este 3813, așa că într-un alt shell este posibil să obțineți scorul folosind acest parametru de kernel oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2Dacă nu doriți ca OOM-Killer să oprească deloc procesul, există o altă opțiune de kernel: oom_score_adj. Adăugați o valoare negativă mare pentru a reduce șansele de a finaliza un proces pe care îl apreciați.
sudo echo -100 > /proc/3813/oom_score_adjPentru a seta o valoare oom_score_adj, setați OOMScoreAdjust în blocul de servicii:
[Service]
OOMScoreAdjust=-1000Sau folosiți oomprotect într-o echipă rcctl.
rcctl set <i>servicename</i> oomprotect -1000Forțare încetarea unui proces
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 terminare. În caz de lipsă de memorie oom_kill() Apelează această funcție pentru a trimite un semnal SIGKILL către proces. Un mesaj este scris în jurnalul kernelului.
Out of Memory: Killed process [pid] [name].Cum să controlezi OOM-Killer
В Linux Puteți activa sau dezactiva OOM-Killer (deși ultima opțiune nu este recomandată). Pentru a-l activa sau dezactiva, utilizați parametrul vm.oom-kill. Pentru a activa OOM-Killer în timpul execuției, executați comanda sysctl.
sudo -s sysctl -w vm.oom-kill = 1Pentru a dezactiva OOM-Killer, specificați valoarea 0 în aceeași comandă:
sudo -s sysctl -w vm.oom-kill = 0Rezultatul acestei comenzi nu va fi salvat pentru totdeauna, ci doar până la prima repornire. Dacă aveți nevoie de mai multă persistență, adăugați această linie la fișier /etc/sysctl.conf:
echo vm.oom-kill = 1 >>/etc/sysctl.confO altă modalitate de a activa și de a dezactiva este să scrieți o variabilă panic_on_oom. Valoarea poate fi întotdeauna verificată /proc.
$ cat /proc/sys/vm/panic_on_oom
0Dacă setați valoarea la 0, atunci când memoria se epuizează, nu va exista nicio panică a nucleului.
$ echo 0 > /proc/sys/vm/panic_on_oomDacă setați valoarea la 1, atunci când memoria se epuizează, va apărea o panică a nucleului.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer poate fi activat și dezactivat, așa cum am menționat deja. Linux poate rezerva mai multă memorie pentru procese decât este disponibilă, dar nu o poate aloca efectiv, iar acest comportament este controlat de un parametru al kernelului LinuxVariabila este responsabilă pentru asta. vm.overcommit_memory.
Puteți specifica următoarele valori pentru acesta:
0: Nucleul însuși decide dacă rezervă prea multă memorie. Aceasta este valoarea implicită în majoritatea versiunilor. Linux.
1: Nucleul va rezerva întotdeauna memorie suplimentară. Acest lucru este riscant, deoarece memoria se poate epuiza, pentru că, cel mai probabil, într-o zi procesele o vor cere.
2: nucleul nu va rezerva mai multă memorie decât cea specificată în parametru overcommit_ratio.
Cu acest parametru, specificați procentul de memorie care poate fi suprarezervat. Dacă nu există loc pentru el, nu se alocă memorie și rezervarea va fi refuzată. Aceasta este cea mai sigură opțiune recomandată pentru PostgreSQL. OOM-Killer este afectat de un alt element - capacitatea de schimb, care este controlată de variabilă cat /proc/sys/vm/swappiness. Aceste valori îi spun nucleului cum să gestioneze paginarea. Cu cât valoarea este mai mare, cu atât este mai puțin probabil ca OOM să încheie procesul, dar din cauza operațiunilor I/O are un impact negativ asupra bazei de date. Și invers - cu cât valoarea este mai mică, cu atât este mai mare probabilitatea intervenției OOM-Killer, dar și performanța bazei de date este mai mare. Valoarea implicită este 60, dar dacă întreaga bază de date încape în memorie, este mai bine să setați valoarea la 1.
Rezultatele
Nu lăsa „ucigașul” din OOM-Killer să te sperie. În acest caz, ucigașul va fi salvatorul sistemului tău. „Ucide” cele mai rele procese și salvează sistemul de la prăbușire. Pentru a evita utilizarea OOM-Killer pentru a termina PostgreSQL, setați la vm.overcommit_memory valoarea 2. Acest lucru nu garantează că OOM-Killer nu va trebui să intervină, dar va reduce probabilitatea de a forța procesul PostgreSQL să se termine.
Sursa: www.habr.com
