SQLite a traîné un bug de corruption pendant 16 ans. Voici pourquoi vous n'êtes probablement pas touché, et ce qu'il faut vérifier quand même.

Cette semaine, Tailscale a publié un post-mortem que chaque équipe utilisant SQLite devrait lire. Pendant six mois, à partir du mois d'août dernier, leur plan de contrôle ne cessait de corrompre des bases de données. Dix-neuf incidents distincts, aucun déclencheur évident, aucun changement de code récent ne permettant de l'expliquer. La cause s'est avérée être une course de données présente dans SQLite depuis la version 3.7.0, livrée en juillet 2010. Elle s'y est cachée pendant environ seize ans.

L'équipe SQLite l'appelle le bug de réinitialisation WAL. Il ne touche que les bases de données fonctionnant en mode WAL (write-ahead logging) lorsque deux connexions ou plus ont le même fichier ouvert sur des threads ou des processus séparés, et qu'elles tentent d'écrire ou d'exécuter un point de contrôle au même instant. Lorsque le moment est propice, un point de contrôle peut laisser un indicateur dans l'index WAL affirmant qu'une partie du journal a déjà été copiée dans le fichier de base de données principal alors que ce n'est pas le cas. Un point de contrôle ultérieur ignore alors ces données, et le fichier se corrompt. Le bug a été corrigé dans SQLite 3.51.3 le 13 mars 2026, avec des rétroports vers les versions 3.44.6 et 3.50.7.

Voici la partie sur laquelle il vaut la peine de s'attarder. Les développeurs de SQLite n'ont pas pu reproduire ce bug intentionnellement. Ils ont dû modifier leur propre code source pour déclencher un callback au moment précisément inapproprié lors d'un point de contrôle. Leur propre télémétrie situe le taux d'occurrence réel au niveau ou en dessous du taux de pannes de SSD et de retournements de bits dus aux rayons cosmiques. Donc si vous exécutez SQLite dans une configuration normale, vous n'avez presque certainement jamais été affecté, et vous ne l'êtes probablement pas encore. Tailscale a été touché parce qu'ils ont pris le contrôle manuel des points de contrôle et les ont exécutés de manière agressive pour des sauvegardes rapides. Ils ont quitté le chemin bien balisé, et une course sur un milliard est devenue un événement mensuel.

Ce que nous ferions vraiment à ce sujet

Mettez à jour, mais ne paniquez pas. Passez à SQLite 3.51.3 ou une version plus récente, ou l'un des rétroports, selon votre propre calendrier. Le problème est que « votre version de SQLite » est rarement évidente. SQLite est intégré presque partout, et vous ne l'installez pas directement. Il est fourni dans votre environnement d'exécution de langage, votre ORM, votre système d'exploitation mobile et votre plateforme edge.

Dans notre travail natif iOS et Android, c'est la chose la plus facile à oublier. Le SQLite système est lié à la version du système d'exploitation que vos utilisateurs exécutent, pas à la version contre laquelle vous avez compilé, et vous n'avez pas le contrôle du moment où ils mettent à jour. Si votre application fait quelque chose d'inhabituel avec les connexions ou les points de contrôle — disons un thread de synchronisation en arrière-plan qui écrit pendant que l'interface utilisateur lit — intégrez votre propre build SQLite afin de contrôler la version plutôt que d'hériter de ce que l'appareil embarque. Nous l'avons fait exactement dans des applications de santé hors ligne et IoT, où un stockage local corrompu signifie des données que l'utilisateur ne pourra jamais récupérer.

Du côté backend et edge, vérifiez contre quoi votre pilote est réellement lié. D'après notre travail avec PHP et Docker, la version de SQLite intégrée dans une image de base peut prendre du retard de plusieurs mois sur l'upstream, et « nous utilisons le dernier framework » ne vous dit rien sur la bibliothèque C en dessous. SQLite serverless et edge — à savoir D1, Turso, LiteFS et consorts — mérite un regard particulier, car ces plateformes s'appuient fortement sur le mode WAL et l'accès concurrent. C'est exactement le profil de conditions que ce bug requiert.

La leçon la plus importante concerne les sauvegardes

Le détail qui m'a marqué n'est pas la course de données. C'est que Tailscale n'a remarqué le problème que parce qu'un pipeline séparé lisait leurs sauvegardes S3 et exécutait PRAGMA integrity_check dessus. Leurs bases de données actives semblaient saines. La corruption se trouvait déjà dans les fichiers qu'ils conservaient pour plus tard.

Lors de nos engagements en sécurité et en tests de pénétration, les sauvegardes sont l'endroit où nous trouvons les lacunes les plus alarmantes. Les équipes les effectuent religieusement et ne les restaurent jamais. Une sauvegarde que vous n'avez pas restaurée est une hypothèse, pas un filet de sécurité. Si vous stockez des fichiers SQLite, exécutez PRAGMA integrity_check sur une copie selon un calendrier régulier, et restaurez réellement dans un environnement de test de temps en temps. Une corruption qui n'apparaît que le jour où vous avez besoin de la sauvegarde est la pire façon d'apprendre cette leçon.

Encore une chose dans le rapport qu'il est facile de manquer. Après que Tailscale a déployé le correctif, un changement d'arrondi dans la version a déclenché de faux avertissements de corruption sur des bases de données utilisant des index d'expression. Ils l'ont détecté parce qu'ils ont d'abord déployé sur quelques fragments canary, puis sur le reste. Les déploiements progressifs ne sont pas de la bureaucratie. C'est ainsi que vous trouvez le deuxième bug que le correctif du premier bug a introduit.

Ce que vous pouvez faire cette semaine

Découvrez quelle version de SQLite vos systèmes de production et vos applications déployées exécutent vraiment. Pas la version du framework, la bibliothèque SQLite réelle. Ensuite, prenez une sauvegarde et prouvez que vous pouvez la restaurer proprement. C'est un après-midi de travail, et pour la plupart des équipes, ça vaut plus que la mise à jour elle-même.

Si savoir quelle version de SQLite vos applications et services exécutent réellement, et si vos sauvegardes survivraient à une restauration, vous parle, parlons-en.

databasesexpert-analysissoftware-developmentsqlitetech-news