<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Le blog Dalibo</title>
		<description>DALIBO est le spécialiste français de PostgreSQL. Nous proposons du support, de la formation et du conseil depuis 2005.</description>
		<link>https://blog.dalibo.com/</link>
		<atom:link href="https://blog.dalibo.com/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>Sortie de PostgreSQL 18.4, 17.10, 16.14, 15.18 et 14.23</title>
				<description>&lt;p&gt;&lt;em&gt;Lyon, le 15 mai 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Le PostgreSQL Global Development Group a publié le 14 mai &lt;strong&gt;&lt;a href=&quot;https://www.postgresql.org/about/news/postgresql-184-1710-1614-1518-and-1423-released-3297/&quot;&gt;une mise à
jour&lt;/a&gt;&lt;/strong&gt;
pour toutes les versions supportées de PostgreSQL, c’est-à-dire les versions
18.4, 17.10, 16.14, 15.18, 14.23. Cette mise à jour corrige 11 vulnérabilités de
sécurité et une soixantaine de bugs.&lt;/p&gt;

&lt;p&gt;Pour la liste complète, voir les &lt;a href=&quot;https://www.postgresql.org/docs/release/&quot;&gt;Notes de version&lt;/a&gt;.&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;p&gt;&lt;img src=&quot;/img/202605_annonce_release.png&quot; alt=&quot;visuel annonce&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;annonce-de-fin-de-vie-de-postgresql-14&quot;&gt;Annonce de fin de vie de PostgreSQL 14&lt;/h3&gt;

&lt;p&gt;PostgreSQL 14 ne recevra plus de mises à jour après le 12 novembre 2026. Si vous
utilisez PostgreSQL 14 en production, nous vous conseillons de planifier la
migration vers une version plus récente et supportée. Voir la politique de
versionnement pour plus de détails.&lt;/p&gt;

&lt;h3 id=&quot;vulnérabilités-de-sécurité&quot;&gt;Vulnérabilités de sécurité&lt;/h3&gt;

&lt;h4 id=&quot;cve-2026-6472-la-commande-create-type-de-postgresql-ne-vérifie-pas-le-droit-create-de-sur-tous-les-schemas&quot;&gt;CVE-2026-6472: La commande CREATE TYPE de PostgreSQL ne vérifie pas le droit CREATE de sur tous les schemas&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 5.4&lt;br /&gt;
Versions vulnérables : 14 - 18.&lt;br /&gt;
Une faille d’autorisation dans la commande CREATE TYPE de PostgreSQL permet au
créateur d’un objet de détourner d’autres requêtes qui utilisent &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search_path&lt;/code&gt;
pour rechercher des types définis par l’utilisateur, y compris les types définis
par des extensions. En d’autres termes, la victime exécutera des fonctions SQL
arbitraires choisies par l’attaquant. Les versions antérieures à PostgreSQL
18.4, 17.10, 16.14, 15.18 et 14.23 sont concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6473-postgresql-sous-dimensionne-les-allocations-à-cause-dun-débordement-dentier&quot;&gt;CVE-2026-6473: PostgreSQL sous-dimensionne les allocations à cause d’un débordement d’entier&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 8.8&lt;br /&gt;
Versions vulnérables : 14 - 18.&lt;br /&gt;
Le débordement d’entier, dans plusieurs fonctionnalitées de PostgreSQL, autorise
une application à forcer le serveur à sous-dimensionner une allocation et à
écrire hors limites. Cela entraîne une erreur de segmentation. Les versions
antérieures à PostgreSQL 18.4, 17.10, 16.14, 15.18 et 14.23 sont concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6474-la-fonction-postgresql-timeofday-peut-divulguer-des-parties-de-la-mémoire-du-serveur&quot;&gt;CVE-2026-6474: La fonction PostgreSQL timeofday() peut divulguer des parties de la mémoire du serveur&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 4.3&lt;br /&gt;
Versions vulnérables : 14 - 18.&lt;br /&gt;
Une chaîne de caractères spécifique utilisée dans la fonction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;timeofday()&lt;/code&gt; de
PostgreSQL permet à un attaquant d’extraire des portions de la mémoire du
serveur, via des fuseaux horaires spécialement conçus. Les versions antérieures
à PostgreSQL 18.4, 17.10, 16.14, 15.18 et 14.23 sont concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6475-les-commandes-pg_basebackup-et-pg_rewind-de-postgresql-peuvent-écraser-des-fichiers-sans-lien-avec-le-choix-du-superutilisateur&quot;&gt;CVE-2026-6475: Les commandes pg_basebackup et pg_rewind de PostgreSQL peuvent écraser des fichiers sans lien avec le choix du superutilisateur&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 8.8&lt;br /&gt;
Versions vulnérables : 14 - 18.&lt;br /&gt;
Le suivi des liens symboliques dans le format brut de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_basebackup&lt;/code&gt; et dans
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_rewind&lt;/code&gt; permet à un superutilisateur d’origine de réécrire des fichiers
locaux, par exemple &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/lib/postgres/.bashrc&lt;/code&gt;, qui détournent le compte du
système d’exploitation. Le fait est que le démarrage du serveur après ces
commandes implique une confiance implicite envers le superutilisateur d’origine,
en raison de fonctionnalités telles que shared_preload_libraries. Par
conséquent, l’attaque n’a de conséquences pratiques que si des actions sont
faites entre l’exécution de ces commandes et le démarrage du serveur, comme par
exemple le déplacement des fichiers vers une autre machine virtuelle ou la
création d’un instantané de la machine virtuelle. Les versions antérieures à
PostgreSQL 18.4, 17.10, 16.14, 15.18 et 14.23 sont concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6476-la-fonction-pg_createsubscriber-de-postgresql-permet-une-injection-sql-via-le-nom-de-labonnement&quot;&gt;CVE-2026-6476: La fonction pg_createsubscriber de PostgreSQL permet une injection SQL via le nom de l’abonnement&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 7.2&lt;br /&gt;
Versions vulnérables : 17 - 18.&lt;br /&gt;
Une faille d’injection SQL dans la fonction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_createsubscriber&lt;/code&gt; de PostgreSQL
permet à un attaquant disposant des droits &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_create_subscription&lt;/code&gt; d’exécuter du
code SQL arbitraire en tant que superutilisateur. L’attaque se produit lors de
la prochaine exécution de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_createsubscriber&lt;/code&gt;. Parmi les versions majeures 17 et
18, les versions mineures antérieures à PostgreSQL 18.4 et 17.10 sont
concernées. Les versions antérieures à PostgreSQL 17 ne sont pas concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6477-les-fonctions-lo_-de-la-bibliothèque-libpq-de-postgresql-permettent-au-superutilisateur-du-serveur-de-réécrire-la-mémoire-de-la-pile-du-client&quot;&gt;CVE-2026-6477: Les fonctions lo_* de la bibliothèque libpq de PostgreSQL permettent au superutilisateur du serveur de réécrire la mémoire de la pile du client&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 8.8&lt;br /&gt;
Supported, Vulnerable Versions: 14 - 18.&lt;br /&gt;
L’utilisation de la fonction intrinsèquement dangereuse comme &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PQfn(...,
result_is_int=0, ...)&lt;/code&gt; dans les fonctions &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lo_export()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lo_read()&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lo_lseek64()&lt;/code&gt;,
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lo_tell64()&lt;/code&gt; de la libpq autorise un superutilisateur de réécrire la pile
mémoire d’un client. C’est notamment le cas pour pg_dump  et psql qui utilisent
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lo_read()&lt;/code&gt;. Les versions antérieures à PostgreSQL 18.4, 17.10, 16.14, 15.18 et
14.23 sont concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6478--postgresql-divulgue-des-mots-de-passe-hachés-en-md5&quot;&gt;CVE-2026-6478:  PostgreSQL divulgue des mots de passe hachés en MD5&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 6.5&lt;br /&gt;
Versions vulnérables : 14 - 18.&lt;br /&gt;
Un canal de synchronisation caché dans la comparaison des mots de passe hachés
MD5 dans l’authentification PostgreSQL permet à un attaquant de récupérer
suffisament d’informations d’utilisateur pour s’authentifier. 
Cela n’affecte pas les mots de passe hachés en scram-sha-256, qui sont la valeur
par défaut dans toutes les versions supportées. Cependant, les bases de données
en version 13 existantes peuvent contenir des mots de passe hachés en MD5. Les
versions antérieures à PostgreSQL 18.4, 17.10, 16.14, 15.18 et 14.23 sont
concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6479-linitialisation-sslgss-de-postgresql-provoque-un-déni-de-service-via-une-récursion-non-contrôlée&quot;&gt;CVE-2026-6479: L’initialisation SSL/GSS de PostgreSQL provoque un déni de service, via une récursion non contrôlée.&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 7.5&lt;br /&gt;
Versions vulnérables : 14 - 18.&lt;br /&gt;
Une récursion incontrôlée dans la négociation SSL et GSS de PostgreSQL permet à
un attaquant capable de se connecter à un socket AF_UNIX de PostgreSQL,
d’obtenir un déni de service. Si SSL et GSS sont désactivés, un attaquant peut
réaliser la même opération en accédant à un socket TCP de PostgreSQL. Les
versions antérieures à PostgreSQL 18.4, 17.10, 16.14, 15.18 et 14.23 sont
concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6575-la-fonction-pg_restore_attribute_stats-de-postgresql-accepte-des-valeurs-qui-entraînent-une-lecture-au-delà-de-la-fin-du-tableau-de-statistiques-lors-de-la-planification-de-la-requête&quot;&gt;CVE-2026-6575: La fonction pg_restore_attribute_stats de PostgreSQL accepte des valeurs qui entraînent une lecture au-delà de la fin du tableau de statistiques lors de la planification de la requête.&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 4.3&lt;br /&gt;
Versions vulnérables : 18.&lt;br /&gt;
Une vulnérabilité de lecture du tampon dans la fonction
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_restore_attribute_stats()&lt;/code&gt; de PostgreSQL accepte des valeurs de tableau de
longueur non adéquat, ce qui provoque une lecture au-delà de la fin d’un tableau
lors de la planification de la requête. Ceci permet à un responsable de table de
déduire des valeurs en mémoire au-delà de cette fin de tableau. Ce problème
affecte les versions majeures antérieures à PostgreSQL 18 et 18.4. Les versions
antérieures à PostgreSQL 18 ne sont pas concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6637-le-module-postgresql-refint-permet-le-dépassement-de-tampon-de-pile-et-linjection-sql&quot;&gt;CVE-2026-6637: Le module PostgreSQL refint permet le dépassement de tampon de pile et l’injection SQL.&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 8.8&lt;br /&gt;
Versions vulnérables : 14 - 18.&lt;br /&gt;
Un dépassement de tampon de la pile dans le module &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;refint&lt;/code&gt; de PostgreSQL permet à
un utilisateur de base de données non privilégié d’exécuter du code arbitraire
en tant qu’utilisateur du système d’exploitation exécutant la base de données. 
Une autre attaque est possible si l’application déclare une colonne utilisateur
comme clé primaire en cascade. Une injection SQL est possible en mettant à jour
la valeur de la clé primaire. Le code SQL est exécuté en tant qu’utilisateur de
la base de données effectuant la mise à jour de la clé primaire. 
Les versions de PostgreSQL antérieures à 18.4, 17.10, 16.14, 15.18 et 14.23 sont concernées.&lt;/p&gt;

&lt;h4 id=&quot;cve-2026-6638-postgresql-refresh-publication-autorise-linjection-sql-via-le-nom-de-la-table&quot;&gt;CVE-2026-6638: PostgreSQL REFRESH PUBLICATION autorise l’injection SQL via le nom de la table.&lt;/h4&gt;
&lt;p&gt;CVSS v3.1 Base Score: 3.7&lt;br /&gt;
Versions vulnérables : 16 - 18.&lt;br /&gt;
Une injection SQL dans la réplication logique de PostgreSQL (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALTER SUBSCRIPTION
... REFRESH PUBLICATION&lt;/code&gt;) permet au créateur d’une table abonnée d’exécuter du
code SQL arbitraire avec les identifiants de publication de l’abonnement.
L’attaque prend effet lors du prochain appel à &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;REFRESH PUBLICATION&lt;/code&gt;. Les versions
majeures 16, 17 et 18, ainsi que les versions mineures antérieures à PostgreSQL
18.4, 17.10 et 16.14, sont concernées. Les versions antérieures à PostgreSQL 16
ne sont pas affectées.&lt;/p&gt;

