Data & IA

Debezium 3.7 : tester votre CDC avant la migration

Une recette CDC PostgreSQL avec Debezium 3.7 pour vérifier suppressions, reprise et chiffres : fichiers Docker, script Python et résultats contrôlés.

Miljan Stojiljkovic
16 Octobre 2026
11 min
Data engineeringCDCDebeziumPostgreSQLQualité des données

Une commande disparaît de la base commerciale, mais reste dans le tableau de bord. Le connecteur fonctionne, les nouveaux achats arrivent et aucun traitement n’est en erreur. Le problème se trouve dans ce que la cible fait des changements reçus.

Le change data capture, ou CDC, transmet les modifications d’une base. Il faut ensuite définir comment les appliquer pour obtenir les données attendues. Une migration réussie doit préserver ce contrat, y compris lors d’une suppression et d’une reprise.

La recette PostgreSQL et Debezium téléchargeable fournit les conteneurs, les données fictives, le script de contrôle et un rapport. Elle a été exécutée le 16 octobre 2026 avec Debezium Server 3.7.0.Final. Elle vérifie une chaîne réelle locale, sans mesurer ses performances ni comparer deux versions.

Debezium 3.7 : ce qui change depuis la version précédente

Debezium 3.7 est sorti le 29 septembre 2026. Il s’agit de la dernière série stable affichée lors de cette rédaction, pas d’une annonce du jour. La version étend aussi le catalogue de connecteurs ; les nouveaux connecteurs TiDB, Milvus et SQLite sont présentés comme incubants. Leur présence dans une release ne démontre pas leur aptitude à votre production. Annonce officielle, série 3.7.

Trois évolutions méritent une vérification ciblée avant migration :

  • Disponibilité du serveur. Le contrôle de readiness de Debezium Server attend désormais le démarrage du polling du connecteur. Auparavant, il pouvait devenir positif dès le démarrage de Quarkus. Cela améliore le signal de démarrage, sans certifier les données écrites chez le consommateur. Changement #2393.
  • Suivi des snapshots. Le compteur TotalNumberOfReadEventsSeen rend visibles les événements READ des snapshots initiaux et incrémentaux. Ce nombre d’événements ne représente pas le nombre de lignes d’une table finale. Changement #2167.
  • Compatibilité MySQL vers JDBC. Un changement de représentation des types ENUM/SET impose de vérifier l’ordre de mise à jour entre source et sink. Le ticket recommande de mettre à niveau les deux, ou le sink avant la source. Ce point concerne cette chaîne particulière ; notre recette PostgreSQL ne le teste pas. Changement #2102.

Une équipe data doit donc regarder les changements de ses connecteurs et de ses consommateurs, au-delà du numéro de version global. Le guide ci-dessous prépare une recette fonctionnelle sous 3.7 ; il ne constitue pas un essai de montée de version depuis une installation 3.6.

Du journal de la base aux lignes consommées par la BI

Dans notre exemple, PostgreSQL est la source. Debezium Server capture un snapshot initial puis les changements, et les écrit dans un flux Redis Streams. Un programme Python relit ces événements pour reconstruire l’état courant par identifiant.

Debezium Server permet ce fonctionnement autonome, sans cluster Kafka dans cette recette. Redis reçoit ici un journal d’événements, pas une table métier automatiquement synchronisée par clé. Le programme de projection réalise cette deuxième opération. Documentation Debezium Server.

Avec un export complet quotidien, on peut remplacer la cible entière et prendre en compte les lignes disparues, à condition que le contrat d’export soit explicite. Un chargement incrémental basé seulement sur une date de modification demande, lui, une méthode supplémentaire pour retrouver les suppressions physiques. Le CDC expose ces changements au fil du journal, mais ajoute des responsabilités : conserver la position de lecture, gérer les reprises et appliquer correctement les événements.

Ne migrez pas uniquement pour rendre un flux « temps réel ». Si une actualisation quotidienne satisfait la décision métier et que son rapprochement est fiable, le gain d’une chaîne continue doit justifier son exploitation supplémentaire. Mesurez la fraîcheur du résultat effectivement consulté, pas seulement la rapidité d’émission du connecteur.

Trois contrats métier différents

Une vue des commandes actives. Dans un commerce fictif, la cible doit reproduire les commandes présentes dans PostgreSQL. Une suppression doit enlever la ligne correspondante. Critère de réussite : mêmes identifiants et mêmes valeurs après stabilisation, pas seulement un total proche.

