Configurazione di Out-Of-Memory Killer in Linux per PostgreSQL

Configurazione di Out-Of-Memory Killer in Linux per PostgreSQL

Quandu un servitore di basa di dati si abbanduneghja inaspettatamente in Linux, avete bisognu di truvà u mutivu. Ci pò esse parechje ragioni. Per esempiu, SIGSEGV - fallimentu per un bug in u servitore backend. Ma questu hè raru. A maiò spessu, avete solu scappatu di spaziu di discu o memoria. S'ellu ùn ci hè micca spaziu di discu, ci hè solu un modu - liberate u spaziu è ripigliate a basa di dati.

Assassinu fora di memoria

Quandu un servitore o un prucessu esce da a memoria, Linux offre 2 suluzioni: crash tuttu u sistema o finisce u prucessu (applicazione) chì manghja memoria. Hè megliu, sicuru, per finisce u prucessu è salvà u OS da crashing. In poche parole, Out-Of-Memory Killer hè un prucessu chì uccide una applicazione per salvà u kernel da crashing. Hè sacrificatu l'applicazione per mantene u SO in esecuzione. Discutemu prima cumu funziona OOM è cumu cuntrullà, è poi vede cumu OOM Killer decide quale applicazione finisce.

Unu di i travaglii principali di Linux hè di assignà memoria à i prucessi quandu u dumandanu. Di genere, un prucessu o applicazione richiede memoria da u SO, ma ùn l'utiliza micca cumplettamente. Se u sistema operativu dà memoria à tutti quelli chì a dumandanu, ma ùn hà micca intenzione di usà, assai prestu a memoria escerà è u sistema falla. Per evitari, u sistema operativu riserva memoria per u prucessu, ma ùn libera micca veramente. A memoria hè attribuita solu quandu un prucessu hà daveru aduprà. Succede chì u SO ùn hà micca memoria libera, ma assigna memoria à un prucessu, è quandu un prucessu ne hà bisognu, u SO l'assigna si pò. U svantaghju hè chì qualchì volta l'OS riserva memoria, ma à u mumentu ghjustu ùn ci hè micca memoria libera, è u sistema crashs. OOM ghjoca un rolu impurtante in questu scenariu è finisce i prucessi per prevene u kernel da u panicu. Quandu un prucessu PostgreSQL hè furzatu à finisce, un messagiu appare in u logu:

Out of Memory: Killed process 12345 (postgres).

Se u sistema hè pocu in memoria è ùn pò micca esse liberatu, a funzione hè chjamata out_of_memory. À questu stadiu, hà solu una cosa da fà - compie unu o più prucessi. OOM-killer deve finisce immediatamente u prucessu o pò aspittà? Ovviamente, quandu out_of_memory hè chjamatu, hè dovutu à aspittà per una operazione I / O o paginazione à u discu. Dunque, l'assassinu OOM deve prima eseguisce cuntrolli è, basatu annantu à elli, decide chì u prucessu deve esse terminatu. Se tutti i cuntrolli sottu sò pusitivi, OOM finisce u prucessu.

Selezzione di prucessu

Quandu a memoria scorri, a funzione hè chjamata out_of_memory(). Hà una funzione select_bad_process(), chì riceve una valutazione da a funzione badness(). U "peghju" prucessu serà destinatu. Funzione badness() sceglie un prucessu secondu certi reguli.

  1. U kernel hà bisognu di qualchì memoria minima per ellu stessu.
  2. Avete bisognu di liberà assai memoria.
  3. Ùn ci hè bisognu di finisce i prucessi chì utilizanu pocu memoria.
  4. I prucessi minimi anu da esse cumpletati.
  5. Algoritmi cumplessi chì aumentanu e probabilità di cumpiimentu per quelli prucessi chì l'utilizatore stessu vole compie.

Dopu avè finitu tutti questi cuntrolli, OOM esamina u puntuatu (oom_score). L'OOM assigna oom_score ogni prucessu, è poi multiplica stu valore da a quantità di memoria. I prucessi cù valori più grande sò più probabili di fallu vittime di l'OOM Killer. I prucessi assuciati cù l'usu root anu un puntuatu più bassu è sò menu prubabile di esse furzati à finisce.

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

L'ID di u prucessu di Postgres hè 3813, cusì in un altru shell hè pussibule di ottene u puntuazione utilizendu stu paràmetru di kernel. oom_score:

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