&lt;h3 id=&quot;correctifs-et-améliorations&quot;&gt;Correctifs et améliorations&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Correction d’un problème pouvant entraîner des résultats erronés lors de
l’utilisation d’une collation non déterministe sur un index unique.&lt;/li&gt;
  &lt;li&gt;Auparavant, une clé étrangère définie comme &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DEFERRABLE INITIALLY DEFERRED&lt;/code&gt; se
comportait comme si elle était &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT DEFERRABLE&lt;/code&gt; après avoir été mise en état
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT ENFORCED&lt;/code&gt;, puis revenue à l’état &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ENFORCED&lt;/code&gt;. C’est maintenant corrigé. 
Si vous avez une clé étrangère présentant ce problème, vous pouvez le résoudre
après avoir installé cette mise à jour en la positionnant comme &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT ENFORCED&lt;/code&gt;
puis &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ENFORCED&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Amélioration du planificateur lors du nettoyage de partitions.&lt;/li&gt;
  &lt;li&gt;Correctif sur les self-join pour mieux gérer les clauses qui ne portent que
sur des colonnes de type booléen.&lt;/li&gt;
  &lt;li&gt;Plusieurs corrections concernent les colonnes générées virtuellement,
notamment pour garantir que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INSERT ... ON CONFLICT&lt;/code&gt; fonctionne lorsque
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXCLUDED&lt;/code&gt; fait référence à une colonne générée virtuellement.&lt;/li&gt;
  &lt;li&gt;Un échec de sérialisation est signalé lorsque &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MERGE&lt;/code&gt; rencontre une ligne mis
à jour simultanément avec les &lt;a href=&quot;https://www.postgresql.org/docs/current/transaction-iso.html&quot;&gt;modes d’isolation&lt;/a&gt; 
« repeatable » ou « serializable ».&lt;/li&gt;
  &lt;li&gt;Correction de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CREATE TABLE ... LIKE ... INCLUDING STATISTICS&lt;/code&gt; pour les cas où la
table source comportait une ou plusieurs colonnes supprimées.&lt;/li&gt;
  &lt;li&gt;Correction de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WITHOUT OVERLAPS&lt;/code&gt; pour autoriser l’utilisation de domaines.&lt;/li&gt;
  &lt;li&gt;Interdiction de faire d’un type composite un membre de lui-même via un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;multirange&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Correction de résultats parfois incorrects lorsque &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;array_agg(anyarray)&lt;/code&gt; s’exécute en
parallèle.&lt;/li&gt;
  &lt;li&gt;Le bloat n’est plus conservé lors d’une restauration à partir d’une sauvegarde incrémentale.&lt;/li&gt;
  &lt;li&gt;La promotion d’une instance standby n’est plus bloquée par un processus de
synchronisation des slots de réplication logique.&lt;/li&gt;
  &lt;li&gt;La colonne &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pid&lt;/code&gt; de la vue système &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_aios&lt;/code&gt; affiche &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NULL&lt;/code&gt; au lieu de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt; lorsqu’une
entrée n’a pas de processus associé.&lt;/li&gt;
  &lt;li&gt;Correction des cas où &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_stat_replication&lt;/code&gt; affiche un lag &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NULL&lt;/code&gt; même lorsque
la réplication est active.&lt;/li&gt;
  &lt;li&gt;L’affichage des variables d’alias &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JOIN&lt;/code&gt; utilisées dans &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GROUP BY&lt;/code&gt; est maintenant correct.&lt;/li&gt;
  &lt;li&gt;Si le processus de démarrage échoue, les autres processus enfants sont
correctement arrêtés avant de stopper le postmaster.&lt;/li&gt;
  &lt;li&gt;Correction d’une race condition qui pouvait entraîner une instance stanby,
suivant une instance primaire dans une version mineure antérieure, à entrer
dans une boucle infinie de plantage et de redémarrage.&lt;/li&gt;
  &lt;li&gt;Empêche l’attente infine lors de l’arrêt d’un processus &lt;em&gt;walsender&lt;/em&gt; lorsque la
réplication logique publie activement des données.&lt;/li&gt;
  &lt;li&gt;Les modifications apportées aux &lt;em&gt;free space map&lt;/em&gt; des tables sont conservées
pendant un recovery. Cela pourrait améliorer les performances d’une instance
standby après sa promotion.&lt;/li&gt;
  &lt;li&gt;Correction de divers bugs dans le code de décompression des sauvegardes
utilisé dans &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_basebackup&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_verifybackup&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Garantie que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_dumpall&lt;/code&gt; n’oublie pas de GRANT sur des rôles qui auraient été
donnés par un ROLE dont l’OID serait manquant.. Un message d’avertissement est
affiché sur la source du dump est PostgreSQL 16 ou une version ultérieure.&lt;/li&gt;
  &lt;li&gt;Correction de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_upgrade&lt;/code&gt; pour qu’il utilise la bonne version du protocole
lors de la connexion à d’anciens serveurs sources.&lt;/li&gt;
  &lt;li&gt;Correction de la sortie dans &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_overexplain&lt;/code&gt; lors de l’utilisation de l’option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RANGE_TABLE&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Correction d’un bug dans &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgres_fdw&lt;/code&gt; causé par le nettoyage prématuré d’une
connexion ayant échoué.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;mettre-à-jour&quot;&gt;Mettre à jour&lt;/h3&gt;

&lt;p&gt;Toutes les mises à jour de PostgreSQL sont cumulatives.
Pour appliquer la mise à jour, comme pour les autres versions mineures,
les utilisateurs n’ont pas besoin de sauvegarder
et recharger leur base de données, ni d’utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_upgrade&lt;/code&gt;. 
Vous pouvez simplement arrêter PostgreSQL et mettre à jour ses binaires.&lt;/p&gt;

&lt;p&gt;Les utilisateurs ayant sauté une version mineure ou plus peuvent avoir besoin de
réaliser d’autres opérations post-mise à jour. Voir les &lt;a href=&quot;https://www.postgresql.org/docs/release/&quot;&gt;Notes de version&lt;/a&gt; pour
les détails.&lt;/p&gt;

&lt;h3 id=&quot;liens&quot;&gt;Liens&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/download/&quot;&gt;Téléchargements&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/docs/release/&quot;&gt;Notes de version&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/support/security/&quot;&gt;Sécurité&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/support/versioning/&quot;&gt;Politique de versionnement&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/account/submitbug/&quot;&gt;Soumettez un bug&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/about/donate/&quot;&gt;Donnez&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Fri, 15 May 2026 00:00:00 -0500</pubDate>
				<link>https://blog.dalibo.com/2026/05/15/postgresql_release_18.4.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/05/15/postgresql_release_18.4.html</guid>
			</item>
		
			<item>
				<title>Manuels Dalibo : leur dernière mise à jour intègre PostgreSQL 18</title>
				<description>&lt;p&gt;&lt;em&gt;Saint-Étienne, le 15 mai 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Voici les manuels Dalibo dans leur &lt;strong&gt;dernière version&lt;/strong&gt;, qui intègre les nouveautés de PostgreSQL 18. Toujours en libre accès sous format PDF, ePub, html et slides !&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;h3 id=&quot;rappels-utiles&quot;&gt;Rappels utiles&lt;/h3&gt;

&lt;p&gt;Revue des cours, nouveaux TP et quiz, correctifs… La mise à jour des manuels est assurée nos DBA, par ailleurs formateurs et consultants.&lt;/p&gt;

&lt;p&gt;Découvrez le sommaire des formations Dalibo, le détail des différents modules et les liens vers les slides &lt;a href=&quot;https://dali.bo/menu&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Si vous notez des éléments qui demandent à être clarifiés, précisés, corrigés, vous pouvez nous écrire à &lt;a href=&quot;mailto:formation@dalibo.com&quot;&gt;formation@dalibo.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Les manuels sont publiés sous la licence &lt;a href=&quot;https://creativecommons.org/licenses/by-nc-sa/4.0/deed.fr&quot;&gt;CC BY-NC-SA&lt;/a&gt; qui autorise l’utilisation &lt;strong&gt;non commerciale&lt;/strong&gt;, le partage dans les mêmes conditions et la modification, à condition de créditer Dalibo.&lt;/p&gt;

&lt;div style=&quot;margin-bottom: 20px;&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;les-manuels&quot;&gt;Les manuels&lt;/h3&gt;

&lt;p&gt;IMPORTANT : leur dernière version intègre les nouveautés de &lt;strong&gt;PostgreSQL 18&lt;/strong&gt;.&lt;/p&gt;

&lt;h4 id=&quot;administration&quot;&gt;Administration&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://dali.bo/dba1&quot;&gt;DBA1&lt;/a&gt; - Administration PostgreSQL : &lt;a href=&quot;https://dali.bo/dba1_pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/dba1_epub&quot;&gt;ePub&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/dba1_html&quot;&gt;html&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://dali.bo/dba2&quot;&gt;DBA2&lt;/a&gt; - Administration PostgreSQL Avancée : &lt;a href=&quot;https://dali.bo/dba2_pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/dba2_epub&quot;&gt;ePub&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/dba2_html&quot;&gt;html&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://dali.bo/dba3&quot;&gt;DBA3&lt;/a&gt; - Sauvegarde et Réplication avec PostgreSQL : &lt;a href=&quot;https://dali.bo/dba3_pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/dba3_epub&quot;&gt;ePub&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/dba3_html&quot;&gt;html&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://dali.bo/hapat&quot;&gt;HAPAT&lt;/a&gt; - Haute disponibilité avec PostgreSQL : &lt;a href=&quot;https://dali.bo/hapat_pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/hapat_epub&quot;&gt;ePub&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/hapat_html&quot;&gt;html&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;développement&quot;&gt;Développement&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://dali.bo/devpg&quot;&gt;DEVPG&lt;/a&gt; - Développer avec SQL : &lt;a href=&quot;https://dali.bo/devpg_pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/devpg_epub&quot;&gt;ePub&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/devpg_html&quot;&gt;html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;performances&quot;&gt;Performances&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://dali.bo/perf1&quot;&gt;PERF1&lt;/a&gt; - PostgreSQL Performances : &lt;a href=&quot;https://dali.bo/perf1_pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/perf1_epub&quot;&gt;ePub&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/perf1_html&quot;&gt;html&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://dali.bo/perf2&quot;&gt;PERF2&lt;/a&gt; - Indexation et SQL Avancés : &lt;a href=&quot;https://dali.bo/perf2_pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/perf2_epub&quot;&gt;ePub&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/perf2_html&quot;&gt;html&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;transition-vers-postgresql&quot;&gt;Transition vers PostgreSQL&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://dali.bo/dbaadm&quot;&gt;DBAADM&lt;/a&gt; - Administration PostgreSQL pour DBA expérientés : &lt;a href=&quot;https://dali.bo/dbaadm_pdf&quot;&gt;PDF&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/dbaadm_epub&quot;&gt;ePub&lt;/a&gt;, &lt;a href=&quot;https://dali.bo/dbaadm_html&quot;&gt;html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;le-privilège-des-stagiaires&quot;&gt;Le privilège des stagiaires&lt;/h3&gt;

&lt;p&gt;Ces manuels ne sont pas commercialisés. Cependant, en vous inscrivant à une &lt;a href=&quot;https://dali.bo/manuels_formation&quot;&gt;formation Dalibo&lt;/a&gt;, vous recevrez un code pour commander gratuitement l’impression et la livraison à domicile de deux manuels de votre choix.&lt;/p&gt;

&lt;p&gt;Nous rappelons d’ailleurs que nos DBA donnent ces formations en intra ou inter-entreprises, en présentiel dans nos locaux parisiens, ou à distance.&lt;/p&gt;

&lt;p&gt;En attendant, bonne lecture à vous !&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Des questions, des remarques ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Écrivez-nous à &lt;a href=&quot;mailto:formation@dalibo.com&quot;&gt;formation@dalibo.com&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
				<pubDate>Fri, 15 May 2026 00:00:00 -0500</pubDate>
				<link>https://blog.dalibo.com/2026/05/15/maj_manuels.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/05/15/maj_manuels.html</guid>
			</item>
		
			<item>
				<title>Plongez dans le monde de CloudNativePG #11 - Exécuter des ordres SQL après la création d'un Cluster</title>
				<description>&lt;p&gt;&lt;em&gt;Lyon, le 11 mars 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CloudNativePG&lt;/strong&gt; ou comment embarquer un éléphant sur un porte-conteneurs !&lt;/p&gt;