Un historique des commandes. Une autre équipe conserve les états successifs pour analyser les changements. Elle ne doit pas effacer toute trace historique à réception d’un événement de suppression. Le critère porte alors sur les versions et leur clôture. Notre projection d’état courant ne répond pas à ce besoin.

Un référentiel produit enrichi. L’équipe ajoute une colonne facultative, puis commence à la renseigner. La cible doit accepter les anciennes lignes et exposer la nouvelle valeur. Un ajout nullable réussi ne valide ni un renommage ni un changement de type. Les évolutions nécessaires au métier doivent figurer dans la recette.

Ces règles relèvent du contrat de données. Elles évitent de demander au connecteur de décider à la place du métier ce qu’une suppression signifie.

Tutoriel : tester la synchronisation et la reprise

1. Préparer un environnement isolé

Prévoyez Docker avec Compose, Python 3.10 ou plus et une connexion permettant de télécharger les images. Aucun paquet Python supplémentaire ni compte cloud n’est nécessaire. Utilisez un dossier neuf et un moteur Docker autorisé pour vos essais.

L’archive contient compose.yaml, application.properties, init.sql, recette.py, un README et le rapport de référence. Le serveur Debezium est fixé à 3.7.0.Final. PostgreSQL utilise 16-alpine et Redis 7.2-alpine : ces deux tags peuvent évoluer. L’exécution publiée utilisait PostgreSQL 16.15 sur architecture ARM64 ; les identifiants des images observées sont fournis pour la traçabilité.

unzip recette-cdc.zip
cd recette-cdc
docker compose up -d
python3 recette.py

Ne lancez pas Python avec l’option -O, qui désactive les assertions de cette recette. Le script refuse une base dont les données initiales ont déjà été modifiées. Il est conçu pour une exécution sur un bac à sable neuf.

Le projet n’expose aucun port sur l’hôte. Il utilise un compte PostgreSQL de laboratoire, un mot de passe public et des volumes dédiés. Cette configuration facilite l’essai ; elle n’est pas une configuration de sécurité de production.

2. Comprendre les données et les opérations

La table commandes commence avec trois identifiants, pour 100, 200 et 300 euros. Les montants sont des entiers en centimes afin de rendre la référence exacte dans cet exemple.

Le script vérifie les trois événements de snapshot, puis exécute les modifications suivantes :

UPDATE commandes SET montant_centimes = 15000 WHERE id = 1;
DELETE FROM commandes WHERE id = 2;
INSERT INTO commandes VALUES (4, 7000, 'validee');

Il attend ensuite les identifiants 1, 3 et 4, pour un total de 52 000 centimes. Il vérifie aussi la présence d’un événement de suppression pour l’identifiant 2. Cette vérification sépare deux questions : le connecteur a-t-il transmis la suppression, et la projection l’a-t-elle appliquée ?

La documentation PostgreSQL de Debezium distingue l’événement op=d et un éventuel tombstone de transport. La disponibilité des anciennes colonnes dépend notamment de REPLICA IDENTITY. La projection utilise ici la clé de l’événement pour supprimer la ligne ; elle ne suppose pas que toutes les anciennes valeurs soient présentes. Connecteur PostgreSQL.

3. Écrire pendant l’arrêt du connecteur

Le programme arrête proprement le service Debezium, en laissant PostgreSQL et Redis fonctionner. Pendant cet arrêt, il passe la commande 4 à 80 euros et ajoute la commande 5 à 90 euros. Il redémarre ensuite le connecteur.

La position de lecture et les événements sont conservés dans Redis selon la configuration fournie. Le contrôle attend que les changements écrits pendant l’arrêt apparaissent. Il ne se contente pas de constater qu’un conteneur tourne.

Enfin, le script ajoute une colonne canal nullable et renseigne web sur la commande 1. Il attend cette valeur dans l’événement reçu. Il normalise les colonnes absentes des anciennes lignes vers null pour comparer l’état reconstruit au nouveau schéma.

4. Lire le résultat attendu

Le rapport de l’exécution locale contient le résultat suivant :

Contrôle Résultat observé
Événements du snapshot initial (r) 3
Créations (c), modifications (u), suppression (d) 2, 3, 1
Identifiants finaux 1, 3, 4, 5
Lignes finales 4
Somme finale 62 000 centimes, soit 620 euros fictifs
Comparaison source, projection et référence indépendante Identique

Les neuf événements de lignes ne doivent donc pas devenir neuf commandes. Aucun tombstone n’a été observé dans ce flux Redis lors de cette exécution ; la suppression est vérifiée par l’événement d et par l’absence de l’identifiant 2 dans le résultat.

