Configuració de Out-Of-Memory Killer a Linux per a PostgreSQL

Configuració de Out-Of-Memory Killer a Linux per a PostgreSQL

Quan un servidor de bases de dades es tanca inesperadament a Linux, cal trobar el motiu. Hi pot haver diversos motius. Per exemple, SIGSEGV — error a causa d'un error al servidor de fons. Però això és rar. Molt sovint, simplement us quedeu sense espai de disc o memòria. Si us quedeu sense espai al disc, només hi ha una sortida: alliberar espai i reiniciar la base de dades.

Assassí sense memòria

Quan un servidor o procés es queda sense memòria, Linux ofereix 2 solucions: bloquejar tot el sistema o finalitzar el procés (aplicació) que està consumint memòria. És millor, per descomptat, finalitzar el procés i evitar que el sistema operatiu es bloquegi. En poques paraules, Out-Of-Memory Killer és un procés que mata una aplicació per evitar que el nucli es bloquegi. Sacrifica l'aplicació per mantenir el sistema operatiu en funcionament. Primer parlem de com funciona l'OOM i com controlar-lo, i després veurem com OOM Killer decideix quina aplicació ha de finalitzar.

Una de les tasques principals de Linux és assignar memòria als processos quan ho demanen. Normalment, un procés o aplicació sol·licita memòria al sistema operatiu, però no la utilitza completament. Si el sistema operatiu dóna memòria a tothom que la demana però no té previst utilitzar-la, molt aviat la memòria s'esgotarà i el sistema fallarà. Per evitar-ho, el sistema operatiu reserva memòria per al procés, però en realitat no l'allibera. La memòria només s'assigna quan un procés realment l'utilitzarà. Succeeix que el SO no té memòria lliure, però assigna memòria a un procés, i quan un procés la necessita, el SO l'assigna si pot. L'inconvenient és que de vegades el sistema operatiu reserva memòria, però en el moment adequat no hi ha memòria lliure i el sistema es bloqueja. L'OOM té un paper important en aquest escenari i finalitza els processos per evitar que el nucli s'espanti. Quan un procés PostgreSQL es veu obligat a finalitzar, apareix un missatge al registre:

Out of Memory: Killed process 12345 (postgres).

Si el sistema té poca memòria i no es pot alliberar, es crida la funció out_of_memory. En aquesta etapa, només li queda una cosa per fer: completar un o més processos. OOM-killer hauria de finalitzar el procés immediatament o pot esperar? Òbviament, quan es crida a out_of_memory, es deu a l'espera d'una operació d'E/S o de paginació al disc. Per tant, l'assassí OOM primer ha de realitzar comprovacions i, a partir d'elles, decidir que s'ha d'acabar el procés. Si totes les comprovacions següents són positives, OOM finalitzarà el procés.

Selecció del procés

Quan s'esgota la memòria, es crida la funció out_of_memory(). Té una funció select_bad_process(), que rep una avaluació de la funció badness(). El procés "pitjor" serà objectiu. Funció badness() selecciona un procés segons determinades regles.

  1. El nucli necessita una mica de memòria mínima per a si mateix.
  2. Necessites alliberar molta memòria.
  3. No cal finalitzar processos que utilitzen poca memòria.
  4. S'han de completar uns tràmits mínims.
  5. Algorismes complexos que augmenten les possibilitats de finalització d'aquells processos que el propi usuari vol completar.

Després de completar totes aquestes comprovacions, OOM examina la puntuació (oom_score). assigna OOM oom_score cada procés i després multiplica aquest valor per la quantitat de memòria. Els processos amb valors més grans tenen més probabilitats de ser víctimes de l'OOM Killer. Els processos associats amb l'usuari root tenen una puntuació més baixa i és menys probable que es vegin obligats a finalitzar.

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

L'ID del procés de Postgres és 3813, de manera que en un altre shell és possible obtenir la puntuació utilitzant aquest paràmetre del nucli oom_score:

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