&lt;p&gt;Jusqu’à présent, nous avons abordé différents sujets liés à l’administration
d’instances PostgreSQL avec CloudNativePG.
On nous a récemment posé une question concernant les possibilités pour exécuter
des requêtes dès la création d’un Cluster. Regardons ce que propose l’opérateur.&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;p&gt;&lt;img src=&quot;/img/cnpg-header.png&quot; alt=&quot;moteur&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;le-besoin&quot;&gt;Le besoin&lt;/h3&gt;

&lt;p&gt;Le besoin rencontré est le suivant : les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Clusters&lt;/code&gt; vont tous être créés sur le même
modèle (RAM, CPU, etc) et seront utilisés par une application pour laquelle nous
possédons déjà le modèle de données.&lt;/p&gt;

&lt;p&gt;Nous voulons donc créer toute la structure d’une nouvelle base dès la création du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt;.
Une fois notre YAML appliqué, l’instance et la base de données seront
directement utilisables par nos développeurs qui pourront connecter l’application
dessus.&lt;/p&gt;

&lt;h3 id=&quot;les-trois-sections-postinit&quot;&gt;Les trois sections postInit&lt;/h3&gt;

&lt;p&gt;L’opérateur donne la possibilité d’exécuter des ordres SQL lors de la phase de
&lt;em&gt;bootstrap&lt;/em&gt; d’un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; via les sections &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postInitXXX&lt;/code&gt;. Elles sont localisées
dans la section &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initdb&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Il en existe trois :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;pour la base &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgres&lt;/code&gt; : la section &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postInit&lt;/code&gt;;&lt;/li&gt;
  &lt;li&gt;pour la base &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;template1&lt;/code&gt; : la section &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postInitTemplate&lt;/code&gt;;&lt;/li&gt;
  &lt;li&gt;pour la base &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app&lt;/code&gt;  : la section &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postInitApplication&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Les ordres SQL, indiqués dans l’une ou l’autre des sections, s’exécuteront dans
la base correspondante dès la fin de la création de l’instance.&lt;/p&gt;

&lt;p&gt;Ces ordres là sont lancés par le rôle &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgres&lt;/code&gt;, qui est &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SUPERUSER&lt;/code&gt;.
Attention donc aux requêtes que vous lancerez et à qui vous laisserez la possibilité
d’utiliser ces sections.&lt;/p&gt;

&lt;h3 id=&quot;exemple-dun-ordre-sql&quot;&gt;Exemple d’un ordre SQL&lt;/h3&gt;

&lt;p&gt;Reprenons notre exemple où le modèle de données doit être créé dans une base de
données, disons &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mybase&lt;/code&gt; qui sera utilisée par la future application. 
Prenons le cas simple où nous souhaitons créer une table avec la définition suivante :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employes&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;serial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nom&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paye&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;numeric&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Cet ordre doit être rajouté à la section
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec.bootstrap.initdb.postInitApplicationSQL&lt;/code&gt; pour que l’ordre en question soit
exécuté dans la base de données applicative &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mybase&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;postgresql.cnpg.io/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Cluster&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cluster-sql&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;instances&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;storage&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;1Gi&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;bootstrap&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;initdb&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mybase&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mybase&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;postInitApplicationSQL&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; 
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt;  &lt;span class=&quot;s&quot;&gt;CREATE TABLE employes (id serial, nom text, paye numeric(8,2)) ;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; peut-être créé avec la commande &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl create&lt;/code&gt; ou &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl
apply&lt;/code&gt;. On vous laisse créer cette ressource et vérifier que la table existe
bien 😏.&lt;/p&gt;

&lt;p&gt;Pour des raisons d’organisation et de lisibilité il est pertinent 
de séparer correctement chaque action SQL. Pour une dizaine d’ordres SQL, cette
solution est tout à fait viable, mais au-delà, cela deviendrait très compliqué à
utiliser et à maintenir.&lt;/p&gt;

&lt;p&gt;Une autre solution est proposée par l’opérateur avec l’utilisation de ressources
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; ou &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Secret&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;exemple-via-configmap&quot;&gt;Exemple via ConfigMap&lt;/h3&gt;

&lt;p&gt;Pour le test, nous n’utiliserons que des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt;. Nous vous laissons le
loisir de tester les étapes qui suivent avec un objet &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Secret&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;L’un des intérêts d’un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; est de regrouper des requêtes SQL et de
les appeler au besoin lors des créations de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt;. Ce sont des ressources
qui peuvent être réutilisées.&lt;/p&gt;

&lt;p&gt;Un autre avantage est de pouvoir mettre un grand nombre d’ordres SQL sans que
cela ne rende la définition du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; illisible.
Voici les quelques étapes à suivre pour mettre en place cette méthode.&lt;/p&gt;

&lt;p&gt;Tout d’abord, écrire la définition du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt;. La section &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data&lt;/code&gt; contient un
champ &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sql&lt;/code&gt; qui, vous le verrez, sera utilisé plus tard lors de la création du
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt;. Le mot &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sql&lt;/code&gt; a été choisi pour qu’il corresponde sémantiquement au
contenu, mais vous pouvez l’appeler comme vous voulez.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;s&quot;&gt;$ cat cm.yaml&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;v1&lt;/span&gt; 
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ConfigMap&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; 
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;my-configmap&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;sql&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt; 
    &lt;span class=&quot;s&quot;&gt;CREATE TABLE liste (i integer) ; &lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;INSERT INTO liste SELECT i from generate_series(1,100) as i ;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Créer cette ressource dans le &lt;em&gt;cluster&lt;/em&gt; Kubernetes.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;kubectl apply -f cm.yaml
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Penchons-nous maintenant sur la création de la ressource &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; afin
d’utiliser ce &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ce qui nous intéresse le plus est la partie &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postInitApplicationSQLRefs&lt;/code&gt;.
Vous l’aurez remarqué, il s’agit ici d’une liste de références à des objets, un
ou des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; donc, et non plus une liste d’ordres SQL. 
Le nom de la section change également, avec l’ajout du suffixe &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Refs&lt;/code&gt;. Vous
l’aurez compris il existe là aussi trois nouveaux paramètres correspondant aux
trois sections précédentes&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postInitSQLRefs&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postInitTemplateSQLRefs&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postInitApplicationSQLRefs&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reprenons l’exemple de notre &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;bootstrap&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;initdb&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mybase&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;owner&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;mybase&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;postInitApplicationSQLRefs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;configMapRefs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;my-configmap&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;sql&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Il est nécessaire de cibler le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; avec l’attribut name et la clé présente
dans celui-ci, en l’occurrence : &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sql&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Créons ce Cluster et vérifions que la table et les données sont bien présentes.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;kubectl cnpg psql cluster-cm -- -d mybase -c &quot;select count(*) from liste&quot;
 count 
-------
   100
(1 row)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Bien évidement, dans votre cas, le contenu de la &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; sera bien plus conséquent.&lt;/p&gt;

&lt;h3 id=&quot;et-si-une-erreur-survient-&quot;&gt;Et si une erreur survient ?&lt;/h3&gt;

&lt;p&gt;L’erreur est humaine. Un administrateur aurait tendance à dire que
&lt;a href=&quot;https://fr.wikipedia.org/wiki/PEBKAC&quot;&gt;PEBKAC&lt;/a&gt; … bref, regardons ce qu’il se
passe si une erreur survient lors de l’exécution des ordres SQL.&lt;/p&gt;

&lt;p&gt;Modifions une requête SQL (suppression de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;INTO&lt;/code&gt;) de notre &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; et
appliquons cette modification. Vous voyez au passage, qu’il n’y a pas de
vérification du contenu d’un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;v1&lt;/span&gt; 
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ConfigMap&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; 
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;my-configmap&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;sql&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt; 
    &lt;span class=&quot;s&quot;&gt;CREATE TABLE configmaps (i integer) ; &lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;INSERT configmaps SELECT i from generate_series(1,100) as i ; &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pour le test, il faut détruire et recréer le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; existant. Et oui,
rappelez-vous que les opérations ne sont exécutées que lors du &lt;em&gt;bootstrap&lt;/em&gt;,
c’est à dire lors de la création du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Une fois que ceci est fait, vous devriez voir, en lançant la commande
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl get pod&lt;/code&gt;, un certain nombre de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt; avec le statut &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Error&lt;/code&gt;.
L’opérateur essaye plusieurs fois de créer les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initdb&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
cluster-cm-1-initdb-k8qrx   0/1     Error     0          11m
cluster-cm-1-initdb-ksb9l   0/1     Error     0          13m
cluster-cm-1-initdb-p4t4p   0/1     Error     0          8m22s
cluster-cm-1-initdb-sdkmn   0/1     Error     0          13m
cluster-cm-1-initdb-tb87p   0/1     Error     0          2m58s
cluster-cm-1-initdb-wvn7h   0/1     Error     0          12m
cluster-cm-1-initdb-zqvd2   0/1     Error     0          13m
cluster-sql-1               1/1     Running   0          33m
cluster-sql-2               1/1     Running   0          32m
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Il y a vraisemblablement une erreur. Regardons maintenant dans les traces
du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt;, quelle en est la cause. Il est possible de cibler un conteneur
spécifique avec l’option &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-c&lt;/code&gt; de la commande &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl logs&lt;/code&gt;. Utilisons là pour
cibler le conteneur &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initdb&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;kubectl logs cluster-cm-1-initdb-zqvd2 -c initdb | jq

&lt;/span&gt;&lt;span class=&quot;c&quot;&gt;...
&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;
{
  &quot;level&quot;: &quot;info&quot;,
  &quot;ts&quot;: &quot;2026-03-09T09:30:09.800909636Z&quot;,
  &quot;logger&quot;: &quot;pg_ctl&quot;,
  &quot;msg&quot;: &quot;server stopped&quot;,
  &quot;pipe&quot;: &quot;stdout&quot;,
  &quot;logging_pod&quot;: &quot;cluster-cm-1-initdb&quot;
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;L’instance PostgreSQL est arrêtée par l’opérateur. Pourquoi ?&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;level&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2026-03-09T09:30:09.801691453Z&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;msg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Error while bootstrapping data directory&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;logging_pod&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cluster-cm-1-initdb&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;error&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;while configuring new instance: could not execute post init application SQL refs: could not execute queries: ERROR: syntax error at or near &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;liste&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; (SQLSTATE 42601)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;stacktrace&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;github.com/cloudnative-pg/machinery/...
  ...
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;L’ordre SQL renvoyant une erreur, l’opérateur le capte et arrête le processus &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initdb&lt;/code&gt; du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt;.
Le cluster reste dans l’état &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Setting up Primary&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;kubectl get cluster
NAME          AGE   INSTANCES   READY   STATUS                     PRIMARY
cluster-cm    15m   1                   Setting up primary     
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Si le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; est corrigé assez rapidement, la boucle de réconciliation de
CloudNativePG entrant en jeu, lors de la nouvelle tentative de création d’un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initdb&lt;/code&gt;, la &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; est relue et la création du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; se fait sans encombre.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;kubectl get pod

NAME                        READY   STATUS      RESTARTS   AGE
cluster-cm-1                1/1     Running     0          27s
cluster-cm-1-initdb-5z9d5   0/1     Error       0          58s
cluster-cm-1-initdb-6kb9n   0/1     Error       0          77s
cluster-cm-1-initdb-cxmkh   0/1     Completed   0          34s
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt;d’&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;initdb&lt;/code&gt; finit par être &lt;em&gt;Completed&lt;/em&gt; et le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt; de l’instance
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cluster-cm-1&lt;/code&gt; est créé.&lt;/p&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Nous venons de voir comment demander à l’opérateur d’exécuter un certain nombre
d’ordres SQL pour nous.&lt;/p&gt;

&lt;p&gt;Vous avez deux possibilités, soit en indiquant des ordres SQL directement, soit
en faisant référence à une ressource &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; ou &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Secret&lt;/code&gt;. Cette dernière est
d’autant plus pratique qu’elle vous permet de réutiliser des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; pour la
création de vos &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Clusters&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Grâce à cette fonctionnalité de l’opérateur, vous n’avez plus besoin d’utiliser
un autre outil pour déclencher la création de schémas, de tables ou d’autres
ressources dans vos bases de données.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Des questions, des commentaires ? &lt;a href=&quot;mailto:pierrick.chovelon@dalibo.com?subject=[Commentaire-Blog] CloudNativePG&quot;&gt;Écrivez-nous !&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
</description>
				<pubDate>Wed, 11 Mar 2026 00:00:00 -0500</pubDate>
				<link>https://blog.dalibo.com/2026/03/11/cnpg-11.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/03/11/cnpg-11.html</guid>
			</item>
		
			<item>
				<title>Nouveau workshop dédié à CloudNativePG™</title>
				<description>&lt;p&gt;&lt;em&gt;Saint-Étienne, le 6 mars 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dalibo vous propose un tout nouveau workshop, testé l’année dernière : celui dédié à l’opérateur &lt;strong&gt;CloudNativePG&lt;/strong&gt; ! Il aura lieu le 8 avril à Paris.&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;p&gt;&lt;img src=&quot;/img/portrait_pierrick-nb.png&quot; alt=&quot;Pierrick Chovelon&quot; style=&quot;float: right; padding:10px; width:150px;&quot; /&gt;&lt;/p&gt;
&lt;h3 id=&quot;découvrir-cloudnativepg&quot;&gt;Découvrir CloudNativePG&lt;/h3&gt;

&lt;p&gt;Initialement développé par Enterprise DB, &lt;a href=&quot;https://cloudnative-pg.io/&quot;&gt;CloudNativePG&lt;/a&gt; est désormais l’un des projets communautaires de la &lt;a href=&quot;https://www.linuxfoundation.org/projects&quot;&gt;Fondation Linux&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Le but de ce workshop est de présenter cet opérateur, ce qu’il permet de faire, ses particularités… voici un aperçu des sujets qui seront abordés lors de cette journée de travail et d’échanges :&lt;/p&gt;

&lt;div style=&quot;float: left; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;ul&gt;
    &lt;li&gt;Installation&lt;/li&gt;
    &lt;li&gt;Montées de version&lt;/li&gt;
    &lt;li&gt;Custom Resource Definitions&lt;/li&gt;
    &lt;li&gt;Gestion des images&lt;/li&gt;
    &lt;li&gt;Gestion des traces&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;float: left; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;ul&gt;
    &lt;li&gt;Streaming Replication / Log Shipping&lt;/li&gt;
    &lt;li&gt;Plugin Barman Cloud&lt;/li&gt;
    &lt;li&gt;PITR&lt;/li&gt;
    &lt;li&gt;Rolling Update&lt;/li&gt;
    &lt;li&gt;Etc.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;Les inscriptions sont ouvertes pour le &lt;strong&gt;8 avril 2026&lt;/strong&gt;. Attention, il y a peu de places : premier arrivé, premier servi !&lt;/p&gt;

&lt;h4 id=&quot;liens-utiles&quot;&gt;Liens utiles&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://cloudnative-pg.io/docs/1.28/&quot;&gt;documentation officielle&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.dali.bo/202501_cloudnativepg&quot;&gt;Premier aperçu&lt;/a&gt; (article)&lt;/li&gt;
  &lt;li&gt;conférence &lt;em&gt;« CloudNativePG, ou comment embarquer un éléphant sur Kubernetes »&lt;/em&gt;, ci-dessous :&lt;/li&gt;
&lt;/ul&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/fHcrJl66KZk?si=eJ7hRIg83BO9rr8P&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen=&quot;&quot;&gt;
  &lt;/iframe&gt;

&lt;h3 id=&quot;rappel-général&quot;&gt;Rappel général&lt;/h3&gt;

&lt;p&gt;Chaque workshop se déroule en présentiel, sur une journée, dans nos locaux parisiens.&lt;/p&gt;

&lt;p&gt;Au programme : des démos, travaux pratiques et sessions de questions-réponses afin de vous familiariser avec le fonctionnement des logiciels.&lt;/p&gt;

&lt;p&gt;L’inscription est gratuite, dans la limite d’une personne par organisation. Le coût du déjeuner est cependant pris en charge par les employeurs.&lt;/p&gt;

&lt;p&gt;Pour toute question et réservation, écrivez-nous à &lt;strong&gt;&lt;a href=&quot;mailto:workshop@dalibo.com&quot;&gt;workshop@dalibo.com&lt;/a&gt;&lt;/strong&gt;.
Un email de confirmation vous sera envoyé.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Des questions, des commentaires ? 
&lt;a href=&quot;mailto:communication@dalibo.com?subject=[BLOG-commentaire] à propos du workshop CNPG&quot;&gt;Écrivez-nous !&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
				<pubDate>Fri, 06 Mar 2026 00:00:00 -0600</pubDate>
				<link>https://blog.dalibo.com/2026/03/06/workshop_cnpg.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/03/06/workshop_cnpg.html</guid>
			</item>
		
			<item>
				<title>Sortie de PostgreSQL 18.3, 17.9, 16.13, 15.17 et 14.22</title>
				<description>&lt;p&gt;&lt;em&gt;Strasbourg, le 26 février 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Le PostgreSQL Global Development Group a publié le 26 février
&lt;a href=&quot;https://www.postgresql.org/about/news/postgresql-183-179-1613-1517-and-1422-released-3246/&quot;&gt;une mise à jour mineure&lt;/a&gt;
pour toutes les versions supportées de PostgreSQL, c’est-à-dire les versions 18.3, 17.9, 16.1, 15.17 et 14.22.&lt;/p&gt;

&lt;p&gt;Il s’agit d’une &lt;strong&gt;mise à jour hors cycle corrigeant plusieurs régressions&lt;/strong&gt; signalées après la mise à jour précédente. Pour la liste complète, voir les &lt;a href=&quot;https://www.postgresql.org/docs/release/&quot;&gt;Notes de version&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Voici notre traduction.&lt;/em&gt;&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;p&gt;&lt;img src=&quot;/img/20260226_annonce_release.png&quot; alt=&quot;visuel annonce&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;correctifs-et-améliorations&quot;&gt;Correctifs et améliorations&lt;/h3&gt;

&lt;p&gt;Cette mise à jour corrige plusieurs bugs rapportés depuis la mise à jour précédente. Les problèmes ci-dessous concernent PostgreSQL 18. Certains peuvent également affecter d’autres versions supportées de PostgreSQL.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;!-- Fix issue where a standby would halt and return an error &quot;could not access status of transaction&quot; --&gt;
    &lt;p&gt;Correction d’un problème où un serveur standby s’arrêtait et renvoyait une erreur “could not access status of transaction”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;!-- Fix error where the substring() function would raise an error &quot;invalid byte sequence for encoding&quot; on non-ASCII text values if the source of that value is a database column. This was due to a change introduced for the fix to CVE-2026-2006. --&gt;
    &lt;p&gt;Correction d’une erreur où la fonction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;substring()&lt;/code&gt; levait une erreur “invalid byte sequence for encoding” sur des valeurs textuelles non-ASCII quand la source était une colonne de base de données. Cela était la conséquence d’un changement pour corriger la &lt;a href=&quot;https://www.postgresql.org/support/security/CVE-2026-2006/&quot;&gt;CVE-2026-2006&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;!-- Fix for the strict_word_similarity function in pg_trgm that could lead to incorrect output or crashes. This was due to an oversight in the fix for CVE-2026-2007 --&gt;
    &lt;p&gt;Correction de la fonction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;strict_word_similarity&lt;/code&gt; dans &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_trgm&lt;/code&gt;, qui pouvait entraîner des résultats incorrects ou des plantages. Cela était dû à un oubli dans la correction de &lt;a href=&quot;https://www.postgresql.org/support/security/CVE-2026-2007/&quot;&gt;CVE-2026-2007&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;!-- Fix function volatility for json_strip_nulls() and jsonb_strip_nulls() to be immutable, like previous releases, allowing for them to be used in indexes. If you previously upgraded to PostgreSQL 18.0 through 18.2, see the additional steps in the &quot;Updating&quot; section. --&gt;
    &lt;p&gt;Correction de la volatilité des fonctions &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json_strip_nulls()&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jsonb_strip_nulls()&lt;/code&gt;, redevenues immutables comme dans les versions précédentes, permettant leur utilisation dans les index. Si vous avez précédemment mis à jour vers PostgreSQL 18.0 à 18.2, consultez les étapes supplémentaires dans la section « Mettre à jour ».&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;!--Fix for NOT NULL tests in LATERAL UNION ALL subquery that could lead to wrong query output.--&gt;
    &lt;p&gt;Correction de tests &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT NULL&lt;/code&gt; dans les sous-requêtes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;LATERAL UNION ALL&lt;/code&gt;, pouvant produire des résultats erronés.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;!-- Avoid NOT NULL constraints from generating name conflicts with user-written constraints. --&gt;
    &lt;p&gt;Éviter que les contraintes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT NULL&lt;/code&gt; ne génèrent des noms en conflit avec les contraintes définies par l’utilisateur.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;!-- Fix pg_stat_get_backend_wait_event() and pg_stat_get_backend_wait_event_type() to report values for auxiliary processes, similar to pg_stat_activity. --&gt;
    &lt;p&gt;Correction de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_stat_get_backend_wait_event()&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_stat_get_backend_wait_event_type()&lt;/code&gt; pour afficher les valeurs des processus auxiliaires, comme dans &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_stat_activity&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;!-- Fix casting a composite-type variable to a domain type when returning its value from a PL/pgSQL function. --&gt;
    &lt;p&gt;Correction du transtypage d’une variable de type composite vers un type domaine en retour d’une fonction PL/pgSQL.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;!-- Fix the hstore binary input function to avoid crashes on input with duplicate keys. --&gt;
    &lt;p&gt;Correction de la fonction d’entrée binaire de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hstore&lt;/code&gt; pour éviter des plantages lors de l’entrée de clés dupliquées.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;mettre-à-jour&quot;&gt;Mettre à jour&lt;/h3&gt;

&lt;p&gt;Toutes les mises à jour de PostgreSQL sont cumulatives.
Pour appliquer la mise à jour, comme pour les autres versions mineures,
les utilisateurs n’ont pas besoin de sauvegarder
et recharger leur base de données, ni d’utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_upgrade&lt;/code&gt;. 
Vous pouvez simplement arrêter PostgreSQL et mettre à jour ses binaires.&lt;/p&gt;

&lt;p&gt;Si vous avez précédemment mis à jour vers PostgreSQL 18.0, 18.1 ou 18.2, vous devez exécuter le SQL suivant en tant que superutilisateur PostgreSQL dans toutes vos bases de données pour rendre les fonctions &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;json_strip_nulls()&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jsonb_strip_nulls()&lt;/code&gt; immutables :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;UPDATE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pg_catalog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pg_proc&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;SET&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;provolatile&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'i'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;oid&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'3261'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'3262'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Vous devez également exécuter cette commande dans les bases de données &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;template0&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;template1&lt;/code&gt; afin que les futures bases de données créées dans votre instance PostgreSQL aient le bon paramètre de volatilité de fonction. Veuillez consulter la documentation sur les &lt;a href=&quot;https://www.postgresql.fr/docs/current/manage-ag-templatedbs.html&quot;&gt;bases de données &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;template&lt;/code&gt;&lt;/a&gt; pour plus d’informations.&lt;/p&gt;

&lt;p&gt;Les utilisateurs n’ayant pas appliqué une ou plusieurs versions peuvent avoir besoin de réaliser d’autres opérations post-mise à jour. 
Voir les &lt;a href=&quot;https://www.postgresql.org/docs/release/&quot;&gt;Notes de version&lt;/a&gt; pour les détails.&lt;/p&gt;

&lt;h3 id=&quot;liens&quot;&gt;Liens&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/download/&quot;&gt;Téléchargements&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/docs/release/&quot;&gt;Notes de version&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/support/security/&quot;&gt;Sécurité&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/support/versioning/&quot;&gt;Politique de versionnement&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/account/submitbug/&quot;&gt;Soumettez un bug&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/about/donate/&quot;&gt;Donnez&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
				<pubDate>Thu, 26 Feb 2026 00:00:00 -0600</pubDate>
				<link>https://blog.dalibo.com/2026/02/26/postgresql_release_18.3.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/02/26/postgresql_release_18.3.html</guid>
			</item>
		
			<item>
				<title>PGSession 18 : les conférences en replay</title>
				<description>&lt;p&gt;&lt;em&gt;Saint-Étienne, le 20 février 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;La journée &lt;strong&gt;Conférences de la PGSession 18&lt;/strong&gt; s’est tenue le 14 janvier dernier à Paris. Voici les liens vers les supports de présentation et les vidéos en replay.&lt;/p&gt;

&lt;!--MORE--&gt;
&lt;p&gt;&lt;img src=&quot;/img/pgsession18_michelin.jpg&quot; alt=&quot;Le retour d'expérience de Michelin&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Un grand merci aux speakers pour leurs contributions : Alain, Guillaume, Alexy, Jean-Luc, Louise, Damien, Julian, Stefan et Pierrick !&lt;/em&gt;.&lt;/p&gt;

&lt;h3 id=&quot;les-conférences-en-replay&quot;&gt;Les conférences en replay&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://dali.bo/pgsession18_conf_pg18&quot;&gt;Les nouveautés de PostgreSQL 18&lt;/a&gt;&lt;/strong&gt;, par Alain Lesage et Guillaume Armède  (Dalibo)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://dali.bo/pgsession18_conf_rex-michelin&quot;&gt;Sécuriser les bases de données : de l’audit à l’action avec les recommandations CIS&lt;/a&gt;&lt;/strong&gt;, par Alexy Mace &amp;amp; Jean-Luc Benhaim (Michelin)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://dali.bo/pgsession18_conf_statistiques&quot;&gt;Tout ou presque sur les statistiques&lt;/a&gt;&lt;/strong&gt;, par Louise Grandjonc Leinweber (Snowflake, VIP Tech)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://dali.bo/pgsession18_conf_pg-anon&quot;&gt;PostgreSQL Anonymizer 3.0 : Réplication Masquée, Anonymisation en Parallèle et bien plus encore !&lt;/a&gt;&lt;/strong&gt;, par Damien Clochard (Dalibo)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://dali.bo/pgsession18_conf_opentofu&quot;&gt;Terraformer PostgreSQL : OpenTofu + PG&lt;/a&gt;&lt;/strong&gt;, par Julian Vanden Broeck (Dalibo)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://dali.bo/pgsession18_conf_pgbackrest-patroni&quot;&gt;Patroni + pgBackRest : le duo gagnant&lt;/a&gt;&lt;/strong&gt;, par Stefan Fercot (Data Egret)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://dali.bo/pgsession18_conf_cnpg&quot;&gt;CloudNativePG, ou comment embarquer un éléphant sur Kubernetes !&lt;/a&gt;&lt;/strong&gt;, par Pierrick Chovelon (Dalibo)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://dali.bo/pgsession18_conf_chiffrement&quot;&gt;Chiffrement Transparent des Données : État de l’art et Perspectives !&lt;/a&gt;&lt;/strong&gt;, par Damien Clochard (Dalibo)&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;les-autres-liens-utiles&quot;&gt;Les autres liens utiles&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://dali.bo/pgsession18_playlist&quot;&gt;la playlist PGSession 18&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://dali.bo/pgsessions_archives&quot;&gt;les supports de présentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enfin, nous remercions chaleureusement notre prestataire &lt;strong&gt;Chapeau rouge&lt;/strong&gt; pour son accompagnement vidéo, toujours efficace et sympathique.&lt;/p&gt;

&lt;p&gt;Bon visionnage !&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;Des questions, des commentaires, des suggestions ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Écrivez-nous à &lt;a href=&quot;mailto:contact@pgsessions.com&quot;&gt;contact@pgsessions.com&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
</description>
				<pubDate>Fri, 20 Feb 2026 00:00:00 -0600</pubDate>
				<link>https://blog.dalibo.com/2026/02/20/replay_pgsession18.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/02/20/replay_pgsession18.html</guid>
			</item>
		
			<item>
				<title>Plongez dans le monde de CloudNativePG #10 - Mise à jour des Nodes et PDB</title>
				<description>&lt;p&gt;&lt;em&gt;Lyon, le 19 février 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CloudNativePG&lt;/strong&gt; ou comment embarquer un éléphant sur un porte-conteneurs !&lt;/p&gt;

&lt;p&gt;Lorsque l’on associe PostgreSQL et mise à jour, la première chose qui vient
en tête est la mise à jour des binaires PostgreSQL. Si les instances sont
déployées avec CloudNativePG, la gestion des versions de l’opérateur est
également à prendre en compte.&lt;/p&gt;

&lt;p&gt;Et Kubernetes dans tout ça ? Quel est l’impact d’une mise à jour de
l’orchestrateur sur nos instances ? Voyons tout cela dans 
ce nouvel article.&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;p&gt;&lt;img src=&quot;/img/cnpg-header.png&quot; alt=&quot;moteur&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;versions-de-kubernetes-et-drain&quot;&gt;Versions de Kubernetes et drain&lt;/h3&gt;

&lt;p&gt;Les nouvelles versions de Kubernetes sont disponibles très fréquemment. Seules
les trois dernières versions mineures sont maintenues (actuellement 1.33, 1.34
et 1.35) et leur durée de vie est assez courte, généralement autour d’un an
pour les dernières versions. Pour vous donner un exemple, la version 1.35 est
sortie en décembre 2025 et ne sera plus supportée en février 2027.&lt;/p&gt;

&lt;p&gt;Le cycle de vie est relativement rapide et il vous faudra mettre à jour vos
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nodes&lt;/code&gt; … où se trouveront vos instances PostgreSQL. Cela aura donc un impact
sur celles-ci et sur les applications qui s’y connectent.&lt;/p&gt;

&lt;p&gt;La
&lt;a href=&quot;https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/&quot;&gt;documentation&lt;/a&gt;
Kubernetes donne les grandes lignes d’une mise à jour d’un 
&lt;em&gt;cluster&lt;/em&gt; Kubernetes. Sans rentrer dans les détails, les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt; de vos instances
PostgreSQL seront nécessairement évincés pour être redéployés sur d’autres
nœuds. On parle de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt;. Une opération de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; marque le nœud comme
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unschedulable&lt;/code&gt; et évince (comprendre détruit) les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Prenons un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod&lt;/code&gt; avec deux instances.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ kubectl get cluster postgresql-prod 
NAME              AGE    INSTANCES   READY   STATUS                     PRIMARY
postgresql-prod   174m   2           2       Cluster in healthy state   postgresql-prod-1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-1&lt;/code&gt; et &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-2&lt;/code&gt; vont être supprimés des
nœuds sur lesquels ils fonctionnent pour pouvoir mettre à jour le nœud.&lt;/p&gt;

&lt;p&gt;Supprimer les &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt; PostgreSQL ? Heu comment ça ?… Peut-on au
moins avoir la main sur l’opération ? C’est ici que rentre en jeu les ressources
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PodDisruptionBudget&lt;/code&gt;, ou PDB, ressource native de Kubernetes.&lt;/p&gt;

&lt;h3 id=&quot;ressource-poddisruptionbudget&quot;&gt;Ressource PodDisruptionBudget&lt;/h3&gt;

&lt;p&gt;Un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PodDisruptionBudget&lt;/code&gt; est créé par défaut pour chaque &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt;. C’est
CloudNativePG qui se charge de cela. Cette ressource, native de Kubernetes,
indique la politique d’éviction des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt; que Kubernetes doit
respecter en cas de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Nodes&lt;/code&gt;. En l’occurrence, elle permet d’indiquer,
à Kubernetes, combien de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt;, respectant certains critères, doivent être
actifs lorsqu’une perturbation volontaire a lieu (ici la montée de version d’un
nœud).&lt;/p&gt;

&lt;p&gt;CloudNativePG crée donc une règle spécifique pour nos &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; PostgreSQL. Le
nom est suffixé de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-primary&lt;/code&gt;. Pour notre exemple, on a donc un PDB
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-primary&lt;/code&gt; dont voici la définition.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;kubectl describe pdb postgresql-prod-primary
&lt;span class=&quot;go&quot;&gt;Name:           postgresql-prod-primary
Namespace:      default
Min available:  1
Selector:       cnpg.io/cluster=postgresql-prod,cnpg.io/instanceRole=primary
Status:
    Allowed disruptions:  0
    Current:              1
    Desired:              1
    Total:                1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Passons en revue les informations disponibles :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Name&lt;/code&gt; : est le nom de cette ressource ;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Namespace&lt;/code&gt; : le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Namespace&lt;/code&gt; où elle se trouve. Le même que le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; ;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Min available&lt;/code&gt; : indique combien de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt; respectant le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Selector&lt;/code&gt; doivent
exister ;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Selector&lt;/code&gt; : la liste des &lt;em&gt;labels&lt;/em&gt; que doit avoir un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt;, il faut comprendre
 ici :
    &lt;ul&gt;
      &lt;li&gt;le primaire (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cnpg.io/instanceRole&lt;/code&gt;) du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod&lt;/code&gt;
(cnpg.io/cluster) ;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ce PDB impose donc qu’il y ait toujours une instance primaire pour le
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt;. Il suffit d’un PDB qui ne soit pas respecté pour que, par exemple,
le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt; ne puisse pas se faire.&lt;/p&gt;

&lt;h3 id=&quot;testons-cela&quot;&gt;Testons cela&lt;/h3&gt;

&lt;p&gt;Lorsqu’un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; est déclenché sur un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt;, CloudNativePG va capter cette
information et va déclencher certaines opérations.&lt;/p&gt;

&lt;p&gt;Prenons le cas du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kind-worker&lt;/code&gt; où se trouve l’instance
primaire &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-1&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;kubectl get pod &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; wide
&lt;span class=&quot;go&quot;&gt;NAME                READY   STATUS    RESTARTS   AGE    IP           NODE           
postgresql-prod-1   1/1     Running   0          3h     10.244.1.5   kind-worker    
postgresql-prod-2   1/1     Running   0          179m   10.244.2.6   kind-worker2   
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Le PDB impose qu’il y ait toujours une instance primaire disponible.
Allons-y, lançons la commande de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;kubectl drain kind-worker --delete-emptydir-data --ignore-daemonsets
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;node/kind-worker already cordoned
Warning: ignoring DaemonSet-managed Pods: kube-system/kindnet-h6hpf, kube-system/kube-proxy-swjbl
evicting pod default/postgresql-prod-1
error when evicting pods/&quot;postgresql-prod-1&quot; -n &quot;default&quot; (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/postgresql-prod-1
pod/postgresql-prod-1 evicted
node/kind-worker drained
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Une première tentative de destruction du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-1&lt;/code&gt; a été
infructueuse. Le message d’erreur &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cannot evict pod as it would violate the pod's disruption budget&lt;/code&gt; 
est plus que parlant. Quelques instants plus tard, le
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt; a bien été évincé :&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pod/postgresql-prod-1 evicted&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Entre les deux tentatives, une opération de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switchover&lt;/code&gt; a été opérée par
l’opérateur. Dans les traces du &lt;em&gt;controller&lt;/em&gt;, on peut notamment trouver cette
trace et l’explication dans le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;msg&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;level&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;ts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2026-02-16T20:12:34.942361272Z&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;msg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Current primary is running on unschedulable node, triggering a switchover&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;controller&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;cluster&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;controllerGroup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;postgresql.cnpg.io&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;controllerKind&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Cluster&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;Cluster&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;postgresql-prod&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;namespace&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;namespace&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;postgresql-prod&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;reconcileID&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;8c0bc954-a723-4aa6-95f6-2ddf4c5f173e&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;currentPrimary&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;postgresql-prod-1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;currentPrimaryNode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;kind-worker&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;targetPrimary&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;postgresql-prod-2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;targetPrimaryNode&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;kind-worker2&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;L’instance primaire fonctionne sur un nœud &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unschedulable&lt;/code&gt; (à cause du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt;).
C’est la cause du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;switchover&lt;/code&gt; déclenché par l’opérateur. Celui-ci va faire en
sorte d’élire le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt; secondaire &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-2&lt;/code&gt; comme nouveau primaire
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;targetPrimary&lt;/code&gt;). Quelques temps après, on peut voir que l’instance primaire
est désormais &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-2&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;kubectl get cluster
NAME              AGE     INSTANCES   READY   STATUS                                       PRIMARY
postgresql-prod   3h12m   2           1       Waiting for the instances to become active   postgresql-prod-2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;À cet instant, un primaire existe bien dans le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod&lt;/code&gt;. Il
se trouve sur un autre &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt; que celui qui est en cours de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt;. Le PDB étant
respecté, l’opération de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt; peut se poursuivre avec l’éviction du
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;C’est à ce moment-là que vous pourrez faire la montée de version du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt;
Kubernetes.&lt;/p&gt;

&lt;p&gt;Avant de déclencher un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; d’un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt;, nous vous suggérons de vérifier
qu’il n’existe pas de retard trop important entre vos instances secondaires et
l’instance primaire.&lt;/p&gt;

&lt;h3 id=&quot;et-après-&quot;&gt;Et après ?&lt;/h3&gt;

&lt;p&gt;Pour les personnes les plus attentives, vous aurez remarqué que le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt;
attend que toutes les instances soient actives.&lt;/p&gt;

&lt;p&gt;La commande &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kubectl cnpg status postgresql-prod&lt;/code&gt; retourne le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Status&lt;/code&gt; suivant : 
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Waiting for the instances to become active Some instances are not yet active. Please wait.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Bien que fonctionnel, le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; est en mode dégradé, car l’instance
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;postgresql-prod-1&lt;/code&gt; doit toujours être re-déployée. Le problème ici est notamment
dû à la co-localité du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PV&lt;/code&gt; et du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt; qui n’est pas respectée. L’instance
PostgreSQL doit se trouver sur le même &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt; que celui où se trouve son volume.
La co-localité des volumes et des instances doit être prise en compte lors du
choix du CSI et de la configuration associée.&lt;/p&gt;

&lt;p&gt;Ce n’est pas le cœur de notre article de blog. On vous laissera donc vous
rapprocher d’experts Kubernetes, mais gardez en tête cette contrainte de
co-localité qui peut exister selon votre choix de système de stockage.&lt;/p&gt;

&lt;p&gt;Supposons que la mise à jour du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt; se soit bien déroulée, il est possible de
redéployer des &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pods&lt;/code&gt; sur le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt;.
Pour cela, l’opération de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uncordon&lt;/code&gt; doit être lancée pour indiquer que le
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt; peut être de nouveau utilisé.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;kubectl uncordon kind-worker
&lt;span class=&quot;go&quot;&gt;
node/kind-worker uncordoned
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Quelques temps après, le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt; est redéployé et le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; est complètement
fonctionnel (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;healthy state&lt;/code&gt;).&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;kubectl get cluster
&lt;span class=&quot;go&quot;&gt;
NAME              AGE   INSTANCES   READY   STATUS                     PRIMARY
postgresql-prod   19h   2           2       Cluster in healthy state   postgresql-prod-2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;cas-dun-cluster-mono-instance&quot;&gt;Cas d’un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; mono-instance&lt;/h3&gt;

&lt;p&gt;Dans le cas où un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt; est effectué sur un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt; qui héberge un
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; mono-instance (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;instances: 1&lt;/code&gt; dans le YAML) l’éviction du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Pod&lt;/code&gt; ne se
fera pas et le message d’erreur suivant sera affiché en boucle.&lt;/p&gt;

&lt;div class=&quot;language-console highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;go&quot;&gt;error when evicting pods/&quot;postgresql-prod-2&quot; -n &quot;default&quot; (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/postgresql-prod-2
error when evicting pods/&quot;postgresql-prod-2&quot; -n &quot;default&quot; (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
evicting pod default/postgresql-prod-2
error when evicting pods/&quot;postgresql-prod-2&quot; -n &quot;default&quot; (will retry after 5s): Cannot evict pod as it would violate the pod's disruption budget.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Il est possible de désactiver l’utilisation de PDB avec le champ
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;spec.enablePDB&lt;/code&gt; dans la définition du &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; :&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;apiVersion&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;postgresql.cnpg.io/v1&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Cluster&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cluster-no-pdb&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;spec&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;instances&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enablePDB&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pour autant que ce soit possible, il n’est pas recommandé de l’utiliser en production.&lt;/p&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Nous venons de voir comment CloudNativePG utilise la ressource Kubernetes
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PodDisruptionBudget&lt;/code&gt; pour protéger un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cluster&lt;/code&gt; PostgreSQL en cas de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;drain&lt;/code&gt;
sur un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Le principe est d’éviter que Kubernetes n’évince une instance primaire de façon
brutale lors d’une opération volontaire. Si une instance secondaire existe, une
bascule est automatiquement effectuée sur celle-ci.&lt;/p&gt;

&lt;p&gt;C’est un mécanisme qui est intéressant de connaître, notamment pour la mise à
jour de vos nœuds Kubernetes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Des questions, des commentaires ? &lt;a href=&quot;mailto:pierrick.chovelon@dalibo.com?subject=[Commentaire-Blog] CloudNativePG&quot;&gt;Écrivez-nous !&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 19 Feb 2026 00:00:00 -0600</pubDate>
				<link>https://blog.dalibo.com/2026/02/19/cnpg-10.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/02/19/cnpg-10.html</guid>
			</item>
		
			<item>
				<title>Formations Dalibo : les prochaines sessions</title>
				<description>&lt;p&gt;&lt;em&gt;Saint-Étienne, le 18 février 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Administration et Performances de PostgreSQL, Développement avec SQL… Dalibo vous propose des formations en présentiel ou à distance. Voici les dates des &lt;strong&gt;prochaines sessions inter-entreprises&lt;/strong&gt; jusqu’à fin 2026.&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/jBk9khks_js&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;
&lt;/iframe&gt;

&lt;h3 id=&quot;le-calendrier-des-sessions&quot;&gt;Le calendrier des sessions&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Rappels&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Certifiées Qualiopi, nos formations sont détaillées sur notre &lt;strong&gt;&lt;a href=&quot;https://dali.bo/manuels_formation&quot;&gt;site&lt;/a&gt; institutionnel&lt;/strong&gt;. Elles se divisent en 4 cursus : Administration, Performances, Développement et Transition vers PostgreSQL.&lt;/p&gt;

&lt;p&gt;Inter-entreprises et en présentiel, elles durent 2 ou 3 journées. Depuis 2020, certaines sessions sont aussi assurées à distance sur 4-5 matinées, de 9h00 à 12h30.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Bon à savoir&lt;/em&gt; : vous pouvez aussi &lt;a href=&quot;mailto:formation@dalibo.com&quot;&gt;nous écrire&lt;/a&gt; afin d’organiser des sessions en intra.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ADMINISTRATION&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&quot;float: left; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;p&gt;&lt;a href=&quot;https://dali.bo/dba1&quot;&gt;DBA1&lt;/a&gt; : Administration PostgreSQL&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;9-13 mars, à distance&lt;/li&gt;
    &lt;li&gt;1-5 juin, à distance&lt;/li&gt;
    &lt;li&gt;8-10 septembre, à Paris&lt;/li&gt;
    &lt;li&gt;5-9 octobre, à distance&lt;/li&gt;
    &lt;li&gt;17-19 novembre, à Paris&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;float: right; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;p&gt;&lt;a href=&quot;https://dali.bo/dba2&quot;&gt;DBA2&lt;/a&gt; : Administration PostgreSQL Avancée&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;24-26 mars, à Paris&lt;/li&gt;
    &lt;li&gt;1-5 juin, à distance&lt;/li&gt;
    &lt;li&gt;23-25 juin, à Paris&lt;/li&gt;
    &lt;li&gt;21-25 septembre, à distance&lt;/li&gt;
    &lt;li&gt;13-15 octobre, à Paris&lt;/li&gt;
    &lt;li&gt;30 novembre - 4 décembre, à distance&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;div style=&quot;float: left; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;p&gt;&lt;a href=&quot;https://dali.bo/dba3&quot;&gt;DBA3&lt;/a&gt; : Sauvegarde et Réplication avec PostgreSQL&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;31 mars - 2 avril, à Paris&lt;/li&gt;
    &lt;li&gt;15-19 juin, à distance&lt;/li&gt;
    &lt;li&gt;29 septembre - 1 octobre, à Paris&lt;/li&gt;
    &lt;li&gt;24-26 novembre, à Paris&lt;/li&gt;
    &lt;li&gt;15-17 décembre, à Paris&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;float: right; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;p&gt;&lt;a href=&quot;https://dali.bo/hapat&quot;&gt;HAPAT&lt;/a&gt; : Haute disponibilité avec PostgreSQL&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;16-20 mars, à distance&lt;/li&gt;
    &lt;li&gt;9-11 juin, à Paris&lt;/li&gt;
    &lt;li&gt;14-18 septembre, à distance&lt;/li&gt;
    &lt;li&gt;1-3 décembre, à Paris&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;PERFORMANCES&lt;/strong&gt;&lt;/p&gt;

&lt;div style=&quot;float: left; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;p&gt;&lt;a href=&quot;https://dali.bo/perf1&quot;&gt;PERF1&lt;/a&gt; : PostgreSQL Performances&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;10-12 mars, à Paris&lt;/li&gt;
    &lt;li&gt;8-12 juin, à distance&lt;/li&gt;
    &lt;li&gt;7-11 septembre, à distance&lt;/li&gt;
    &lt;li&gt;13-15 octobre, à Paris&lt;/li&gt;
    &lt;li&gt;16-20 novembre, à distance&lt;/li&gt;
    &lt;li&gt;8-10 décembre, à Paris&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;float: right; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;p&gt;&lt;a href=&quot;https://dali.bo/perf2&quot;&gt;PERF2&lt;/a&gt; : Indexation et SQL Avancés&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;31 mars - 1 avril, à Paris&lt;/li&gt;
    &lt;li&gt;23-24 juin, à Paris&lt;/li&gt;
    &lt;li&gt;29-30 septembre, à Paris&lt;/li&gt;
    &lt;li&gt;24-25 novembre, à Paris&lt;/li&gt;
    &lt;li&gt;15-18 décembre, à distance&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;div style=&quot;float: left; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;p&gt;&lt;strong&gt;DÉVELOPPEMENT&lt;/strong&gt;&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://dali.bo/devpg&quot;&gt;DEVPG&lt;/a&gt; : Développer avec SQL&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;17-19 mars, à Paris&lt;/li&gt;
    &lt;li&gt;16-18 juin, à Paris&lt;/li&gt;
    &lt;li&gt;22-24 septembre, à Paris&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;float: left; width: 50%; padding-right: 10px;&quot;&gt;
  &lt;p&gt;&lt;strong&gt;TRANSITION&lt;/strong&gt;&lt;/p&gt;

  &lt;p&gt;&lt;a href=&quot;https://dali.bo/dbaadm&quot;&gt;DBAADM&lt;/a&gt; : Administration PostgreSQL pour DBA expérimentés&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;em&gt;uniquement en intra et en présentiel&lt;/em&gt;&lt;/li&gt;
  &lt;/ul&gt;
&lt;/div&gt;

&lt;div style=&quot;clear: both&quot;&gt;&lt;/div&gt;

&lt;h3 id=&quot;contactez-nous&quot;&gt;Contactez-nous&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Appelez Jill et Lorraine au + 33 1 83 64 61 88,&lt;/li&gt;
  &lt;li&gt;ou écrivez à &lt;a href=&quot;mailto:formation@dalibo.com&quot;&gt;formation@dalibo.com&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
				<pubDate>Wed, 18 Feb 2026 00:00:00 -0600</pubDate>
				<link>https://blog.dalibo.com/2026/02/18/formations.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/02/18/formations.html</guid>
			</item>
		
			<item>
				<title>Sortie de PostgreSQL 18.2, 17.8, 16.12, 15.16 et 14.21</title>
				<description>&lt;p&gt;&lt;em&gt;Strasbourg, le 12 février 2026&lt;/em&gt;&lt;/p&gt;

&lt;p class=&quot;alert alert-danger&quot;&gt;&lt;strong&gt;Addendum du 17 février&lt;/strong&gt; : en raison de &lt;a href=&quot;https://www.postgresql.org/about/news/out-of-cycle-release-scheduled-for-february-26-2026-3241/&quot;&gt;régressions liées à la fonction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;substring&lt;/code&gt; et à des arrêts possibles
du serveur secondaire&lt;/a&gt;,
nous vous recommandons de surseoir à la mise à jour.
Une nouvelle mise à jour est prévue le 26 février.&lt;/p&gt;

&lt;p&gt;Le PostgreSQL Global Development Group a publié le 12 février
&lt;strong&gt;&lt;a href=&quot;https://www.postgresql.org/about/news/postgresql-182-178-1612-1516-and-1421-released-3235/&quot;&gt;une mise à jour&lt;/a&gt;&lt;/strong&gt;
pour toutes les versions supportées de PostgreSQL,
c’est-à-dire les versions 18.2, 17.8, 16.12, 15.16, 14.21.
Cette mise à jour corrige 5 failles de sécurité
et plus de 65 bugs remontés ces derniers mois.&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;p&gt;&lt;img src=&quot;/img/202602_annonce_release.png&quot; alt=&quot;visuel annonce&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;sécurité&quot;&gt;Sécurité&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-2003: le type oidvector révèle quelques octets de mémoire&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Score CVSS v3.1: 4.3 / Versions supportées vulnérables : 14 - 18&lt;/p&gt;

&lt;p&gt;Une validation imparfaite du type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oidvector&lt;/code&gt; dans PostgreSQL permet à un utilisateur de révéler quelques octets de la mémoire du serveur. Nous n’avons pas exclu la possibilité d’attaques qui réussiraient à y trouver des informations confidentielles, mais elles semblent improbables. Les versions avant PostgreSQL 18.2, 17.8, 16.12, 15.16 et 14.21 sont concernées. Le projet PostgreSQL remercie Altan Birler pour avoir rapporté le problème.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-2004: l’absence de validation du type d’entrée &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;intarray&lt;/code&gt; dans l’estimation de sélectivité permet d’exécuter du code arbitraire.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Score CVSS v3.1: 8.8 / Versions supportées vulnérables : 14 - 18&lt;/p&gt;

&lt;p&gt;Dans l’extension &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;intarray&lt;/code&gt; de PostgreSQL, l’absence de validation du type d’entrée dans la fonction d’estimation de la sélectivité permet à un utilisateur pouvant créer des objets d’exécuter du code arbitraire en tant qu’utilisateur système. Les versions de PostgreSQL avant 18.2, 17.8, 16.12, 15.16, et 14.21  sont concernées.&lt;/p&gt;

&lt;p&gt;Le projet PostgreSQL remercie Daniel Firer, dans le cadre de &lt;a href=&quot;https://www.zeroday.cloud/&quot;&gt;zeroday.cloud&lt;/a&gt;, d’avoir rapporté le problème.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-2005: Un dépassement de tampon dans pgcrypto exécute du code arbitraire&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Score CVSS v3.1: 8.8 / Versions supportées vulnérables : 14 - 18&lt;/p&gt;

&lt;p&gt;Un dépassement de tampon dans l’extension &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pgcrypto&lt;/code&gt; permet à un fournisseur de texte chiffré d’exécuter du code arbitraire en tant qu’utilisateur système de la base de données. Les versions antérieures à PostgreSQL 18.2, 17.8, 16.12, 15.16 et 14.21 sont concernées.&lt;/p&gt;

&lt;p&gt;Le projet PostgreSQL remercie l’équipe Xint Code, dans le cadre de &lt;a href=&quot;https://www.zeroday.cloud/&quot;&gt;zeroday.cloud&lt;/a&gt;, d’avoir signalé ce problème.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-2006:  Une absence de validation par PostgreSQL de la longueur des caractères exécute du code arbitraire&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Score CVSS v3.1: 8.8 / Versions supportées vulnérables : 14 - 18&lt;/p&gt;

&lt;p&gt;Une absence de validation par PostgreSQL de la longueur des caractères multi-octets dans la manipulation des textes permet à un utilisateur de forger des requêtes et de parvenir à un dépassement de tampon (&lt;em&gt;buffer overrun&lt;/em&gt;).
Cela suffit pour exécuter du code arbitraire en tant qu’utilisateur système de la base.
Les versions antérieures à PostgreSQL 18.2, 17.8, 16.12, 15.16 et 14.21 sont concernées.
Le projet PostgreSQL remercie Paul Gerste et Moritz Sanft, dans le cadre de &lt;a href=&quot;https://www.zeroday.cloud/&quot;&gt;zeroday.cloud&lt;/a&gt;, d’avoir rapporté ce problème.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-2007: Un dépassement de tampon dans pg_trgm heap buffer écrits des  données dans la mémoire du serveur&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Score CVSS v3.1: 8.2 / Versions supportées vulnérables : 18&lt;/p&gt;

&lt;p&gt;Un dépassement de tampon dans l’extension &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_trgm&lt;/code&gt; permet à un utilisateur de la base d’effectuer des opérations indéfinies en entrant une chaîne spécialement forgée. L’attaquant a un contrôle limité sur la structure des données écrite, mais nous n’avons pas exclu la possibilité d’attaques menant à une élévation des privilèges. PostgreSQL 18.1 et 18.0 sont concernés.
Le projet PostgreSQL remercie Heikki Linnakangas d’avoir signalé ce problème.&lt;/p&gt;

&lt;h3 id=&quot;correctifs-et-améliorations&quot;&gt;Correctifs et améliorations&lt;/h3&gt;

&lt;p&gt;Cette mise à jour corrige plus de 65 bugs rapportés ces derniers mois. Les problèmes décrits ci-dessous concernent PostgreSQL 18. Certains peuvent également affecter d’autres versions supportées de PostgreSQL.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Correction d’incohérences dans l’extension &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ltree&lt;/code&gt;, relatives à la correspondance de texte insensible à la casse. Si vous utilisez un index sur une colonne ltree, une réindexation peut être nécessaire. Voir la section « Mise à jour » pour d’autres consignes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ajouter une contrainte &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT NULL&lt;/code&gt; sur une colonne déjà marquée &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOT NULL&lt;/code&gt; via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALTER TABLE … ADD CONSTRAINT&lt;/code&gt; impose maintenant que le nom de la contrainte corresponde au nom existant.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Correction du comportement des triggers lorsque &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MERGE&lt;/code&gt; est exécuté depuis un &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WITH&lt;/code&gt; pour inclure les lignes affectées par le &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MERGE&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Plusieurs corrections du planificateur de requêtes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Correction de la recherche de sous-chaînes de texte avec des collations non déterministes.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Plusieurs améliorations de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOTIFY&lt;/code&gt; dans la gestion et les rapports d’erreurs.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Utilise la bonne fonction de tri lors des constructions parallélisées d’index GIN.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Correction une gestion incorrecte des sauvegardes incrémentales avec des tables de plus de 1 sGo.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;La restauration échoue désormais si les WAL n’existent pas en remontant jusqu’au point de redo indiqué par l’enregistrement de checkpoint.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Correction d’&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ALTER PUBLICATION&lt;/code&gt; pour garantir que les trigger sur événements contiennent bien toutes les options définies.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Divers correctifs dans l’initialisation des slots de réplication.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;En réplication logique, le slot de réplication n’avance plus après l’échec d’un worker parallèle &lt;em&gt;apply&lt;/em&gt;, évitant ainsi la perte de transactions côté souscripteur.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Correction des rapports d’erreurs en cas d’incohérence de types dans SQL/JSONPath.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Correctif dans l’inlining de fonctions en compilation JIT avec LLVM 17 et ultérieurs.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Nouveau paramètre serveur &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;file_extend_method&lt;/code&gt; pour contrôler l’usage de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;posix_fallocate()&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Correctif dans l’autocomplétion psql des options de la commande &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VACUUM&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_dump&lt;/code&gt; gère à présent correctement des suppressions de séquences concurrentes, et échoue si l’utilisateur n’a explicitement pas les privilèges de lecture sur la séquence.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Plusieurs correctifs d’&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;amcheck&lt;/code&gt; pour l’inspection des btree.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Évite un crash de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_stat_statements&lt;/code&gt; quand une liste &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IN&lt;/code&gt; mélange des constantes et des expressions non constantes.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cette version intègre également les mises à jour des fuseaux horaires tzdata 2025c, avec juste une correction historiques des horodatages antérieurs à 1976 en Basse-Californie.&lt;/p&gt;

&lt;h3 id=&quot;mettre-à-jour&quot;&gt;Mettre à jour&lt;/h3&gt;

&lt;p&gt;Toutes les mises à jour de PostgreSQL sont cumulatives.
Pour appliquer la mise à jour, comme pour les autres versions mineures,
les utilisateurs n’ont pas besoin de sauvegarder
et recharger leur base de données, ni d’utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pg_upgrade&lt;/code&gt;. 
Vous pouvez simplement arrêter PostgreSQL et mettre à jour ses binaires.&lt;/p&gt;

&lt;p&gt;Si vous avez des index sur des colonnes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ltree&lt;/code&gt;
et que vous n’utilisez pas le fournisseur de collation &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libc&lt;/code&gt;, vous devez réindexer toutes les colonnes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ltree&lt;/code&gt;
après la mise à jour. Vous pouvez utiliser &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;REINDEX INDEX CONCURRENTLY&lt;/code&gt; pour minimiser l’impact sur votre système.&lt;/p&gt;

&lt;p&gt;Les utilisateurs ayant sauté une version mineure ou plus peuvent avoir besoin de réaliser d’autres opérations post-mise à jour. 
Voir les [Notes de version] pour les détails.&lt;/p&gt;

&lt;h3 id=&quot;liens&quot;&gt;Liens&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/download/&quot;&gt;Téléchargements&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/docs/release/&quot;&gt;Notes de version&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/support/security/&quot;&gt;Sécurité&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/support/versioning/&quot;&gt;Politique de versionnement&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/account/submitbug/&quot;&gt;Soumettez un bug&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.postgresql.org/about/donate/&quot;&gt;Donnez&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
				<pubDate>Thu, 12 Feb 2026 00:00:00 -0600</pubDate>
				<link>https://blog.dalibo.com/2026/02/12/postgresql_release.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/02/12/postgresql_release.html</guid>
			</item>
		
			<item>
				<title>UUID v7 – 80x moins d'I/O pour VACUUM</title>
				<description>&lt;p&gt;&lt;em&gt;Mont de Marsan, le 6 février 2026&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Le type de donnée &lt;em&gt;Universally unique identifier&lt;/em&gt; ou UUID est très apprécié dans
les architectures distribuées. En effet, une séquence classique (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SERIAL&lt;/code&gt;,
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDENTITY&lt;/code&gt;) ne garantit l’unicité qu’au sein d’une seule base de données, là où
un UUID est voulu unique au monde par construction, tout en étant généré
localement, sans coordination centrale.&lt;/p&gt;

&lt;p&gt;Cependant leur nature aléatoire pose un problème de performance mal connu (sauf
des DBA PostgreSQL…): la fragmentation des index. Voyons comment PostgreSQL
18 qui implémente les UUID v7 résout ce problème.&lt;/p&gt;

&lt;!--MORE--&gt;

&lt;p&gt;&lt;img src=&quot;/img/portrait_alain2.png&quot; alt=&quot;Alain Lesage&quot; style=&quot;float: right; padding:10px; width:120px;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;le-problème-des-uuid-v4&quot;&gt;Le problème des UUID v4&lt;/h2&gt;

&lt;p&gt;La fonction &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gen_random_uuid()&lt;/code&gt;, apparue avec PostgreSQL 13, génère des UUID
version 4, c’est-à-dire des identifiants de 128 bits complètement aléatoires.
Cette propriété est idéale pour éviter les collisions dans les systèmes
distribués, mais elle a un effet de bord délétère sur les performances.&lt;/p&gt;

&lt;p&gt;Lorsqu’on insère des lignes avec un UUID v4 comme clé primaire, chaque nouvel
UUID atterrit à un endroit aléatoire dans l’index B-tree associé à cette clé.
Ceci a pour conséquence que les insertions sont dispersées dans tout l’index,
rendant le cache peu efficace : chaque page lue n’est utilisée qu’une fois
avant d’être évincée. &lt;!-- je ne vois pas comment mieux formuler/expliquer --&gt;&lt;/p&gt;

&lt;h2 id=&quot;la-solution--uuid-version-7&quot;&gt;La solution : UUID version 7&lt;/h2&gt;

&lt;p&gt;Les UUID v7, définis par la &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc9562&quot;&gt;RFC 9562&lt;/a&gt;,
résolvent ce problème en intégrant un &lt;strong&gt;timestamp&lt;/strong&gt; dans les premiers bits de
l’identifiant. Les UUID générés sont donc naturellement triés par ordre
chronologique.&lt;/p&gt;

&lt;p&gt;PostgreSQL 18 ajoute de nouvelles fonctions :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;uuidv4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;                      &lt;span class=&quot;c1&quot;&gt;-- Alias de gen_random_uuid()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;uuidv7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;                      &lt;span class=&quot;c1&quot;&gt;-- Génère un UUID v7&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;uuid_extract_version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;-- Retourne la version (1 à 7)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;uuid_extract_timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;-- Extrait la date de création (v1, v7)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;comparaison&quot;&gt;Comparaison&lt;/h2&gt;

&lt;p&gt;Générons quelques UUID des deux versions pour comprendre les différences :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuidv4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid_v4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuidv7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid_v7&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generate_series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;               uuid_v4                |               uuid_v7
--------------------------------------+--------------------------------------
 f8856df2-1638-4478-81ad-0b1be6ab94b7 | 019c2ada-69d6-794a-bf1c-207ea936bb8c
 6ebf42db-6fa7-4ee5-9427-c010fc298630 | 019c2ada-69d6-7967-abd3-ace26cbbe5d1
 9af32354-efd4-4e85-9c5b-12422cfb8420 | 019c2ada-69d6-796d-95d4-7e1c221fc193
 654fa0c3-7398-4a1a-819d-57d003d8afd6 | 019c2ada-69d6-7972-8f04-314ff096437d
 41bf3daa-76ac-46d1-9174-72e6f9dda78c | 019c2ada-69d6-7976-b785-8b92ae4329c2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Les UUID v7 partagent un &lt;strong&gt;préfixe commun&lt;/strong&gt; (le timestamp) tandis que les UUID
v4 sont complètement aléatoires. Ce préfixe commun est la clé de leur efficacité
dans les index B-tree.&lt;/p&gt;

&lt;h2 id=&quot;impact-sur-la-taille-des-index&quot;&gt;Impact sur la taille des index&lt;/h2&gt;

&lt;p&gt;Créons deux tables avec 500 000 lignes chacune :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- Table avec UUID v4&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;INTO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv4&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuidv4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'ligne '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generate_series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;500000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- Table avec UUID v7&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv7&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;INTO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv7&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuidv7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'ligne '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generate_series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;500000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;VACUUM&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ANALYZE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Comparons la taille des index :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relname&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relpages&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pages&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pg_class&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relname&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;LIKE&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'t_uuid%pkey'&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;relname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;     index     | pages
---------------+-------
 t_uuidv4_pkey |  2434
 t_uuidv7_pkey |  1927
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;L’index UUID v7 est 21 % plus petit ! Les insertions séquentielles
permettent un meilleur remplissage des pages de l’index.&lt;/p&gt;

&lt;h2 id=&quot;colocalité-des-données&quot;&gt;Colocalité des données&lt;/h2&gt;

&lt;p&gt;Au-delà de la taille, c’est la &lt;strong&gt;localité des données&lt;/strong&gt; qui fait la différence.
Regardons où se trouvent physiquement les 10 plus petits UUID de chaque table :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- UUID v4 : accès par index (10 plus petits UUID)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv4&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                  id                  |    ctid    | page
--------------------------------------+------------+------
 00001a5f-3538-4f1b-a5c5-0a1a3703a15d | (210,8)    |  210
 000025eb-4928-418f-b418-a5b4693d0f02 | (67,62)    |   67
 00002f6c-ae0b-4eaf-856c-26cb41de7ea0 | (252,97)   |  252
 0000316a-83fb-4cb8-bdee-9f867d20d83a | (3297,33)  | 3297
 0000335b-6c7a-4678-a989-ba5603b69317 | (806,37)   |  806
 ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ayant été générés à des moments complètement différents, les 10 plus petits UUID
v4, bien que contigus dans l’index, pointent vers des pages dispersées
aléatoirement dans la table. Et inversement, les UUID d’une même page de la
table sont dispersés dans tout l’index.&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- UUID v7 : accès par index (10 plus petits UUID)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv7&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                  id                  |  ctid  | page
--------------------------------------+--------+------
 019c2adc-fa3d-7711-ae51-43d144c4a169 | (0,1)  |    0
 019c2adc-fa3e-76e4-9094-94cb6398b0a9 | (0,2)  |    0
 019c2adc-fa3e-770d-baa4-149bd7d53633 | (0,3)  |    0
 019c2adc-fa3e-7716-a416-77105da270a2 | (0,4)  |    0
 019c2adc-fa3e-771d-9679-be4d91be9c8c | (0,5)  |    0
 ...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Avec UUID v7, les plus petits UUID (les plus anciens) sont dans les premières
pages de la table. La sélection d’une plage d’id consécutifs sur une table UUID
v7 lira des pages contiguës, tandis que sur UUID v4, elle fera des accès
aléatoires à travers toute la table. Vous n’avez peut-être pas de requête métier
qui font ce genre de sélection d’id, mais nous verrons plus loin qu’une pénalité
demeure sur l’efficacité du processus &lt;em&gt;autovacuum&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;tri-chronologique-natif&quot;&gt;Tri chronologique natif&lt;/h2&gt;

&lt;p&gt;Puisque les UUID v7 contiennent un timestamp, ils sont naturellement triables
par date de création :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uuid_extract_timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;AS&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t_uuidv7&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DESC&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                  id                  |         created_at
--------------------------------------+----------------------------
 019c2add-08da-77d8-8834-7a34d2075185 | 2026-02-04 22:54:14.746+00
 019c2add-08da-77d2-9ee7-e296fd1bc85a | 2026-02-04 22:54:14.746+00
 019c2add-08da-77cc-837f-e3399d65ffb7 | 2026-02-04 22:54:14.746+00
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ORDER BY id&lt;/code&gt; équivaut à &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ORDER BY created_at&lt;/code&gt; ! Cette propriété peut vous
permettre d’économiser une colonne &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;created_at&lt;/code&gt; et son index associé.&lt;/p&gt;

&lt;h2 id=&quot;impact-sur-vacuum&quot;&gt;Impact sur VACUUM&lt;/h2&gt;

&lt;p&gt;Un effet de la fragmentation dans les index concerne VACUUM. Lors d’une purge de
données anciennes (typiquement &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DELETE FROM sessions WHERE created_at &amp;lt; now() -
interval '30 days'&lt;/code&gt;), les lignes supprimées sont :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Dispersées&lt;/strong&gt; dans toutes les pages avec UUID v4 (insertions aléatoires)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Groupées&lt;/strong&gt; dans les premières pages avec UUID v7 (insertions chronologiques)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;VACUUM peut même &lt;strong&gt;bypasser le scan d’index&lt;/strong&gt; si moins de 2% des pages de la
table contiennent des tuples morts. Démonstration :&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;-- Deux tables de sessions avec 10 000 lignes sur 100 jours&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UUID&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gen_random_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;TIMESTAMP&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;TEXT&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v7&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;UUID&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuidv7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;TIMESTAMP&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;TEXT&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- Insertion de 10 000 lignes réparties sur 100 jours&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;INTO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v4&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'2026-01-01'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;timestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interval&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'1 day'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generate_series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;INTO&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v7&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'2026-01-01'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;timestamp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;interval&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'1 day'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'x'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;generate_series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- Réorganisation physique selon l'index UUID (maintenance courante)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CLUSTER&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v4&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;USING&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v4_pkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CLUSTER&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v7&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;USING&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v7_pkey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;VACUUM&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;ANALYZE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;-- Suppression d'un jour de données (1% des lignes)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;DELETE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v4&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'2026-01-02'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;DELETE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sessions_v7&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;created_at&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'2026-01-02'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Exécutons &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VACUUM (VERBOSE)&lt;/code&gt; sur les deux :&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;-- sessions_v4
INFO:  vacuuming &quot;postgres.public.sessions_v4&quot;
INFO:  finished vacuuming &quot;postgres.public.sessions_v4&quot;: index scans: 1
pages: 0 removed, 193 remain, 193 scanned (100.00% of total), 0 eagerly scanned
[…]
index &quot;sessions_v4_pkey&quot;: pages: 41 in total, 0 newly deleted, 0 currently deleted, 0 reusable

-- sessions_v7
INFO:  vacuuming &quot;postgres.public.sessions_v7&quot;
INFO:  finished vacuuming &quot;postgres.public.sessions_v7&quot;: index scans: 0
pages: 0 removed, 193 remain, 3 scanned (1.55% of total), 0 eagerly scanned
[…]
index scan bypassed: 2 pages from table (1.04% of total) have 100 dead item identifiers
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;!-- 

-- sessions_v4
INFO:  vacuuming &quot;postgres.public.sessions_v4&quot;
INFO:  finished vacuuming &quot;postgres.public.sessions_v4&quot;: index scans: 1
pages: 0 removed, 193 remain, 193 scanned (100.00% of total), 0 eagerly scanned
tuples: 100 removed, 9900 remain, 0 are dead but not yet removable
removable cutoff: 771, which was 0 XIDs old when operation ended
new relfrozenxid: 771, which is 4 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 76 pages set all-visible, 76 pages set all-frozen (0 were all-visible)
index scan needed: 76 pages from table (39.38% of total) had 100 dead item identifiers removed
index &quot;sessions_v4_pkey&quot;: pages: 41 in total, 0 newly deleted, 0 currently deleted, 0 reusable

-- sessions_v7
INFO:  vacuuming &quot;postgres.public.sessions_v7&quot;
INFO:  finished vacuuming &quot;postgres.public.sessions_v7&quot;: index scans: 0
pages: 0 removed, 193 remain, 3 scanned (1.55% of total), 0 eagerly scanned
tuples: 100 removed, 10000 remain, 0 are dead but not yet removable
removable cutoff: 771, which was 0 XIDs old when operation ended
new relfrozenxid: 771, which is 3 XIDs ahead of previous value
frozen: 0 pages from table (0.00% of total) had 0 tuples frozen
visibility map: 0 pages set all-visible, 0 pages set all-frozen (0 were all-visible)
index scan bypassed: 2 pages from table (1.04% of total) have 100 dead item identifiers

--&gt;

&lt;p&gt;Avec UUID v4, les 100 lignes supprimées (1% des données), VACUUM doit scanner
100 % (!) des pages de la table et effectuer un scan complet de l’index (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;index
scans: 1&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Avec UUID v7, les mêmes 100 lignes sont groupées, VACUUM peut bypasser le scan
d’index (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;index scans: 0&lt;/code&gt;) et ne parcourt que 1.55% des pages de la table,
l’autovacuum sera d’autant plus efficace, n’ayant que 3 pages à parcourir au
lieu de 234 (table + index), soit 78 fois moins !!&lt;/p&gt;

&lt;p&gt;Notre exemple, volontairement simplifié, permet d’observer deux phénomènes
distincts :&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;le bypass&lt;/strong&gt; du scan d’index, optimisation de VACUUM ;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;moins de pages à parcourir&lt;/strong&gt; sur la table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En production, ces deux effets ne sont pas toujours liés, l’avantage de UUID v7
sera donc généralement moins spectaculaire que dans cette démonstration, mais
néanmoins bien réel.&lt;/p&gt;

&lt;h2 id=&quot;à-retenir&quot;&gt;À retenir&lt;/h2&gt;

&lt;p&gt;Les UUID v7 offrent des index plus compacts, une excellente colocalité des
données, un tri chronologique natif et un VACUUM nettement plus efficace. Ils
sont particulièrement adaptés aux tables à fort volume d’insertions, aux tables
partitionnées par date, et aux systèmes distribués. Les UUID v4 restent
pertinents si l’imprévisibilité de l’identifiant est requise pour des raisons de
sécurité, mais leur utilisation a des conséquences, que vous pourrez désormais
anticiper.&lt;/p&gt;

&lt;h2 id=&quot;références&quot;&gt;Références&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;La norme &lt;a href=&quot;https://www.rfc-editor.org/rfc/rfc9562&quot;&gt;RFC 9562 - UUID version 7&lt;/a&gt; ;&lt;/li&gt;
  &lt;li&gt;Le commit
&lt;a href=&quot;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=78c5e141e&quot;&gt;78c5e141e&lt;/a&gt; sur
PostgreSQL ;&lt;/li&gt;
  &lt;li&gt;Nos formations &lt;a href=&quot;https://dali.bo/perf1_html&quot;&gt;PERF1&lt;/a&gt; et
&lt;a href=&quot;https://dali.bo/perf2_html&quot;&gt;PERF2&lt;/a&gt; qui abordent l’indexation dans PostgreSQL.&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Fri, 06 Feb 2026 00:00:00 -0600</pubDate>
				<link>https://blog.dalibo.com/2026/02/06/UUID-v7.html</link>
				<guid isPermaLink="true">https://blog.dalibo.com/2026/02/06/UUID-v7.html</guid>
			</item>
		
	</channel>
</rss>
