12 points par GN⁺ 2025-12-13 | 1 commentaires | Partager sur WhatsApp
  • Litestream VFS est une extension sous forme de plugin qui permet de lire et d’interroger directement une base de données SQLite depuis un stockage objet (comme S3)
  • Permet d’effectuer des requêtes immédiates sur des fichiers de sauvegarde distants et une restauration à un instant donné (Point-in-Time Recovery, PITR) sans télécharger toute la base de données
  • Utilise en interne le format LTX pour gérer efficacement les ensembles de pages modifiées, et améliore la vitesse de restauration grâce à une compaction qui ignore les pages dupliquées
  • Exploite l’interface VFS de SQLite pour n’intercepter que les opérations de lecture, tandis que l’écriture reste prise en charge par le processus Litestream existant
  • Grâce à des sauvegardes à la seconde et à des mises à jour d’index, fournit une réplique quasi temps réel, adaptée à l’exécution rapide de requêtes dans le cloud

Présentation de Litestream VFS

  • Litestream VFS permet à SQLite d’utiliser directement une URL de stockage objet comme source de données
    • S’active dans le shell SQLite avec les commandes .load litestream.so et .open file:///my.db?vfs=litestream
    • Il devient ensuite possible d’exécuter des requêtes à partir de fichiers de sauvegarde stockés sur S3
  • Il est possible d’interroger directement une sauvegarde distante sans télécharger toute la base de données
    • Dans l’exemple, la requête SELECT * FROM sandwich_ratings permet de consulter immédiatement une partie des données stockées sur S3

Fonction de restauration à un instant donné (PITR)

  • La commande PRAGMA litestream_time = '5 minutes ago'; permet de consulter l’état des données à un instant précis
    • Il est possible de spécifier une heure relative (5 minutes ago) ou absolue (2000-01-01T00:00:00Z)
  • Cela permet d’effectuer une restauration instantanée à un instant donné (Point-in-Time Recovery) au niveau SQL
    • Dans l’exemple, après l’exécution d’un UPDATE erroné, un retour à l’état d’il y a 5 minutes permet de vérifier les données correctes

Format LTX et compression des données

  • Litestream v0.5 intègre le format LTX (Litestream Transaction eXchange)
    • Les versions précédentes transféraient des pages SQLite entières, tandis que LTX ne transfère qu’un ensemble ordonné de pages
  • L’élément clé de LTX est la fonction « compaction », qui sélectionne uniquement la version la plus récente de chaque page lors de la restauration
    • Exemple : dans 1 2 3 5 3 5 4 5 5, seules les occurrences les plus à droite de 5, 4, 3, 2 et 1 sont utilisées
  • LTX peut être compressé non seulement pour une base complète, mais aussi entre des ensembles de fichiers LTX, ce qui rend possible la restauration PITR
  • Le trailer des fichiers LTX contient un index des offsets de chaque page, ce qui permet de
    • lire uniquement les pages nécessaires via des requêtes S3 Range sans télécharger le fichier entier

Méthode d’implémentation du VFS

  • Litestream VFS est implémenté à l’aide de l’interface VFS (Virtual File System) de SQLite
    • Le VFS est une structure de plugin qui abstrait la couche d’accès à l’OS de SQLite
  • Litestream VFS ne traite que les opérations de lecture (Read), tandis que les opérations d’écriture (Write) sont prises en charge par le processus Litestream existant
  • Lorsque SQLite lit une page, le VFS effectue un mappage basé sur l’index des pages au lieu d’utiliser directement l’offset en octets demandé
    • Il retrouve dans l’index le nom du fichier, l’offset réel et la taille de page, puis télécharge uniquement le bloc concerné via l’en-tête Range de l’API S3
  • Un cache LRU conserve en mémoire les « hot pages » fréquemment consultées afin de minimiser les appels à S3

Réplication en temps réel et performances

  • Litestream effectue une sauvegarde de niveau L0 une fois par seconde
    • Le VFS interroge périodiquement le chemin S3 et met à jour progressivement l’index
    • Il en résulte une réplique quasi temps réel (near-realtime replica)
  • L’utilisation est immédiate, sans avoir à streamer l’intégralité de la base de données
  • Cette architecture permet d’obtenir un démarrage rapide et des temps de restauration courts

Usages et intérêt

  • Litestream conserve en sauvegarde tous les états de la base de données avec une résolution à la seconde
    • En cas d’erreur de DELETE ou de UPDATE, il est possible de restaurer immédiatement l’instant souhaité
  • L’interrogation directe depuis un stockage objet permet un fonctionnement rapide même dans des environnements de serveurs éphémères
  • En s’appuyant sur les fonctions natives de SQLite sans mécanismes complexes, il fournit un système de sauvegarde et de restauration simple mais puissant
  • Il est aussi utilisé dans l’API interne de Fly.io et peut être exploité de manière stable en production

