
Quando dentro Linux Il server del database si arresta in modo imprevisto ed è necessario determinarne la causa. Le ragioni potrebbero essere molteplici. Ad esempio, SIGSEGV — errore dovuto a un bug nel server backend. Ma questo è raro. Molto spesso, semplicemente si esaurisce lo spazio su disco o la memoria. Se esaurisci lo spazio su disco, c'è solo una via d'uscita: liberare spazio e riavviare il database.
Killer senza memoria
Quando server oppure il processo esaurisce la memoria, Linux L'Out-Of-Memory Killer offre due soluzioni: mandare in crash l'intero sistema o terminare il processo (applicazione) che sta consumando memoria. Ovviamente, è preferibile terminare il processo ed evitare il crash del sistema operativo. In breve, l'Out-Of-Memory Killer è un processo che termina un'applicazione per evitare il crash del kernel. Sacrifica l'applicazione per mantenere il sistema operativo in esecuzione. Analizziamo prima come funziona l'OOM e come controllarlo, per poi esaminare come l'OOM Killer decide quali applicazioni terminare.
Uno dei compiti principali Linux — Assegna memoria ai processi solo quando la richiedono. In genere, un processo o un'applicazione richiede memoria al sistema operativo, ma non la utilizza completamente. Se il sistema operativo alloca memoria a tutti coloro che la richiedono senza avere intenzione di utilizzarla, il sistema esaurirà rapidamente la memoria e si bloccherà. Per evitare ciò, il sistema operativo riserva memoria per un processo, ma non la alloca effettivamente. La memoria viene allocata solo quando un processo intende effettivamente utilizzarla. A volte il sistema operativo non ha memoria libera, ma la alloca a un processo e, quando il processo ne ha bisogno, il sistema operativo la alloca se possibile. Lo svantaggio è che a volte il sistema operativo riserva memoria, ma quando serve non ce n'è di libera, causando un arresto anomalo del sistema. La gestione della memoria insufficiente (OOM) gioca un ruolo chiave in questo scenario, terminando i processi per evitare che il kernel vada in panic. Quando il processo PostgreSQL viene terminato forzatamente, nel log viene visualizzato il seguente messaggio:
Out of Memory: Killed process 12345 (postgres).Se la memoria del sistema è insufficiente e non può essere liberata, viene richiamata la funzione out_of_memory. A questo punto le resta solo una cosa da fare: completare uno o più processi. OOM-killer deve terminare immediatamente il processo o può attendere? Ovviamente, quando viene chiamato out_of_memory, è dovuto all'attesa di un'operazione di I/O o di paginazione su disco. Pertanto, l'OOM killer deve prima effettuare dei controlli e, in base ad essi, decidere che il processo deve essere terminato. Se tutti i controlli seguenti risultano positivi, OOM terminerà il processo.
Selezione del processo
Quando la memoria si esaurisce, viene richiamata la funzione out_of_memory(). Ha una funzione select_bad_process(), che riceve una valutazione dalla funzione badness(). Verrà preso di mira il processo “peggiore”. Funzione badness() seleziona un processo secondo determinate regole.
- Il kernel necessita di una memoria minima per se stesso.
- È necessario liberare molta memoria.
- Non è necessario terminare i processi che utilizzano poca memoria.
- È necessario completare processi minimi.
- Algoritmi complessi che aumentano le possibilità di completamento di quei processi che l'utente stesso desidera completare.
Dopo aver completato tutti questi controlli, OOM esamina il punteggio (oom_score). OOM assegna oom_score ogni processo, quindi moltiplica questo valore per la quantità di memoria. I processi con valori più grandi hanno maggiori probabilità di cadere vittime dell'OOM Killer. I processi associati all'utente root hanno un punteggio inferiore e hanno meno probabilità di essere forzati a terminare.
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3813
(1 row)L'ID del processo 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
2Se non vuoi che OOM-Killer interrompa del tutto il processo, c'è un'altra opzione del kernel: oom_score_adj. Aggiungi un valore negativo elevato per ridurre le possibilità di completare un processo che apprezzi.
sudo echo -100 > /proc/3813/oom_score_adjPer impostare un valore oom_score_adj, imposta OOMScoreAdjust nel blocco servizi:
[Service]
OOMScoreAdjust=-1000Oppure usa oomprotect in una squadra rcctl.
rcctl set <i>servicename</i> oomprotect -1000Forzare la conclusione di un processo
Quando uno o più processi sono già selezionati, OOM-Killer richiama la funzione oom_kill_task(). Questa funzione invia un segnale di terminazione al processo. In caso di carenza di memoria oom_kill() Chiama questa funzione per inviare un segnale SIGKILL al processo. Viene scritto un messaggio nel log del kernel.
Out of Memory: Killed process [pid] [name].Come controllare OOM-Killer
В Linux È possibile abilitare o disabilitare OOM-Killer (anche se quest'ultima opzione non è consigliata). Per abilitarlo o disabilitarlo, utilizzare il parametro vm.oom-kill. Per abilitare OOM-Killer in fase di runtime, esegui il comando sysctl.
sudo -s sysctl -w vm.oom-kill = 1Per disabilitare OOM-Killer, specificare il valore 0 nello stesso comando:
sudo -s sysctl -w vm.oom-kill = 0Il risultato di questo comando non verrà salvato per sempre, ma solo fino al primo riavvio. Se hai bisogno di maggiore persistenza, aggiungi questa riga al file /etc/sysctl.conf:
echo vm.oom-kill = 1 >>/etc/sysctl.confUn altro modo per abilitare e disabilitare è scrivere una variabile panic_on_oom. Il valore può sempre essere registrato /proc.
$ cat /proc/sys/vm/panic_on_oom
0Se imposti il valore su 0, quando la memoria si esaurisce, non si verificherà alcun panico nel kernel.
$ echo 0 > /proc/sys/vm/panic_on_oomSe imposti il valore su 1, quando la memoria si esaurisce, si verificherà un panico del kernel.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer può essere attivato e disattivato, come già accennato. Linux può riservare più memoria per i processi di quanta ne sia disponibile, ma non allocarla effettivamente, e questo comportamento è controllato da un parametro del kernel. LinuxLa variabile è responsabile di ciò. vm.overcommit_memory.
È possibile specificare i seguenti valori:
0: È il kernel stesso a decidere se riservare troppa memoria. Questo è il valore predefinito nella maggior parte delle versioni. Linux.
1: Il kernel riserverà sempre memoria extra. Questo è rischioso, perché la memoria potrebbe esaurirsi, perché, molto probabilmente, un giorno i processi ne avranno bisogno.
2: il kernel non riserverà più memoria di quella specificata nel parametro overcommit_ratio.
Con questo parametro si specifica la percentuale di memoria che può essere riservata in eccesso. Se non c'è spazio, non verrà allocata memoria e la prenotazione verrà negata. Questa è l'opzione più sicura consigliata per PostgreSQL. OOM-Killer è influenzato da un altro elemento: la capacità di scambio, che è controllata dalla variabile cat /proc/sys/vm/swappiness. Questi valori dicono al kernel come gestire il paging. Più alto è il valore, meno è probabile che OOM termini il processo, ma a causa delle operazioni di I/O ha un impatto negativo sul database. E viceversa: più basso è il valore, maggiore è la probabilità dell'intervento di OOM-Killer, ma anche le prestazioni del database sono maggiori. Il valore predefinito è 60, ma se l'intero database entra in memoria, è meglio impostare il valore su 1.
Risultati di
Non lasciare che il "killer" di OOM-Killer ti spaventi. In questo caso, l'assassino sarà il salvatore del tuo sistema. “Uccide” i processi peggiori e salva il sistema dal crash. Per evitare di dover utilizzare OOM-Killer per terminare PostgreSQL, impostare su vm.overcommit_memory valore 2. Ciò non garantisce che OOM-Killer non debba intervenire, ma ridurrà la probabilità di forzare la chiusura del processo PostgreSQL.
Fonte: habr.com
