Vaut-il la peine d'exécuter VACUUM sur une table qui ne reçoit que des INSERT?

19

Dans une conférence sur re: Invent en 2015, AWS a mentionné que le vide devrait être exécuté non seulement après les mises à jour ou les suppressions, mais également après les insertions. Voici la partie pertinente de l'exposé:

http://www.youtube.com/watch?v=tZXp19q8RFo&t=16m2s

Soi-disant, il y a un nettoyage qui doit être fait sur les blocs même s'ils n'ont reçu que des insertions et ce nettoyage peut être effectué soit la première fois qu'un bloc est sélectionné (ralentissement des lectures) ou pendant le vide. Est-ce vrai et si oui, quel nettoyage doit être fait exactement?

foobar0100
la source

Réponses:

15

tl; dr: le premier processus qui lit les données après leur validation définit des bits de conseil. Cela salira la page, créant une activité d'écriture. L'autre chose VACUUM(mais pas les autres commandes) consiste à marquer la page comme visible, le cas échéant. VACUUMdevra finalement frapper la table pour geler les tuples.

Le travail qui doit être fait après un insert n'est pas vraiment un nettoyage, du moins pas dans le sens des autres travaux VACUUM. Avant d'entrer dans les détails, notez que cette réponse est basée sur le code 9.6 actuel (non publié) et j'ignore les effets de la réplication en streaming, même si cela peut avoir un effet sur la visibilité.

En raison de MVCC , chaque fois que Postgres évalue si un tuple doit être visible pour une requête, il doit déterminer si la transaction qui a créé le tuple (enregistrée dans le champ caché xmin) a été validée, ainsi que d'autres critères. Ce contrôle est coûteux, donc dès que l'on sait qu'une transaction est visible pour toutes les transactions actuellement ouvertes, un "bit de conseil" est défini sur l'en-tête du tuple pour l'indiquer. Le réglage de ce bit salit la page, ce qui signifie qu'il devra être écrit sur le disque. Cela peut être très déroutant si la prochaine commande pour lire les données est SELECTcelle qui crée soudainement beaucoup de trafic d'écriture. L'exécution d'un VACUUMaprès la validation de l'insertion évitera cela. Une autre distinction importante est queVACUUMaffichera TOUJOURS des tuples sur une page (tant qu'il aura le verrou de nettoyage sur la page), mais la plupart des autres commandes n'indiqueront que si la transaction d'insertion validée avant le démarrage de la commande.

Un point important sur l'écriture de tous ces bits de conseil est qu'il VACUUMpeut être limité (et l'autovacuum est limité par défaut). Les autres commandes ne sont pas limitées et généreront des données sales le plus rapidement possible.

VACUUMest la seule méthode pour marquer les pages comme étant entièrement visibles, ce qui est une considération de performance importante pour certaines opérations (notamment les analyses d'index uniquement). Si vous faites un grand insert, il est très probable qu'il y ait beaucoup de pages avec rien mais des tuples nouvellement insérés. VACUUMpeut potentiellement marquer ces pages comme visibles, mais uniquement si la transaction en cours d'exécution la plus ancienne au VACUUMdémarrage était plus récente que la transaction qui a inséré les données .

En raison du fonctionnement de MVCC, les tuples qui ont été insérés il y a plus de ~ 2 milliards de transactions doivent être marqués comme " gelés ". Par défaut, autovacuum interviendra pour le faire toutes les 200 millions de transactions. L'exécution d'un vide manuel avec vacuum_freeze_min_age défini sur 0 après une insertion en vrac peut aider à réduire l'impact de cela. Plus agressivement, vous pouvez courir VACUUM FREEZEsur la table après l'insertion. Cela "réinitialiserait l'horloge" lorsque le prochain arrêt sur gel se produirait.

Si vous souhaitez connaître les détails spécifiques, jetez un oeil à l' HEAPTUPLE_LIVEaffaire après l'appel à l' HeapTupleSatisfiesVacuum()intérieur lazy_scan_heap(). Voir aussi HeapTupleSatisfiesVacuum()lui-même et le comparer à HeapTupleSatisfiesMVCC().

Il y a deux autres présentations qui pourraient être intéressantes. La première vidéo est disponible sur http://www.pgcon.org/2015/schedule/events/829.en.html , tandis que la seconde (qui je pense était un peu meilleure) sur https://www.youtube. com / watch? v = L8nErzxPJjQ

Jim Nasby
la source
Ceci est très intéressant, et explique également certaines pages encrassées dans certains EXPLAIN (ANALYZE, BUFFERS) outputs. But, if I understand things correctly, some of the hint bits (at least * COMMITTED` et *INVALID) peuvent (pourraient) déjà être définies par le COMMITou ROLLBACK, non?
dezso
3
COMMIT et ROLLBACK ne touchent pas réellement les pages de données, donc non, ces commandes en particulier ne pourraient jamais faire allusion. Une commande DML peut toujours définir les statuts d'indication xmin et xmax, soit pour les tuples marqués par d'autres transactions, soit potentiellement pour les tuples marqués par la transaction en cours.
Jim Nasby