Si no voleu que OOM-Killer mati el procés, hi ha una altra opció del nucli: oom_score_adj. Afegiu un valor negatiu gran per reduir les possibilitats de completar un procés que valoreu.

sudo echo -100 > /proc/3813/oom_score_adj

Per establir un valor oom_score_adj, establiu OOMScoreAdjust al bloc de servei:

[Service]
OOMScoreAdjust=-1000

O utilitzar oomprotect en un equip rcctl.

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

Força la finalització d'un procés

Quan un o més processos ja estan seleccionats, OOM-Killer crida la funció oom_kill_task(). Aquesta funció envia un senyal de terminació al procés. En cas de manca de memòria oom_kill() Crida aquesta funció per enviar un senyal SIGKILL al procés. S'escriu un missatge al registre del nucli.

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

Com controlar OOM-Killer

A Linux, podeu activar o desactivar OOM-Killer (tot i que aquest últim no és recomanable). Per activar o desactivar, utilitzeu el paràmetre vm.oom-kill. Per habilitar OOM-Killer en temps d'execució, executeu l'ordre sysctl.

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

Per desactivar OOM-Killer, especifiqueu el valor 0 a la mateixa ordre:

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

El resultat d'aquesta ordre no es desarà per sempre, sinó només fins al primer reinici. Si necessiteu més persistència, afegiu aquesta línia al fitxer /etc/sysctl.conf:

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

Una altra manera d'activar i desactivar és escriure una variable panic_on_oom. El valor sempre es pot registrar /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Si poseu el valor a 0, quan s'esgoti la memòria, no hi haurà pànic del nucli.

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

Si poseu el valor a 1, quan s'esgoti la memòria, es produirà un pànic al nucli.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer no només es pot activar i apagar. Ja hem dit que Linux pot reservar més memòria per als processos de la que està disponible sense assignar-la realment, i aquest comportament està controlat per un paràmetre del nucli de Linux. La variable és responsable d'això vm.overcommit_memory.

Podeu especificar-hi els valors següents:

0: El nucli mateix decideix si reserva massa memòria. Aquest és el valor predeterminat a la majoria de versions de Linux.
1: El nucli sempre reservarà memòria addicional. Això és arriscat, perquè la memòria es pot esgotar, perquè, molt probablement, algun dia els processos ho requeriran.
2: el nucli no reservarà més memòria de la que s'especifica al paràmetre overcommit_ratio.

Amb aquest paràmetre, especifiqueu el percentatge de memòria que es pot sobrereservar. Si no hi ha lloc, no s'assigna cap memòria i es denegarà la reserva. Aquesta és l'opció més segura recomanada per a PostgreSQL. OOM-Killer es veu afectat per un altre element: la capacitat d'intercanvi, que està controlada per la variable cat /proc/sys/vm/swappiness. Aquests valors indiquen al nucli com gestionar la paginació. Com més alt sigui el valor, menys probable és que l'OOM acabi el procés, però a causa de les operacions d'E/S té un impacte negatiu a la base de dades. I viceversa: com més baix sigui el valor, més probabilitat d'intervenció OOM-Killer, però el rendiment de la base de dades també és més alt. El valor predeterminat és 60, però si tota la base de dades cap a la memòria, és millor establir el valor a 1.

Resultats de

No deixis que el "assassí" d'OOM-Killer t'espanti. En aquest cas, l'assassí serà el salvador del vostre sistema. "Mata" els pitjors processos i evita que el sistema s'estavelli. Per evitar haver d'utilitzar OOM-Killer per finalitzar PostgreSQL, configureu a vm.overcommit_memory valor 2. Això no garanteix que OOM-Killer no hagi d'intervenir, però reduirà la probabilitat d'obligar la finalització del procés PostgreSQL.

Font: www.habr.com

Afegeix comentari