Le contrôle compare toutes les lignes attendues. Deux erreurs de sens opposé pourraient conserver la même somme : le total seul serait insuffisant. La référence est écrite à partir du scénario, puis comparée séparément à PostgreSQL et à la projection.

5. Tester le rejeu sans surinterpréter le résultat

Le script duplique ensuite chaque événement reçu dans une liste locale et rejoue les doublons consécutivement. L’état final reste identique parce que les créations et modifications remplacent la valeur de la même clé, et que supprimer une clé absente ne rajoute rien.

Ce rejeu est une simulation locale. Le test n’a pas provoqué de panne pour obtenir de vrais doublons du connecteur. Il ne traite pas non plus des événements remis dans le désordre : une ancienne modification rejouée après une nouvelle pourrait écraser la bonne valeur.

La documentation décrit une livraison pouvant répéter des événements lors de certaines reprises. Cela oblige à préparer le consommateur, sans promettre une garantie universelle « exactly once ». Garanties du connecteur PostgreSQL.

6. Diagnostiquer et nettoyer

En cas d’échec, consultez docker compose logs debezium, l’état des services avec docker compose ps et les fichiers produits dans resultats/. Le délai d’attente de 45 secondes est une borne de cette recette, pas une promesse de latence du produit. Ne l’augmentez pas pour masquer une erreur de configuration.

Après avoir conservé votre rapport, cette commande supprime les conteneurs et les données du projet de laboratoire :

docker compose down --volumes

Exécutez-la depuis le dossier de cette recette, dont le nom de projet est dédié. Pour refaire l’essai, repartez de volumes neufs. Ne réutilisez pas ce nettoyage sur un projet contenant des données utiles.

Les contrôles à ajouter avant la production

La readiness observée était UP. Le test fonctionnel avait aussi réussi. Ces deux preuves répondent à des questions différentes : disponibilité du connecteur d’un côté, conformité des données de l’autre. Conservez au minimum le suivi du connecteur, le retard jusqu’à la cible et un rapprochement métier périodique.

Notre essai couvre un arrêt propre, pas un crash brutal, une perte de Redis, une bascule PostgreSQL ou une saturation. La projection Python est en mémoire et relit un petit flux complet. Elle n’est ni un consommateur durable ni un modèle de capacité pour une volumétrie d’entreprise.

Pour votre pilote, ajoutez une panne représentative, une restauration des positions et de la cible, puis la charge attendue. Définissez un délai de rattrapage acceptable et vérifiez que la rétention des journaux permet réellement ce rattrapage. Un slot PostgreSQL peut retenir du WAL ; son suivi fait partie de l’exploitation. Documentation PostgreSQL du connecteur.

Les permissions, les secrets et le réseau doivent être revus avec l’équipe qui exploite la base. Limitez les tables capturées au besoin réel et vérifiez également qui peut lire le flux, ses sauvegardes et ses exports. Dans la recette, les données sont fictives ; aucun transfert de données client n’a été nécessaire.

Coûts et décision de migration

Le dépôt Debezium est distribué sous licence Apache 2.0. Cette recette ne souscrit aucune offre Debezium hébergée. Cela ne rend pas un pipeline de production gratuit : base, stockage des journaux, transport, supervision et temps d’exploitation restent à budgéter. Les services managés et le support éventuel ont leurs propres conditions. Dépôt et licence Debezium.

Avant de généraliser, sélectionnez une table et un consommateur représentatifs. Exécutez le même scénario sur votre chaîne actuelle puis sur la candidate, avec les mêmes données et critères. Contrôlez les changements de types, les snapshots, la reprise et la stratégie de retour arrière. Un retour à l’ancienne image ne garantit pas à lui seul la compatibilité des états persistés.

Gardez le traitement existant si son délai satisfait le métier et que le CDC n’apporte pas de bénéfice mesurable. Si vous migrez, le premier livrable devrait être une preuve que les bonnes lignes arrivent dans la bonne cible. Le guide sur les reprises de pipelines complète cette recette pour les traitements qui consomment ensuite ces données.

Ressource gratuite

Checklist Audit IA 90 jours pour PME

Cadrage des process, données, cas d'usage, garde-fous RGPD/AI Act, quick wins, roadmap : 6 blocs et 28 points de contrôle, utilisables en autonomie. Reçue par email, sans séquence commerciale derrière.

Recevoir la checklist

Appliquer cette méthode à vos process

Votre équipe Data & IA externalisée, de 2 à 5 jours par semaine. L'atelier de cadrage inclus produit votre feuille de route priorisée par impact.