1 commentaires

 
GN⁺ 2025-12-13
Commentaires Hacker News
  • Oh, ça utilise le module sqlite vfs pour Go que j’ai créé
    Ça me fait toujours vraiment plaisir de voir que le code que j’ai écrit aide d’autres personnes
    psanford/sqlite3vfs
    • Ça a bien marché. Merci pour ça
    • Au fond, c’est ce genre de moment qu’on recherche dans la vie
  • C’est vraiment génial. Litestream VFS incarne parfaitement la philosophie Unix
    SQLite fonctionne comme d’habitude, et Litestream opère de manière transparente par-dessus
    Autrement dit, on peut mettre en place une restauration à un instant donné (PITR) uniquement avec SQL et les pragma SQLite.
    On peut consulter rapidement des données passées sans toucher directement au dataset de production
  • Le design de l’interface est vraiment propre
    Il suffit de définir le bucket S3 via une variable d’environnement, puis dans SQLite de faire .load litestream.so et
    avec PRAGMA litestream_time = '5 minutes ago'; on peut consulter directement les données à un instant passé
    • Sur macOS, après brew install sqlite3,
      il faut indiquer explicitement le nom de la fonction d’initialisation comme dans .load litestream sqlite3_litestreamvfs_init
  • J’ai aussi réussi à le faire fonctionner avec bun:sqlite
    Il suffit de définir "LITESTREAM_REPLICA_URL" et les variables d’environnement des clés AWS
    Après avoir chargé l’extension avec temp.loadExtension("/path/to/litestream.dylib", "sqlite3_litestreamvfs_init"),
    on peut l’utiliser immédiatement en ouvrant file:my.db?vfs=litestream
    • Je me demande si c’est surtout prévu pour des environnements de serveur JavaScript (bun)
    • Super que ça ait bien marché. En revanche, je me demande comment tu as trouvé le chemin du fichier .dylib
    • À noter : dans cet exemple, la partie configuration des variables d’environnement ne fonctionne pas avec dotenv. Il faut impérativement les définir directement au lancement
  • C’est une fonctionnalité vraiment sympa.
    Mon cas d’usage consiste à utiliser directement sur un site web une base SQLite en lecture seule stockée sur S3
    La base est mise à jour via une tâche cron, etc., et le site ne fait que lire les données les plus récentes via Litestream VFS
    Je me demande si ce type d’usage est acceptable, et s’il existe aussi un module d’intégration Python
    Pour l’instant, mon appli Flask récupère les données depuis Google Spreadsheet, les convertit en SQLite puis les met à jour chaque jour
    Voir le code de mon appli
    • Auteur ici. Litestream VFS interroge automatiquement les données de sauvegarde toutes les secondes pour rester à jour
      Ça fonctionne tel quel même dans le CLI SQLite, sans code Python supplémentaire
    • Je recommande aussi ZeroFS pour un usage similaire
      Il n’utilise que S3 comme dépendance externe et s’accorde bien avec SQLite
      Référence sur les performances SQLite de ZeroFS
  • Je l’ai déjà implémenté aussi dans un driver SQLite pour Go
    Exemple de code ncruces/go-sqlite3
    On peut le piloter depuis le code du programme sans variable d’environnement, et gérer plusieurs bases en parallèle
    Attention toutefois : PRAGMA litestream_time s’applique au niveau de la connexion, donc il faut faire attention si on utilise un pool de connexions
    • En voyant .load litestream.so, j’ai immédiatement pensé à ncruces/go-sqlite3
      Je me demande si ça a été difficile de le faire fonctionner aussi dans un environnement wasm
  • En ce moment j’apprends DuckDB et je ressens bien les différences avec SQLite
    L’extension “DuckLake” de DuckDB crée un snapshot à chaque transaction et fournit une fonction de “voyage temporel”
    C’est similaire au PITR de Litestream VFS
    En OLTP, on appelle cela une fonction de restauration, alors qu’en OLAP on parle de “Time Travel”
    DuckLake s’appuie sur une base de catalogue externe (PostgreSQL/MySQL/SQLite) pour coordonner les accès multi-processus
    Litestream, lui, permet à plusieurs lecteurs d’accéder simultanément via les fichiers LTX immuables sur S3
    Dans les deux mondes, on converge vers une structure de type “stockage partagé + métadonnées + compaction”
    J’aimerais voir davantage de collaboration croisée entre ce genre de projets
  • En tant qu’amateur de sandwichs, je suis vraiment curieux de connaître ces données de notation de sandwichs
  • C’est intéressant, mais je ne comprends pas très bien quel logiciel a exactement été annoncé. C’est une nouvelle version de Litestream ?
    • Auteur ici. Oui, Litestream v0.5.3 vient de sortir, avec une nouvelle option VFS en lecture seule
      Notes de version v0.5.3
    • Cette version inclut aussi la prise en charge de la réplication de répertoires pour les bases multi-tenant. C’est un excellent ajout
  • Je me demande si ça fonctionne aussi avec les extensions SQLite
    Par exemple, si on utilise des extensions de recherche vectorielle comme sqlite-vec ou vss,
    est-ce qu’on peut faire des sauvegardes en temps réel vers S3 avec Litestream puis interroger à distance via Litestream VFS ?
    • Je me pose la même question. A priori, si les requêtes s’exécutent en local et que les données nécessaires sont récupérées depuis S3 page par page, ça devrait simplement fonctionner
      J’imagine qu’il n’y a pas d’autre choix que de le tester directement
    • Oui, c’est possible (c’est tout)