Introduction
Notre équipe a construit et exploité cinq services gérés PostgreSQL au cours des 15 dernières années. Tout au long de ces expériences, une configuration est restée constante : la surallocation de mémoire stricte. Dans cet article, nous allons expliquer comment la surallocation de mémoire stricte protège votre base de données des catastrophiques tueurs OOM (out of memory). Nous partagerons également comment un bogue à trois caractères dans le noyau a forcé notre équipe à désactiver temporairement ce paramètre. Enfin, nous expliquerons notre heuristique pour déterminer la limite de surallocation de mémoire appropriée.
Contexte Technique
Linux permet aux processus d'allouer plus de mémoire virtuelle que ce qui est physiquement disponible. Lorsqu'un processus alloue de la mémoire, le noyau réserve un espace d'adresse virtuel pour celui-ci. Cependant, le noyau n'attribue pas immédiatement cet espace avec de la mémoire physique. Les pages physiques ne sont consommées que lorsque le processus touche réellement la mémoire. Le noyau repose sur l'hypothèse que toute la mémoire allouée ne sera pas utilisée activement en même temps. Généralement, cette hypothèse se vérifie. Lorsqu'elle ne l'est pas, le noyau invoque le tueur OOM pour libérer de la mémoire en terminant un processus.
PostgreSQL est différent des autres processus. Son processus principal (postmaster) crée un processus backend pour chaque connexion. Ces backends partagent des segments de mémoire qui contiennent des tampons partagés, des tampons WAL, des tables de verrous et d'autres états partagés. Le tueur OOM ne comprend pas cette architecture. Il sélectionne simplement un processus en fonction d'une heuristique (généralement le processus qui utilise le plus de mémoire) et le termine. Si ce backend modifiait un segment de mémoire partagée, le segment peut être laissé dans un état incohérent.
Analyse et Implications
La surallocation de mémoire stricte convertit les défaillances tardives et destructrices en défaillances précoces et sans danger. Cependant, ce compromis fonctionne mieux lorsque la machine est dédiée à PostgreSQL et à un petit ensemble de processus connus. Dans ce scénario, le profil de mémoire engagée est prévisible et la limite peut être ajustée avec confiance. Sur les machines partagées exécutant des charges de travail diverses, la mémoire engagée devient plus difficile à prédire.
Notre équipe a toujours préféré la surallocation de mémoire stricte pour PostgreSQL. Cependant, après l'avoir activée, nous avons rapidement rencontré des problèmes. Un bogue à trois caractères dans le noyau a forcé notre équipe à désactiver temporairement ce paramètre. Nous avons découvert que le compteur de mémoire engagée était erroné, ce qui a conduit à des erreurs de mémoire insuffisante même lorsque la mémoire physique était disponible.
Perspective
Il est essentiel de comprendre les implications de la surallocation de mémoire stricte sur les performances et la fiabilité de PostgreSQL. Notre équipe a développé une heuristique pour déterminer la limite de surallocation de mémoire appropriée, en tenant compte des caractéristiques spécifiques de la charge de travail et de la configuration du système. Il est crucial de surveiller les paramètres de surallocation de mémoire et de les ajuster en conséquence pour éviter les erreurs de mémoire insuffisante et assurer la stabilité de la base de données.