L'une des fonctionnalités intéressantes de PostgreSQL depuis la version 9.4 est la possibilité de contrôler la suppression des fichiers WAL à l'aide de slots de réplication. Le côté obscur est que les slots de réplication peuvent faire que les disques se remplissent d'anciens WAL, tuant le serveur de production principal. Dans cet article, j'explique les emplacements de réplication PostgreSQL et comment une nouvelle fonctionnalité de PostgreSQL 13 permet d'éviter ce problème.
Production WAL
Comme vous le savez, WAL est produit pour les changements de base de données dans un serveur primaire :insertions, mises à jour, et cetera . Une base de données plus active produira plus de WAL — dans un serveur très actif, plusieurs gigaoctets de WAL peuvent être produits chaque minute. WAL est écrit dans des fichiers avec des noms dans une séquence numérique croissante, et les fichiers ont toujours la même taille (16 Mo est la valeur par défaut et typique). Une fois que les données d'un fichier ne sont plus nécessaires, ce fichier peut être recyclé , ce qui signifie le renommer à une position de numéro supérieur dans la séquence afin qu'il puisse être rempli avec de nouvelles données ultérieurement.
(Il existe des situations particulières telles qu'une augmentation de l'activité qui conduit à la création de fichiers supplémentaires ; lorsque l'augmentation se calme plus tard, ces fichiers supplémentaires sont supprimés au lieu d'être recyclés.)
Étant donné que toute activité d'écriture de base de données produit des WAL, il est essentiel que l'espace disque soit disponible. Lorsque le disque stockant les WAL est plein, le serveur sera incapable de traiter de nouvelles transactions et peut se bloquer, ou pire :il peut tomber complètement. C'est donc une situation à éviter par tous les moyens possibles.
Emplacements de réplication
La réplication dans PostgreSQL fonctionne en traitant les fichiers WAL. Pour que cela fonctionne, tous les fichiers WAL doivent être temporairement disponibles jusqu'à ce qu'ils soient traités. Par conséquent, un mécanisme est nécessaire pour indiquer à la gestion principale des WAL de ne pas recycler ou supprimer des fichiers.
Entrez les emplacements de réplication. Les slots sont un mécanisme qui indique que ce la sauvegarde que nous prenons exigera que fichier WAL, et pouvez-vous s'il vous plaît ne pas le supprimer encore; ou ceci le réplica n'a toujours pas traité ça Fichier WAL, alors peut-il s'il vous plaît être laissé seul pendant un petit moment.
En eux-mêmes, les slots de réplication occupent très peu d'espace disque. Ils stockent juste un tout petit peu de métadonnées, y compris un pointeur vers une position dans WAL. Mais les données WAL qu'il protège sont une autre affaire :dans un serveur très actif, elles peuvent être mesurées en gigaoctets ou pire.
Consommation WAL
Fournir des données à une réplique physique signifie copier les données WAL à partir de son serveur principal. De même, une réplique logique doit lire les données WAL (et transmettre une version interprétée à la réplique). La position WAL en cours de lecture est ce que la fente garde en mémoire. Une fois que la réplique a sécurisé les données WAL d'une manière ou d'une autre, le slot peut être avancé ; cela indique à la gestion WAL dans le primaire que le fichier WAL est alors disponible pour suppression. Cela se produit en permanence lorsque la réplique est active, de sorte que les WAL du serveur principal utilisent la même quantité d'espace disque ou peut-être juste un peu plus. Même deux ou dix fois plus peuvent être acceptables, selon les conditions.
Le problème est que si une réplique meurt complètement et ne récupère pas pendant une longue période de temps; soit la réplique est détruite et le DBA oublie de retirer le slot de réplication; ou la fente est un reste oublié d'une expérience; ou même si la réplique est alimentée via un lien réseau lent, alors le WAL réservé augmentera sans limites. Et cela devient une bombe à retardement.
Limiter la taille de l'emplacement
Afin de lutter contre ce problème, Kyotaro Horiguchi travaillait depuis février 2017 dans un patch PostgreSQL pour limiter la taille des WAL réservés par un slot. Après un très long processus de révision et de refonte, je l'ai intégré à PostgreSQL 13, améliorant ainsi la gestion des batteries PostgreSQL à haute disponibilité.
Le principe principal est qu'il est préférable de tuer une réplique (en rendant son emplacement invalide ; plus d'informations ci-dessous) que de tuer le serveur principal qui alimente cette réplique et d'arrêter toute la production avec.
La façon dont cela fonctionne est assez simple :définissez max_slot_wal_keep_size
(documentation) dans postgresql.conf à la quantité maximale d'espace disque de WAL que les slots de réplication sont autorisés à réserver. Si un slot atteint ce point et qu'un point de contrôle se produit, ce slot sera marqué comme invalide et certains fichiers WAL pourront être supprimés. Si le slot était utilisé activement par un walsender processus, ce processus sera signalé afin qu'il se termine. Si le walsender redémarre, il constatera que les fichiers WAL nécessaires ne seront plus là. La réplique utilisant cet emplacement devra être reclonée.
Si max_slot_wal_keep_size
est zéro, qui est la valeur par défaut, il n'y a pas de limite. Je ne le recommande pas, car cela entraîne des échecs lorsque les emplacements remplissent le disque.
Surveillance de la santé des emplacements
Certaines fonctionnalités de surveillance sont également incluses. Deux colonnes dans pg_replication_slots sont pertinentes. Le plus critique est wal_status
. Si cette colonne est reserved
, alors l'emplacement pointe vers des données dans max_wal_size
; s'il est extended
alors il a dépassé max_wal_size
, mais est toujours protégé soit par wal_keep_size
ou max_slot_wal_keep_size
(y compris lorsque max_slot_wal_keep_size
est zéro). L'un ou l'autre état est bon et normal. Cependant, lorsqu'un emplacement dépasse la limite, il devient d'abord unreserved
, ce qui signifie qu'il est en danger imminent, mais qu'il peut encore récupérer s'il est assez rapide. Enfin, le statut devient lost
lorsque les fichiers WAL ont été supprimés et qu'aucune récupération n'est possible.
L'autre colonne est safe_wal_size
:il montre le nombre d'octets de WAL qui peuvent être écrits avant que cet emplacement ne risque d'avoir des fichiers WAL supprimés. Nous vous suggérons de surveiller de près cette colonne dans votre système de surveillance et d'émettre des alertes lorsqu'elle devient faible. Zéro ou négatif signifie que votre réplique sera morte dès qu'un point de contrôle se produira :
SELECT slot_name, active, wal_status, safe_wal_size FROM pg_catalog.pg_replication_slots;
Nous pensons que cette nouvelle fonctionnalité rend la maintenance des répliques plus facile et plus robuste ; espérons que nous ne verrons plus de catastrophes avec une baisse de production à cause de ces problèmes.
(Remarque :safe_wal_size
a été introduit dans 13beta3, alors assurez-vous de consulter la documentation à jour, ou vous verrez min_safe_lsn
Au lieu. Ignorez cela.)
Merci
Un merci spécial à Kyotaro Horiguchi pour avoir travaillé à la résolution de ce problème. Plusieurs critiques ont approfondi ce sujet, parmi lesquels je tiens à remercier tout particulièrement Masahiko Sawada, Fujii Masao, Jehan-Guillaume de Rorthais et Amit Kapila (sans ordre particulier).