
Lorsque le serveur de base de données s'arrête de manière inattendue sous Linux, vous devez trouver la raison. Il peut y avoir plusieurs raisons. Par exemple, SIGSEGV - plantage en raison d'un bogue sur le serveur principal. Mais c'est une rareté. Plus souvent qu'autrement, l'espace disque ou la mémoire est tout simplement épuisé. Si l'espace disque est épuisé, une solution consiste à libérer de l'espace et à redémarrer la base de données.
Tueur de mémoire insuffisante
Lorsque le serveur ou le processus manque de mémoire, Linux propose 2 solutions: planter le système entier ou terminer le processus (application) qui consomme de la mémoire. Il est préférable, bien sûr, de terminer le processus et de sauver le système d'exploitation d'une interruption anormale. En bref, Out-Of-Memory Killer est le processus qui met fin à une application pour sauver le noyau d'un plantage. Il sacrifie l'application pour faire fonctionner l'OS. Voyons d'abord comment fonctionne OOM et comment le contrôler, puis voyons comment OOM Killer décide quelle application mettre fin.
L'une des principales tâches de Linux consiste à allouer de la mémoire aux processus lorsqu'ils le demandent. Habituellement, un processus ou une application demande de la mémoire au système d'exploitation, mais eux-mêmes ne l'utilisent pas pleinement. Si le système d'exploitation émet de la mémoire à tous ceux qui le demandent, mais ne prévoit pas de l'utiliser, très vite la mémoire se terminera et le système échouera. Pour éviter cela, le système d'exploitation réserve de la mémoire pour le processus, mais ne le fait pas réellement. La mémoire n'est allouée que lorsque le processus va vraiment l'utiliser. Il arrive que le système d'exploitation n'ait pas de mémoire libre, mais il attribue de la mémoire au processus, et lorsque le processus en a besoin, le système d'exploitation l'alloue s'il le peut. L'inconvénient est que parfois le système d'exploitation réserve de la mémoire, mais au bon moment, il n'y a pas de mémoire libre et le système se bloque. Le MOO joue un rôle important dans ce scénario et met fin aux processus pour empêcher le noyau de paniquer. Lorsque le processus PostgreSQL est interrompu de force, un message apparaît dans le journal:
Out of Memory: Killed process 12345 (postgres).
S'il y a peu de mémoire dans le système et qu'il est impossible de la libérer, la fonction out_of_memory
est out_of_memory
. À ce stade, il ne lui reste qu'une chose: terminer un ou plusieurs processus. OOM-killer doit-il mettre fin immédiatement au processus ou puis-je attendre? Évidemment, lorsque out_of_memory est appelé, cela est dû à l'attente d'une opération d'E / S ou d'un échange de page sur le disque. Par conséquent, le MOO-tueur doit d'abord effectuer des vérifications et, sur cette base, décider que le processus doit être terminé. Si toutes les vérifications ci-dessous donnent un résultat positif, le MOO mettra fin au processus.
Sélection de processus
Lorsque la mémoire est épuisée, la fonction out_of_memory()
est out_of_memory()
. Il a une fonction select_bad_process()
, qui reçoit une estimation de la fonction select_bad_process()
. La distribution du processus le plus "mauvais". La fonction badness()
sélectionne un processus selon certaines règles.
- Le noyau a besoin d'un minimum de mémoire pour lui-même.
- Vous devez libérer beaucoup de mémoire.
- Pas besoin de terminer les processus qui utilisent peu de mémoire.
- Vous devez effectuer un minimum de processus.
- Algorithmes complexes qui augmentent les chances d'achèvement des processus que l'utilisateur lui-même souhaite terminer.
Après avoir effectué toutes ces vérifications, le MOO examine la note ( oom_score
). Le MOO affecte oom_score
chaque processus, puis multiplie cette valeur par la quantité de mémoire. Les processus avec des valeurs plus élevées sont plus susceptibles de devenir victimes de OOM Killer. Les processus associés à un utilisateur privilégié ont une note inférieure et sont moins susceptibles de forcer l'arrêt.
postgres=# SELECT pg_backend_pid(); pg_backend_pid ---------------- 3813 (1 row)
L'identifiant du processus Postgres est 3813, donc dans un autre shell, vous pouvez obtenir une estimation en utilisant ce oom_score
noyau oom_score
:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score 2
Si vous ne voulez pas que OOM-Killer termine le processus, il existe un autre paramètre du noyau: oom_score_adj
. Ajoutez une grande valeur négative pour réduire les chances de terminer le processus que vous aimez.
sudo echo -100 > /proc/3813/oom_score_adj
Pour définir la valeur oom_score_adj
, définissez OOMScoreAdjust dans le bloc de service:
[Service] OOMScoreAdjust=-1000
Ou utilisez oomprotect
dans la rcctl
.
rcctl set <i>servicename</i> oomprotect -1000
Arrêt forcé du processus
Lorsqu'un ou plusieurs processus sont déjà sélectionnés, OOM-Killer appelle la fonction oom_kill_task()
. Cette fonction envoie un signal de terminaison au processus. S'il n'y a pas assez de mémoire, oom_kill()
appelle cette fonction pour envoyer un signal SIGKILL au processus. Un message est écrit dans le journal du noyau.
Out of Memory: Killed process [pid] [name].
Comment contrôler OOM-Killer
Sous Linux, vous pouvez activer ou désactiver OOM-Killer (bien que ce dernier ne soit pas recommandé). Pour activer et désactiver, utilisez l'option vm.oom-kill
. Pour activer OOM-Killer à l'exécution, exécutez la commande sysctl
.
sudo -s sysctl -w vm.oom-kill = 1
Pour désactiver OOM-Killer, spécifiez la valeur 0 dans la même commande:
sudo -s sysctl -w vm.oom-kill = 0
Le résultat de cette commande ne sera pas enregistré pour toujours, mais uniquement jusqu'au premier redémarrage. Si vous avez besoin de plus de persistance, ajoutez cette ligne au fichier /etc/sysctl.conf
:
echo vm.oom-kill = 1 >>/etc/sysctl.conf
Une autre façon d'activer et de désactiver consiste à écrire la variable panic_on_oom
. La valeur peut toujours être archivée dans /proc
.
$ cat /proc/sys/vm/panic_on_oom 0
Si vous définissez la valeur sur 0, lorsque la mémoire est épuisée, la panique du noyau ne le sera pas.
$ echo 0 > /proc/sys/vm/panic_on_oom
Si vous définissez la valeur sur 1, lorsque la mémoire est épuisée, une panique du noyau se produit.
echo 1 > /proc/sys/vm/panic_on_oom
OOM-Killer peut non seulement être activé ou désactivé. Nous avons déjà dit que Linux peut réserver plus de mémoire aux processus qu'il n'y en a, mais ne pas l'allouer en fait, et ce comportement est contrôlé par le paramètre du noyau Linux. La variable vm.overcommit_memory
est responsable.
Vous pouvez lui spécifier les valeurs suivantes:
0: le noyau lui-même décide de réserver trop de mémoire. Il s'agit de la valeur par défaut sur la plupart des versions de Linux.
1: le noyau réservera toujours de la mémoire supplémentaire. C'est risqué, car la mémoire peut s'arrêter, car, très probablement, un jour, les processus exigeront ce qui est censé être.
2: le noyau ne réservera pas plus de mémoire que celle spécifiée dans le paramètre overcommit_ratio
.
Dans ce paramètre, vous spécifiez le pourcentage de mémoire pour lequel la redondance est autorisée. S'il n'y a pas d'espace pour cela, la mémoire n'est pas allouée, la réservation sera refusée. Il s'agit de l'option la plus sûre recommandée pour PostgreSQL. OOM-Killer est affecté par un autre élément - la fonction de swap, qui est contrôlée par la variable cat /proc/sys/vm/swappiness
. Ces valeurs indiquent au noyau comment gérer la pagination. Plus la valeur est élevée, moins il est probable que le MOO termine le processus, mais en raison des E / S, cela affecte négativement la base de données. Et vice versa - plus la valeur est petite, plus la probabilité d'intervention d'OOM-Killer est élevée, mais les performances de la base de données sont également plus élevées. La valeur par défaut est 60, mais si la base de données entière tient en mémoire, il est préférable de définir la valeur sur 1.
Résumé
N'ayez pas peur du tueur dans OOM-Killer. Dans ce cas, le tueur sera le sauveur de votre système. Il «tue» les pires processus et sauve le système d'une interruption anormale. Pour éviter d'avoir à utiliser OOM-Killer pour terminer PostgreSQL, définissez vm.overcommit_memory
sur 2. Cela ne garantit pas que OOM-Killer n'a pas à intervenir, mais réduira la probabilité de fin forcée d'un processus PostgreSQL.