Que se passe-t-il dans le point de contrôle PostgreSQL?

22

Voici une partie de mon journal de point de contrôle:

2014-03-26 11:51:29.341 CDT,,,18682,,532854fc.48fa,4985,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 15047 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 30 recycled; write=68.980 s, sync=1.542 s, total=70.548 s; sync files=925, longest=0.216 s, average=0.001 s",,,,,,,,,""
2014-03-26 11:56:05.430 CDT,,,18682,,532854fc.48fa,4987,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 16774 buffers (1.6%); 0 transaction log file(s) added, 0 removed, 31 recycled; write=72.542 s, sync=17.164 s, total=89.733 s; sync files=885, longest=3.812 s, average=0.019 s",,,,,,,,,""
2014-03-26 12:01:21.650 CDT,,,18682,,532854fc.48fa,4989,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 14436 buffers (1.4%); 0 transaction log file(s) added, 0 removed, 33 recycled; write=122.350 s, sync=5.212 s, total=127.676 s; sync files=924, longest=3.740 s, average=0.005 s",,,,,,,,,""
2014-03-26 12:06:25.028 CDT,,,18682,,532854fc.48fa,4991,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 13277 buffers (1.3%); 0 transaction log file(s) added, 0 removed, 29 recycled; write=126.217 s, sync=5.733 s, total=131.991 s; sync files=894, longest=1.859 s, average=0.006 s",,,,,,,,,""
2014-03-26 12:10:41.958 CDT,,,18682,,532854fc.48fa,4993,,2014-03-18 09:15:24 CDT,,0,LOG,00000,"checkpoint complete: wrote 20765 buffers (2.0%); 0 transaction log file(s) added, 0 removed, 28 recycled; write=88.015 s, sync=10.818 s, total=98.872 s; sync files=881, longest=2.690 s, average=0.012 s",,,,,,,,,""

J'ai remarqué que parfois notre base de données est très lente - vous pouvez voir un très grand nombre de requêtes normalement courtes bloquées beaucoup plus longtemps que maintenant. Cela arrive régulièrement sans coupable clair.

Question: Checkpoint pourrait-il provoquer cela? Que se passe-t-il dans la phase "sync" du point de contrôle?

Konrad Garus
la source

Réponses:

32

Pendant son fonctionnement, PostgreSQL enregistre les modifications apportées aux fichiers journaux des transactions, mais il ne les enregistre pas immédiatement dans les tables de base de données réelles. Il conserve généralement les modifications en mémoire et les renvoie de la mémoire lorsqu'elles sont demandées, à moins que la RAM ne commence à être pleine et qu'elle ne les écrive.

Cela signifie que s'il se bloque, les tables sur disque ne seront pas à jour. Il doit relire les journaux de transactions, en appliquant les modifications aux tables sur disque, avant de pouvoir démarrer la sauvegarde. Cela peut prendre un certain temps pour une grande base de données chargée.

Pour cette raison, et afin que les journaux de transactions ne continuent pas de croître indéfiniment, PostgreSQL effectue périodiquement un point de contrôle où il s'assure que la base de données est dans un état propre. Il vide toutes les modifications en attente sur le disque et recycle les journaux de transactions qui étaient utilisés pour conserver un enregistrement de récupération après incident des modifications.

Cette vidange se déroule en deux phases:

  • Tamponné write()s de sale shared_bufferssur les tables; et
  • fsync() des fichiers affectés pour vous assurer que les modifications atteignent vraiment le disque

Ces deux éléments peuvent augmenter la charge d'E / S disque. Les conflits causés par ces écritures peuvent ralentir les lectures et ralentir également le vidage des segments WAL requis pour valider les transactions.

Cela a été un défi de longue date, mais cela empire à mesure que nous voyons des systèmes avec de plus en plus de RAM afin qu'ils puissent tamponner plus de données et prendre plus de temps pour les écrire. Il y a une discussion entre les communautés Linux et PostgreSQL sur la façon de gérer cela en ce moment, comme discuté dans cet article LWN.net . (LWN.net ne pourra pas continuer à écrire ce genre de travail formidable si les gens ne s'abonnent pas. Je suis abonné et partage ce lien parce qu'il est utile et informatif. Veuillez envisager de vous abonner si vous voulez en voir plus genre de chose.)

