PostgreSQL 19 : la commande REPACK native met fin au casse-tête du bloat de tables
Si vous gérez des bases de données PostgreSQL en production, vous connaissez probablement cette situation inconfortable : une table qui grossit indéfiniment, des outils tiers qui inspirent une confiance limitée, et VACUUM FULL qui est hors de question sur un système en ligne. PostgreSQL 19 apporte enfin une réponse native à ce problème vieux comme le moteur lui-même.
Le problème du bloat : un héritage de l'architecture MVCC
PostgreSQL repose sur un mécanisme de contrôle de concurrence multiversion (MVCC). Concrètement, chaque modification d'une ligne laisse l'ancienne version en place dans le heap — la structure de stockage physique de la table — pour permettre aux transactions en cours de lire une version cohérente des données.
VACUUM passe régulièrement pour identifier ces tuples obsolètes et les marquer comme réutilisables. Mais attention : marquer comme réutilisable ne signifie pas restituer l'espace au système d'exploitation. En pratique, une table PostgreSQL ne rétrécit jamais d'elle-même. Sur des systèmes à forte volumétrie, on se retrouve avec des tables de plusieurs centaines de gigaoctets dont une part significative est du vide inutilisable.
Ce phénomène, appelé bloat, dégrade les performances (plus de pages à parcourir pour les scans séquentiels), gonfle artificiellement les sauvegardes et peut saturer les disques.
Les solutions existantes : chacune avec ses compromis
Jusqu'à présent, les DBA avaient le choix entre deux familles de solutions, toutes imparfaites.
Les commandes natives VACUUM FULL et CLUSTER réécrivent physiquement la table et restituent l'espace. Mais elles posent un verrou exclusif (ACCESS EXCLUSIVE) pour toute la durée de l'opération. Sur une table d'1 To, cela peut représenter plusieurs heures d'indisponibilité totale — incompatible avec tout SLA de production sérieux.
Les outils tiers pg_repack et pg_squeeze contournent ce problème en s'appuyant sur le logical decoding pour réécrire la table avec un verrouillage minimal. Certaines équipes les exécutent même en tâche planifiée pour maintenir les tables à leur taille optimale en permanence. Mais ces outils opèrent en dehors du moteur core, sans bénéficier de ses garanties de sécurité internes. Shaun Thomas, dans son article publié sur le blog pgEdge le 29 mai 2026, mentionne avoir lui-même traité des tickets de support liés à des corruptions causées par pg_repack. De quoi rendre les équipes les plus prudentes réticentes à s'y fier en production.
La commande REPACK native dans PostgreSQL 19 : le meilleur des deux mondes
PostgreSQL 19 intègre directement cette fonctionnalité dans le moteur avec la nouvelle commande REPACK. Elle reprend le principe des outils tiers — réécriture de la table avec verrouillage minimal — mais avec toutes les garanties de sécurité du core engine.
L'option clé est CONCURRENTLY :
REPACK TABLE ma_grosse_table CONCURRENTLY;
En mode concurrent, la commande évite le verrou exclusif prolongé qui rendait VACUUM FULL si problématique. Les lectures et écritures peuvent continuer pendant la majeure partie de l'opération. Seule une fenêtre très courte nécessite un verrou, comparable à celle d'une création d'index concurrente.
Un bénéfice collatéral pour VACUUM FULL et CLUSTER
La bonne nouvelle va plus loin : PostgreSQL 19 refactorise également VACUUM FULL et CLUSTER pour qu'ils utilisent la même infrastructure interne que REPACK. Toutes les routes vers la compaction de table convergent désormais vers le même code, ce qui améliore la maintenabilité du moteur et garantit une cohérence comportementale entre les différentes approches.
Ce que ça change concrètement pour vos projets PHP/Symfony
Pour les applications web développées avec Symfony et Doctrine, les tables les plus susceptibles de souffrir de bloat sont généralement :
- Les tables de logs applicatifs ou d'événements avec de nombreuses insertions/suppressions
- Les tables de sessions ou de cache persisté en base
- Les tables de file d'attente (pattern outbox, jobs asynchrones)
- Toute table avec des mises à jour fréquentes sur de nombreuses colonnes
Avec PostgreSQL 19, vous pourrez planifier un REPACK ... CONCURRENTLY sur ces tables sans craindre d'impacter vos utilisateurs, et sans dépendre d'une extension tierce à maintenir à jour à chaque montée de version de PostgreSQL.
Concrètement, une tâche de maintenance planifiée pourrait ressembler à :
-- Maintenance nocturne sans interruption de service
REPACK TABLE app_events CONCURRENTLY;
REPACK TABLE messenger_messages CONCURRENTLY;
REPACK TABLE sessions CONCURRENTLY;
Conclusion
L'arrivée de REPACK dans PostgreSQL 19 représente une évolution significative pour tous ceux qui administrent des bases de données en production. Ce n'est pas une révolution spectaculaire, mais c'est le type d'amélioration pragmatique qui simplifie concrètement le quotidien des DBA et des équipes de développement.
Pouvoir compacter une table sans interruption de service, avec les garanties du moteur core, c'est exactement ce qu'il manquait à PostgreSQL depuis des années. Les outils tiers comme pg_repack ont rendu un service précieux à la communauté, mais leur place naturelle est désormais dans l'histoire du moteur plutôt que dans vos scripts de maintenance.
📖 Source originale : Looking Forward to Postgres 19: The New REPACK Command par Shaun Thomas, publié sur le blog pgEdge le 29 mai 2026.