Se ùn vulete micca chì OOM-Killer uccida u prucessu, ci hè una altra opzione di kernel: oom_score_adj. Aghjunghjite un grande valore negativu per riduce e probabilità di compie un prucessu chì valore.

sudo echo -100 > /proc/3813/oom_score_adj

Per stabilisce un valore oom_score_adj, stabilisce OOMScoreAdjust in u bloccu di serviziu:

[Service]
OOMScoreAdjust=-1000

O aduprà oomprotect in una squadra rcctl.

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

Forza a terminazione di un prucessu

Quandu unu o più prucessi sò digià sceltu, OOM-Killer chjama a funzione oom_kill_task(). Sta funzione manda un signalu di terminazione à u prucessu. In casu di mancanza di memoria oom_kill() Chjama sta funzione per mandà un signalu SIGKILL à u prucessu. Un missaghju hè scrittu à u logu di u kernel.

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

Cumu cuntrullà OOM-Killer

In Linux, pudete attivà o disattivà OOM-Killer (ancu se l'ultimu ùn hè micca cunsigliatu). Per attivà o disattivà aduprà u paràmetru vm.oom-kill. Per attivà OOM-Killer in runtime, eseguite u cumandimu sysctl.

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

Per disattivà OOM-Killer, specificate u valore 0 in u listessu cumandamentu:

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

U risultatu di sta cumanda ùn serà micca salvatu per sempre, ma solu finu à u primu reboot. Sè avete bisognu di più persistenza, aghjunghje sta linea à u schedariu /etc/sysctl.conf:

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

Un altru modu per attivà è disattivà hè di scrive una variabile panic_on_oom. U valore pò sempre esse verificatu /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Se mette u valore à 0, quandu a memoria si esaurisce, ùn ci sarà micca u panicu di u kernel.

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

Se mette u valore à 1, quandu a memoria si esaurisce, un panicu di u kernel succede.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer ùn pò micca solu esse attivatu è disattivatu. Avemu digià dettu chì Linux pò riservà più memoria per i prucessi di ciò chì hè dispunibule senza in realtà l'assignà, è questu cumpurtamentu hè cuntrullatu da un paràmetru di kernel Linux. A variàbile hè rispunsevule per questu vm.overcommit_memory.

Pudete specificà i seguenti valori per questu:

0: U kernel stessu decide s'ellu riservà troppu memoria. Questu hè u predefinitu in a maiò parte di e versioni di Linux.
1: U kernel riservà sempre memoria extra. Questu hè risicatu, perchè a memoria pò esce, perchè, assai prubabilmente, un ghjornu i prucessi l'avete bisognu.
2: u kernel ùn riservà più memoria di quella specificata in u paràmetru overcommit_ratio.

Cù stu paràmetru, specificate u percentualità di memoria chì hè permessa di esse riservata. S'ellu ùn ci hè micca spaziu per questu, ùn hè micca attribuita memoria, è a riservazione serà denegata. Questa hè l'opzione più sicura cunsigliata per PostgreSQL. OOM-Killer hè affettatu da un altru elementu - a capacità di scambià, chì hè cuntrullata da a variabile cat /proc/sys/vm/swappiness. Questi valori dicenu à u kernel cumu gestisce a paginazione. U più altu hè u valore, u menu prubabile hè chì OOM finisce u prucessu, ma per via di l'operazioni I/O hà un impattu negativu nantu à a basa di dati. E vice versa - u più bassu u valore, u più altu a probabilità di intervenzione OOM-Killer, ma u rendiment di a basa di dati hè ancu più altu. U valore predeterminatu hè 60, ma se tutta a basa di dati si mette in memoria, hè megliu stabilisce u valore à 1.

Risultati

Ùn lasciate micca chì u "assassinu" in OOM-Killer ti spaventa. In questu casu, l'assassinu serà u salvatore di u vostru sistema. Hè "uccide" i prucessi peghju è salva u sistema da crashing. Per evità di avè aduprà OOM-Killer per finisce PostgreSQL, impostate à vm.overcommit_memory valore 2. Questu ùn guarantisci micca chì OOM-Killer ùn deve micca intervene, ma riducerà a probabilità di furzà u prucessu PostgreSQL per finisce.

Source: www.habr.com

Add a comment