Configurare l'Out-Of-Memory Killer in Linux per PostgreSQL

Configurare l'Out-Of-Memory Killer in Linux per PostgreSQL

Quando in Linux il server del database si arresta in modo imprevisto, è necessario trovare la causa. Le cause possono essere diverse. Per esempio, SIGSEGV — un crash dovuto a un bug nel server backend. Ma questo è raro. Nella maggior parte dei casi, lo spazio su disco o la memoria finiscono. Se lo spazio su disco è esaurito, l'unica soluzione è liberare spazio e riavviare il database.

Out-Of-Memory Killer

Quando la server memoria di un processo si esaurisce, Linux offre 2 soluzioni: far crashare l'intero sistema o terminare il processo (l'applicazione) che consuma memoria. È preferibile terminare il processo e salvare il sistema operativo da un arresto anomalo. In breve, l'Out-Of-Memory Killer è un processo che termina l'applicazione per proteggere il kernel da un crash. Sacrifica l'applicazione per preservare il funzionamento del sistema operativo. Innanzitutto, discutiamo di come funziona OOM e di come controllarlo, poi vediamo come l'OOM Killer decide quale applicazione terminare.

Uno dei principali compiti di Linux è allocare memoria ai processi quando la richiedono. Di solito, un processo o un'applicazione richiedono memoria al sistema operativo, ma la utilizzano solo parzialmente. Se il sistema operativo fornisce memoria a chi la chiede, ma non la utilizza, presto la memoria si esaurirà e il sistema si bloccherà. Per evitare ciò, il sistema operativo riserva la memoria per il processo, ma in effetti non la fornisce. La memoria viene allocata solo quando il processo è pronto a usarla. A volte, il sistema operativo non ha memoria libera, ma riserva memoria per il processo e, quando è necessaria, la fornisce, se può. Il problema è che a volte il sistema operativo riserva memoria, ma al momento opportuno non c'è memoria libera, causando un crash del sistema. L'OOM gioca un ruolo importante in questo scenario e termina i processi per salvaguardare il kernel da panico. Quando un processo PostgreSQL viene terminato forzatamente, nel log appare il messaggio:

Out of Memory: Killed process 12345 (postgres).

Se nel sistema c'è poca memoria e non è possibile liberarla, viene chiamata la funzione out_of_memory. A questo punto, le resta solo una cosa da fare: terminare uno o più processi. OOM-killer deve terminare il processo immediatamente o si può aspettare? È ovvio che, quando viene chiamato out_of_memory, ciò è legato a un'attesa per un'operazione di input/output o al paginamento su disco. Pertanto, l'OOM-killer deve prima eseguire le verifiche e, sulla base di esse, decidere quale processo terminare. Se tutte le verifiche sottostanti danno esito positivo, OOM terminerà il processo.

Selezione del processo

Quando la memoria è esaurita, viene chiamata la funzione out_of_memory(). Essa contiene una funzione select_bad_process(), che riceve un punteggio dalla funzione badness(). Sarà il processo più “cattivo” a essere selezionato. La funzione badness() seleziona il processo secondo determinate regole.

  1. Il kernel ha bisogno di una certa quantità minima di memoria per sé stesso.
  2. È necessario liberare molta memoria.
  3. Non bisogna terminare i processi che usano poca memoria.
  4. È necessario terminare almeno alcuni processi.
  5. Algoritmi complessi che aumentano le possibilità di terminazione per quei processi che l'utente desidera terminare.

Dopo aver eseguito tutte queste verifiche, OOM esamina il punteggio (oom_score). OOM assegna oom_score a ciascun processo, poi moltiplica questo valore per la quantità di memoria. I processi con valori più alti hanno maggiori probabilità di diventare le vittime dell'OOM Killer. I processi associati a un utente privilegiato hanno un punteggio più basso e minori possibilità di terminazione forzata.

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

L'ID del processo di Postgres è 3813, quindi in un'altra shell è possibile ottenere il punteggio utilizzando questo parametro del kernel oom_score:

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