La principale chose que vous pouvez faire pour réduire l'impact des points de contrôle à l'heure actuelle est de répartir l'activité des points de contrôle en augmentant de checkpoint_completion_targetsorte que davantage de données aient été écrites au moment de l'arrivée du point de contrôle final. Cela a cependant un coût - si vous mettez à jour une page (disons) dix fois, elle peut être écrite sur le disque plusieurs fois avant le point de contrôle avec une cible d'achèvement élevée, même si elle n'a été strictement écrite qu'une seule fois pour des raisons de sécurité. Un objectif d'achèvement plus élevé permet des modèles d'E / S plus fluides, mais une surcharge d'E / S globale.

L'autre chose que vous pouvez faire pour aider est de dire à votre système d'exploitation de commencer immédiatement à écrire des données lors de l'écriture en mémoire tampon. C'est comme le côté noyau de la configuration checkpoint_completion_targetet a un compromis similaire. Voir la documentation vm linux , en particulier dirty_background_bytes, dirty_background_ratio, dirty_expire_centisecs.

Craig Ringer
la source
L'écriture est étalée sur une longue période et je ne pense pas que cela cause des problèmes. Qu'en est-il de la synchronisation, est-ce par hasard un type d'opération stop-the-world?
Konrad Garus
@KonradGarus La synchronisation ne devrait pas être un type d'opération stop-the-world, mais elle l'est souvent de toute façon. Lisez l'article que j'ai lié à ci-dessus, c'est un résumé très opportun et utile des problèmes, bien que d'un point de vue assez technique. La version courte est "fsync () sous Linux a tendance à complètement supprimer les performances de toutes les E / S concurrentes avec fsync ()". Vous pouvez atténuer cela avec les options de réglage répertoriées ci-dessus, afin de réduire la quantité qui doit être éliminée par un fsync.
Craig Ringer
1

Flushing les tampons du système de fichiers OS sales causés par un dépassement dirty_bytesou dirty_ratio est une opération de blocage de premier plan!

Les paramètres de noyau dirty_bytes, dirty_background_bytes, dirty_ratio , dirty_background_ratioet le dirty_centisecscontrôle de rinçage des tampons de système de fichiers OS sales sur le disque. dirty_bytesest le seuil en octets, dirty_ratioest le seuil en tant que rapport de la mémoire totale. dirty_background_byteset dirty_background_ratiosont des seuils similaires, mais le vidage se produit en arrière-plan et ne bloque pas les autres opérations de lecture / écriture tant qu'il n'est pas terminé. dirty_centisecsest le nombre de centisecondes qui peuvent s'écouler avant qu'un vidage ne soit lancé.

Récemment, les paramètres par défaut de ces paramètres ont été réduits sous Linux, car la taille de la mémoire pour les machines modernes a considérablement augmenté. Même des ratios de 5 et 10% pour dirty_background_ratioet dirty_ratiosur une machine de 256 Go peuvent inonder un système d'E / S.

Il est difficile de régler dirty_background_bytesou dirty_background_ratiode commencer à vider les tampons sales en arrière-plan. Heureusement, vous pouvez régler ces paramètres sans avoir à arrêter PostgreSQL ou l'hôte en faisant écho aux nouvelles valeurs dans les fichiers appropriés:

$ sudo echo [int value of bytes] > /proc/sys/vm/dirty_background_bytes

par exemple, pour définir le nombre d'octets sales pour déclencher un vidage d'arrière-plan. Si vous utilisez une carte RAID à batterie, à condensateur ou à mémoire flash (vous ne voulez garder vos données en cas d'accident, non?) Commencer parréglagedirty_background_bytesà 1/2 la taille demémoire tampon de cache d'écriture etdirty_bytesaux 3/4 de cette taille. Surveillez votre profil d'E / S avec iostats et si vous rencontrez toujours des problèmes de latence, cela signifie que la charge d'écriture de votre base de données écrase toujours les vidages du cache de tampon de fichiers. Baissez les valeurs jusqu'à ce que la latence s'améliore ou envisagez de mettre à niveau votre sous-système d'E / S. Les cartes et SSD FusionIO sont deux possibilités pour un débit d'E / S extrême.

Bonne chance!

bobl
la source
Votre commentaire sur les données "sales" est un point pertinent pour la lenteur. Essentiellement: plus le rapport sale est important, plus le tampon est alloué pour les données sales avant le rinçage. Ainsi, minimiser les délais de vidage signifie augmenter le tampon sale ou augmenter la durée pendant laquelle les données sales peuvent rester en mémoire.
Peter Teoh