Statistiques cumulatives dans PostgreSQL 18

Dans PostgreSQL 18, le sous-système de statistiques et de supervision bénéficie d’une refonte majeure: statistiques cumulatives étendues, nouvelle visibilité I/O par backend, possibilité pour les extensions d’exporter / importer / ajuster les statistiques, et améliorations des contrôles GUC ainsi que du comportement de cache et de snapshot. Ces changements ouvrent de nouvelles perspectives pour l’analyse de performance, la simulation inter-environnements et une meilleure intégration avec les extensions. Dans cet article, j’explore les nouveautés, les points d’attention, les paramètres GUC, ainsi que la manière dont les auteurs d’extensions peuvent exploiter la nouvelle API en C.
Introduction & motivation
Les statistiques (au sens large: compteurs de supervision, métriques I/O, et estimations pour le planificateur / optimiseur) sont au cœur à la fois de l’optimisation de performance et des décisions internes de PostgreSQL. Des statistiques transparentes, fiables et manipulables permettent entre autres aux DBAs d’adresser directement l’efficacité de PostgreSQL, et donnent aux «extensions» la possibilité d’améliorer l’expérience utilisateur.
Cela dit, le système historique de statistiques de PostgreSQL n’était pas exempt de frictions: capacité limitée à réinitialiser les statistiques des relations, métriques exprimées dans des unités pas toujours alignées avec les besoins utilisateurs, absence d’API C pour utiliser le moteur de statistiques cumulatives de PostgreSQL. PostgreSQL 18 répond directement à ces préoccupations.
Voici un résumé des améliorations clés.
Un avertissement sur les statistiques
Bien que les statistiques soient extrêmement utiles, leur collecte peut consommer du temps et des ressources. PostgreSQL 18 introduit un point important: avec l’élargissement du spectre des métriques collectables, la taille maximale de la table de hachage a été augmentée. Gardez cela à l’esprit, surtout si vous concevez des systèmes à grande échelle avec des architectures «un ensemble de tables par client»: on a constaté que la limite de 1 Go pouvait être atteinte avec quelques millions de tables.
Quoi de neuf dans PostgreSQL 18 et les « stats »
Voici les nouvelles fonctionnalités majeures ou les améliorations concernant les statistiques et la supervision.
De manière générale, pg_stat_io rapporte désormais l’activité I/O en octets plutôt qu’en pages, ce qui est plus pratique pour l’analyse. De plus, les statistiques WAL y ont été déplacées depuis pg_stat_wal
, offrant ainsi une vue unique et complète.
Mises à jour
pg_upgrade est désormais capable de conserver les statistiques de l’optimiseur, supprimant la nécessité de relancer un ANALYZE
complet pour obtenir de bons plans de requêtes après une montée de version: une avancée très attendue pour les grandes bases!
Attention toutefois: les statistiques personnalisées ajoutées par une extension ainsi que celles créées avec CREATE STATISTICS ne sont pas conservées.
Vous voudrez sûrement examiner les nouvelles options de vacuumdb (--missing-stats-only
) pour n’analyser que ce qui est nécessaire.
Dans la même veine, l’option --[no-]statistics
a été ajoutée à pg_dump, pg_dumpall, et pg_restore.
Maintenance
Il est désormais plus simple d’évaluer l’effort de maintenance sur les objets, puisque le temps total passé dans les opérations VACUUM et ANALYZE (y compris
automatiques) est rapporté dans pg_stat_all_tables et ses variantes.
Un nouveau GUC à ne pas oublier: track_cost_delay_timing. Il collecte le temps passé à dormir (suite aux opérations retardées) pour VACUUM
et ANALYZE
. Très intéressant, mais comme les autres GUC track_io*
, il multiplie les appels à l’horloge système, ce qui peut provoquer un impact sévère sur certaines plateformes. Toujours vérifier avec un outil comme pg_test_timing pour s’assurer que votre système peut le supporter!
Plus de questions sur l’activité du checkpointer grâce à pg_stat_checkpointer. Le nouvel attribut num_done
indique le nombre de checkpoints terminés. Vous pouvez aussi savoir quel type de buffers a été écrit grâce à slru_written
, et buffers_written
qui ne concerne désormais que shared_buffers
: auparavant, journal et vue n’affichaient pas les mêmes totaux, car un compteur SLRU
existait dans un cas mais pas dans l’autre.
Analyse
Envie d’en savoir plus sur l’I/O traité par un backend (PID) ? Appelez pg_stat_get_backend_io(int) et vous obtiendrez une sortie similaire à la vue pg_stat_io
, mais pour ce processus. Pour les stats WAL de ce PID: utilisez pg_stat_get_backend_wal(int).
De nouveaux attributs parallel_workers_to_launch
et parallel_workers_launched
apparaissent dans pg_stat_database. Le ratio permet de savoir si nous avons assez de slots pour les workers parallèles.
Changements intéressants dans pg_stat_statements: plus de requêtes seront regroupées sous le même identifiant. Par exemple, les
motifs IN (1,2,3, ...)
n’utiliseront que la première et la dernière constante. Un changement plus contre-intuitif concerne le nom de table utilisé dans une requête: seul le nom est pris en compte, pas le schéma ni l’OID de relation. Cela permet de suivre les tables supprimées ou recréées, mais cela peut aussi regrouper les stats de tables sans lien ayant simplement le même nom. Pour séparer les stats de tables homonymes, il faudra les aliaser dans les requêtes (FROM my.table mt, other.table ot
)…
Enfin, ajouts à pg_backend_memory_contexts avec path
(pour récupérer parent/enfant) et type
pour distinguer les contextes AllocSet
, Generation
, Slab
et Bump
… Et au fait, que sont Slab
et Bump
? Pas documentés ; il faut lire les en-têtes des fichiers C ici. Ils existent pour optimiser l’allocation, la réallocation et la réinitialisation mémoire selon les usages attendus. Par exemple, Slab
est défini comme un «MemoryContext implementation designed for cases where large numbers of equally-sized objects can be allocated and freed efficiently with minimal memory wastage and fragmentation».
Ah, non, encore une dernière: wal_buffers_full
a été ajouté à pg_stat_statements
pour permettre un meilleur réglage de wal_buffers
.
Réplication
De meilleures informations apparaissent désormais pour la gestion des conflits en réplication logique grâce à de nouveaux attributs dans pg_stat_subscription_stats. En référence, cet extrait du commit liste les attributs introduits:
confl_insert_exists
: nombre de fois où une insertion de ligne a violé une contrainte unique NOT DEFERRABLE.confl_update_origin_differs
: nombre de fois où une mise à jour a été faite sur une ligne déjà modifiée par une autre origine.confl_update_exists
: nombre de fois où la valeur mise à jour d’une ligne viole une contrainte unique NOT DEFERRABLE.confl_update_missing
: nombre de fois où le tuple à mettre à jour est manquant.confl_delete_origin_differs
: nombre de fois où une suppression a été effectuée sur une ligne déjà modifiée par une autre origine.confl_delete_missing
: nombre de fois où le tuple à supprimer est manquant.
Avancé
Un nouveau jeu de fonctions permet désormais de gérer les statistiques de relations et d’attributs (relpages
, avg_width
, etc.). Cela offre la possibilité d’exporter, importer et ajuster les stats à volonté, afin de répliquer le comportement du planificateur hors production, de maintenir des stats corrigées, et plus encore.
Mon préféré pour les auteurs d’extensions: la nouvelle API C de stats
L’une des évolutions les plus enthousiasmantes est ce que PostgreSQL 18 ouvre aux auteurs d’extensions.
Cette petite ligne au bas de la section E.1.3.9 Modules est celle qui nous intéresse :
Allow extensions to use the server’s cumulative statistics API (Michael Paquier)
Jusqu’ici, la manipulation des statistiques était réservée à l’interne ; désormais, une API officielle et structurée est disponible pour construire (ou envelopper) autour.
Le message de commit est bien rédigé et couvre l’essentiel des nouveautés. Un sous-ensemble des options est détaillé dans la documentation. Cependant, il faut encore plonger dans le code source pour en savoir plus ; en particulier, il vaut la peine de regarder l’extension injection points
(fournie avec PostgreSQL) qui utilise cette nouvelle API.
Pour aller plus loin sur la manière dont une extension peut exploiter ces nouvelles capacités, vous pourrez bientôt découvrir PACS (PostgreSQL Advanced Cumulative Statistics) sur Codeberg : mon projet qui propose une bibliothèque de wrappers et des utilitaires autour des nouvelles APIs de statistiques de PostgreSQL 18.
En attendant, la présentation que j’ai donnée à FOSDEM 2025 explore ce sujet plus en détail.