Se non si desidera che l'OOM-Killer termini il processo, c'è un altro parametro del kernel: oom_score_adj. Aggiungi un grande valore negativo per ridurre le probabilità di terminazione del processo a te caro.

sudo echo -100 > /proc/3813/oom_score_adj

Per impostare un valore oom_score_adj, imposta OOMScoreAdjust nel blocco di servizio:

[Service]
OOMScoreAdjust=-1000

Oppure usa oomprotect nel comando rcctl.

rcctl set servicename oomprotect -1000

Terminazione forzata del processo

Quando uno o più processi sono già stati selezionati, OOM-Killer chiama la funzione oom_kill_task(). Questa funzione invia un segnale di terminazione al processo. In caso di esaurimento della memoria oom_kill() chiama questa funzione per inviare al processo il segnale SIGKILL. Un messaggio viene registrato nel log del kernel.

Out of Memory: processo ucciso [pid] [name].

Come controllare OOM-Killer

In Linux è possibile attivare e disattivare OOM-Killer (anche se quest'ultimo non è consigliato). Per attivare e disattivare, utilizzare il parametro vm.oom-kill. Per attivare OOM-Killer durante l'esecuzione, eseguire il comando sysctl.

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

Per disattivare OOM-Killer, specificare il valore 0 in lo stesso comando:

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

Il risultato di questo comando non sarà permanente, ma solo fino al primo riavvio. Se si desidera maggiore persistenza, aggiungere questa riga al file /etc/sysctl.conf:

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

Un altro modo per attivare e disattivare è scrivere la variabile panic_on_oom. Il valore può sempre essere controllato in /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Se si imposta il valore 0, non ci sarà alcun kernel panic quando esaurisce la memoria.

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

Se si imposta il valore 1, si verificherà un kernel panic quando esaurisce la memoria.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer può essere attivato e disattivato. Abbiamo già detto che Linux può riservare più memoria per i processi di quanto non ce ne sia realmente, ma non allocarla, e questo comportamento è controllato dal parametro del kernel Linux. A ciò è responsabile la variabile vm.overcommit_memory.

Per essa, è possibile specificare i seguenti valori:

0: il kernel decide autonomamente se riservare troppa memoria. Questo è il valore predefinito nella maggior parte delle versioni di Linux.
1: il kernel riserverà sempre memoria extra. Questo è rischioso, in quanto è probabile che un giorno i processi richiedano quanto dovuto.
2: il kernel non riserverà più memoria di quanto specificato nel parametro overcommit_ratio.

In questo parametro si specifica la percentuale di memoria per cui è consentita la riserva eccessiva. Se non c'è spazio per essa, non viene allocata memoria, la riserva verrà negata. Questa è l'opzione più sicura, raccomandata per PostgreSQL. Un altro elemento che influisce su OOM-Killer è la possibilità di swapping, gestita dalla variabile cat /proc/sys/vm/swappiness. Questi valori indicano al kernel come gestire lo swap delle pagine. Maggiore è il valore, minore sarà la probabilità che l'OOM termini il processo, ma le operazioni di input/output influiscono negativamente sul database. E viceversa: minore è il valore, maggiore sarà la probabilità di intervento dell'OOM-Killer, ma anche la performance del database sarà maggiore. Il valore predefinito è 60, ma se l'intero database può essere memorizzato in memoria, è meglio impostare il valore a 1.

Conclusioni

Non lasciatevi spaventare dal 'killer' nell'OOM-Killer. In questo caso, il killer sarà il salvatore del vostro sistema. 'Uccide' i processi più critici e salva il sistema da arresti anomali. Per evitare di dover utilizzare l'OOM-Killer per terminare PostgreSQL, impostate per vm.overcommit_memory il valore 2. Questo non garantisce che l'OOM-Killer non debba intervenire, ma ridurrà la probabilità di terminazione forzata del processo PostgreSQL.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster