Image de couverture : Collation PostgreSQL et glibc : comment une mise à jour silencieuse peut corrompre vos données
tech

Collation PostgreSQL et glibc : comment une mise à jour silencieuse peut corrompre vos données

06 April 2026
7 min de lecture
1 vues
Sébastien Muler

Collation PostgreSQL et glibc : comment une mise à jour silencieuse peut corrompre vos données

Imaginez que votre base de données fonctionne parfaitement, que votre application PHP/Symfony tourne sans erreur, et que pourtant, en coulisses, vos index sont corrompus, vos tris sont faux et vos contraintes d'unicité ne valent plus rien. C'est exactement ce qui s'est produit à grande échelle depuis 2018, suite à une mise à jour de la bibliothèque système glibc. Cet article, inspiré de l'analyse de Shaun Thomas publiée sur le blog pgEdge, vous explique ce risque concret, comment le détecter rapidement et quelles actions correctives prioriser.


Qu'est-ce qu'une collation et pourquoi est-ce critique ?

Une collation définit les règles de comparaison et de tri du texte dans une base de données. En apparence, cela semble anodin. En pratique, c'est le fondement invisible sur lequel reposent vos index, vos tris ORDER BY, vos recherches et vos contraintes UNIQUE.

Pour du texte simple en ASCII (lettres de a à z, sans accent), les règles sont triviales. Mais dès que l'on introduit des caractères accentués — et le français en est rempli — les choses se compliquent. Est-ce que é doit être trié comme e ? Est-ce que ß en allemand équivaut à ss ? Chaque langue a ses propres règles, codifiées dans des standards internationaux.

PostgreSQL délègue historiquement cette logique à la bibliothèque C du système d'exploitation : la glibc (GNU C Library) sur Linux. Et c'est là que tout a déraillé.

Le bug silencieux de glibc 2.28

Le 1er août 2018, la version 2.28 de glibc est sortie. Elle intégrait 18 ans de modifications accumulées sur les règles de collation locale, alignées avec la norme ISO 14651 (édition 2016) et Unicode 9.0.0. Ce n'était pas un ajustement mineur : c'était une réécriture massive des règles de tri.

Le problème ? PostgreSQL avait construit ses index en se basant sur les règles de l'ancienne version de glibc. Après la mise à jour du système, les nouvelles règles de tri ne correspondaient plus à l'ordre dans lequel les données avaient été indexées. Résultat :

  • Des index silencieusement corrompus : PostgreSQL les utilise mais ils renvoient des résultats incorrects.
  • Des doublons invisibles : une contrainte UNIQUE peut laisser passer deux valeurs considérées comme identiques par les nouvelles règles, mais distinctes selon les anciennes.
  • Des tris erronés : vos listes triées par nom, prénom ou libellé peuvent être dans le mauvais ordre sans qu'aucune erreur ne soit levée.
  • PostgreSQL ne se plaint pas. Le système d'exploitation non plus. Tout semble normal.

Pour les dirigeants de TPE/PME, cela se traduit concrètement par : des emails envoyés deux fois à un même client, des rapports triés de façon incohérente, des règles métier contournées silencieusement.


Comment vérifier si votre base est exposée ?

Avant toute chose, il faut évaluer votre exposition. Voici les contrôles rapides à effectuer.

1. Identifier la collation utilisée

Connectez-vous à votre base PostgreSQL et exécutez :

SELECT datname, datcollate, datctype
FROM pg_database
WHERE datname = current_database();

Si datcollate contient une valeur du type fr_FR.UTF-8 ou en_US.UTF-8 (collations dépendantes de la glibc), vous êtes potentiellement concerné. Les bases configurées avec la collation ICU (ex. und-x-icu) sont nettement plus robustes car ICU est une bibliothèque indépendante du système.

2. Vérifier la version de glibc de votre serveur

ldd --version

Si la version affichée est 2.28 ou supérieure et que votre instance PostgreSQL a été créée avec une version antérieure de glibc, le risque est réel.

3. Détecter les index potentiellement corrompus

PostgreSQL fournit l'extension amcheck pour inspecter l'intégrité des index B-tree :

CREATE EXTENSION IF NOT EXISTS amcheck;

SELECT bt_index_check(c.oid)
FROM pg_index i
JOIN pg_class c ON c.oid = i.indexrelid
JOIN pg_am am ON am.oid = c.relam
WHERE am.amname = 'btree';

Une erreur retournée par cette fonction est un signal d'alarme à ne pas ignorer.


Les actions correctives prioritaires

Si votre analyse révèle un risque, voici les actions à mener, par ordre de priorité.

Action 1 : Reconstruire les index (REINDEX)

La reconstruction des index force PostgreSQL à les recalculer selon les règles de collation actuelles. C'est l'action la plus rapide :

REINDEX DATABASE nom_de_votre_base;

⚠️ Sur une base volumineuse, cette opération peut être longue et impactante. Planifiez-la en dehors des heures de pointe, ou utilisez REINDEX CONCURRENTLY (PostgreSQL 12+) pour limiter l'impact.

Action 2 : Effectuer un dump/restore complet

Pour une remise à zéro complète et fiable, la procédure dump/restore est la solution la plus sûre. Elle recrée l'ensemble de la base, y compris les index, avec les règles de collation courantes :

pg_dump -Fc nom_de_votre_base > sauvegarde.dump
pg_restore -d nom_de_votre_nouvelle_base sauvegarde.dump

C'est l'occasion d'en profiter pour migrer vers une collation ICU, qui ne dépend plus de la glibc et est donc stable entre les mises à jour système.

Action 3 : Épingler vos images Docker

Si votre infrastructure repose sur Docker, c'est un point critique souvent négligé. Une image postgres:latest peut embarquer n'importe quelle version de glibc. Une mise à jour automatique de l'image peut recréer exactement le problème décrit.

La bonne pratique est d'épingler une version précise dans votre docker-compose.yml ou vos manifestes Kubernetes :

image: postgres:16.2-alpine

Alpine Linux utilise musl libc et non glibc, ce qui réduit le risque. Mais dans tous les cas, ne laissez jamais une image non versionnée en production.

Action 4 : Migrer vers les collations ICU dans vos projets Symfony/PHP

Si vous démarrez un nouveau projet ou effectuez une migration majeure, configurez PostgreSQL pour utiliser ICU dès la création de la base :

CREATE DATABASE ma_base
  LOCALE_PROVIDER = 'icu'
  ICU_LOCALE = 'fr-FR'
  ENCODING = 'UTF8'
  TEMPLATE = template0;

Dans vos migrations Doctrine (Symfony), vérifiez que vos colonnes texte sensibles utilisent explicitement une collation ICU plutôt que la collation par défaut héritée de la base.


Conclusion : un risque discret mais réel pour votre activité

La corruption silencieuse des index PostgreSQL liée à glibc n'est pas un problème théorique. Elle a affecté des milliers d'instances dans le monde depuis 2018, souvent sans que les équipes techniques ou les dirigeants en soient informés. Pour une TPE ou une PME, les conséquences peuvent être concrètes : doublons clients, rapports erronés, règles métier non respectées.

Les bonnes nouvelles : les contrôles sont rapides, les correctifs existent et les bonnes pratiques (collations ICU, images Docker épinglées, REINDEX planifié) permettent d'éviter toute récidive.

Chez MulerTech, nous intégrons systématiquement ces vérifications dans nos audits de bases de données PostgreSQL pour nos clients PHP/Symfony. Si vous avez un doute sur l'état de vos données, n'hésitez pas à nous contacter.


Source originale : "What is a Collation, and Why is My Data Corrupt?" par Shaun Thomas, publié sur le blog pgEdge.

Partager cet article