DevOps & Monitoring

Facet-Ingenieure beheben Bug für stillen Datenverlust im mandantenfähigen SQLite-Backup-System

Entwickler von Facet entdeckten einen Logikfehler in ihrem Point-in-Time-Wiederherstellungssystem, der veraltete Daten liefern konnte. Sie korrigierten die Epoch-Verarbeitung, um zeitlicher Genauigkeit Vorrang vor Sequenznummern zu geben.

Server racks under a glass dome with amber warning lights indicating a system alert.
Für diesen Artikel erstellte Illustration

Automatisch aus dem englischen Original übersetzt.

Facet, eine auf Go und SQLite basierende Plattform für Creator, hat kürzlich einen kritischen Fehler in ihrem Point-in-Time-Wiederherstellungsmechanismus (PITR) identifiziert und behoben. Der im Oktober 2026 entdeckte Fehler führte dazu, dass das System bei Wiederherstellungsvorgängen fälschlicherweise veraltete Datenbank-Snapshots auswählte. Die Ingenieure implementierten eine dreiteilige Lösung, um sicherzustellen, dass sich Wiederherstellungen auf Zeitstempel statt auf einfache Sequenzzähler stützen, wodurch ein stiller Datenrückgang für Mandanten verhindert wird.

Was passiert ist

Facet betreibt eine mandantenfähige Plattform, bei der jeder Creator eine isolierte SQLite-Datenbank erhält. Um granulare Wiederherstellungsoptionen ohne prohibitiv hohe Kosten anzubieten, entwickelte das Team einen eigenen Backup-Shipper, der direkt in den Anwendungsprozess integriert ist. Dieses System lädt unveränderliche Snapshot- und Write-Ahead-Log-(WAL)-Segmente in den Cloudflare-R2-Speicher hoch. Jedes Objekt enthält einen signierten Header mit einer Sequenznummer und einem Hash des vorherigen Objekts, was eine überprüfbare Chain of Custody für die Daten jedes Mandanten schafft.

Das Engineering-Team stellte kürzlich fest, dass mehrere Demo-Seiten nach der Migration von einer Staging-Umgebung in die Produktion auf veraltete Datenketten verwiesen. Die Staging-Hosts hatten lokale Statusdateien mit hohen Epoch-Nummern beibehalten, während die neuen Produktionsinstanzen bei Epoch eins frisch starteten. Da die Wiederherstellungslogik unabhängig vom Zeitpunkt der Datenschreibung die höchste Epoch-Nummer priorisierte, hätte das System die Seiten auf ihren Stand von Ende September anstelle der aktuellen Live-Version wiederhergestellt. Dies geschah, obwohl alle einzelnen Backup-Objekte die Integritätsprüfungen bestanden hatten, da der Fehler in der Auswahlllogik lag und nicht in einer Datenkorruption.

Zur Lösung dieses Problems stellte das Team drei spezifische Änderungen in der Produktionsumgebung bereit. Erstens wurde die Epoch-Zuweisung so modifiziert, dass sie die Remote-Historie prüft, bevor neue Sequenznummern zugewiesen werden, was verhindert, dass lokale Statusdateien konfliktbehaftete Ketten erzeugen. Zweitens wählt der Wiederherstellungsplaner nun Epochen basierend auf ihrer zeitlichen Relevanz für den Zielzeitpunkt der Wiederherstellung aus, nicht nur anhand ihrer numerischen Höhe. Schließlich verweigert das System jetzt explizit die Wiederherstellung, wenn es eine invertierte Chronologie erkennt, und zwingt Operatoren dazu, mehrdeutige Zeitlinien zu klären, anstatt zu raten.

Wichtige Details

  • Das Backup-System kostet etwa $0,0034 pro Mandant und Monat durch die Nutzung änderungsgetriebener Uploads, die inaktive Datenbanken überspringen.
  • Jedes Backup-Objekt ist unveränderlich und enthält einen SHA-256-Hash des vorherigen Objekts, was eine Verifizierung ohne zentralen Index ermöglicht.
  • Der Bug führte dazu, dass der Wiederherstellungsplaner veraltete Ketten mit höheren Epoch-Nummern aus früheren Staging-Umgebungen auswählte.
  • Zu den Fixes gehören die Zuweisung von Epochen gegen die Remote-Historie sowie die Verweigerung von Wiederherstellungen bei invertierter Chronologie.
  • Tests nach dem Fix zeigten, dass eine Demo-Seite mit 79 WAL-Segmenten erfolgreich in 2 Minuten und 34 Sekunden wiederhergestellt wurde.
  • Das System deaktiviert das automatische SQLite-Checkpointing für versendete Mandanten, um Schreibkonflikte mit dem internen Shipper zu verhindern.

Hintergrund

Point-in-Time Restore (PITR) ermöglicht es Administratoren, eine Datenbank zu jedem bestimmten Moment wiederherzustellen, nicht nur zum Zeitpunkt des letzten vollständigen Backups. Bei SQLite umfasst dies typischerweise die Kombination eines Basis-Snapshots mit einer Reihe von WAL-Segmenten, die jede Änderung seit diesem Snapshot protokollieren. Facets Ansatz vermeidet externe Tools wie Litestream, indem die Backup-Logik innerhalb desselben Go-Prozesses ausgeführt wird, der die Datenbank bedient. Dies stellt sicher, dass das Backup-System Lebenszyklusereignisse von Mandanten wie Hibernation oder Migration kennt, die externe Sidecars möglicherweise übersehen würden.

Der Begriff „Epoch“ bezieht sich in diesem Kontext auf einen distincten Zeitraum in der Backup-Kette. Epochen werden zurückgesetzt, wenn die Kontinuität nicht garantiert werden kann, beispielsweise nach einer Host-Migration. Durch die Verkettung dieser Epochen mit kryptografischen Hashes stellt das System sicher, dass jede Lücke oder Manipulation erkennbar ist. Die Verwaltung dieser Epochen über verschiedene Umgebungen hinweg erfordert jedoch sorgfältige Koordination, um sicherzustellen, dass neuere Nummern immer neueren Daten entsprechen – eine Annahme, die beim jüngsten Vorfall fehlschlug.

Warum das wichtig ist

Für Teams, die Self-Hosted-Software betreiben oder mandantenfähige Architekturen verwalten, verdeutlicht dieser Vorfall die Risiken, die entstehen, wenn verteilte Systeme auf lokalen Status vertrauen. Wenn Anwendungen zwischen Hosts oder Umgebungen migriert werden, können übrig gebliebene Metadaten Konflikte verursachen, die schwer zu erkennen sind, bis ein Wiederherstellungsversuch unternommen wird. Die Erfahrung des Facet-Teams zeigt, dass selbst robuste Integritätsprüfungen einzelner Dateien logische Fehler bei deren Zusammenführung während der Wiederherstellung nicht verhindern können.

Die Kosteneffizienz ihres Modells bietet zudem eine Blaupause für kleine und mittelständische Unternehmen. Durch die Abrechnung nur für tatsächliche Schreibvorgänge und das Überspringen inaktiver Mandanten erreichten sie einen Preis, der PITR für jeden Nutzer praktikabel macht, nicht nur für Enterprise-Kunden. Dies demonstriert, dass granulare Backup-Strategien nicht unbedingt teure Infrastruktur erfordern, wenn die Softwarearchitektur mit dem Preismodell des Speicheranbieters übereinstimmt.

Darüber hinaus ist die Entscheidung, bei mehrdeutigen Daten lautstark zu scheitern, eine entscheidende Lektion in Sachen Reliability Engineering. Viele Systeme könnten versuchen, die richtige Kette zu erraten, wobei sie potenziell korrupte oder veraltete Daten ausliefern, ohne den Nutzer zu warnen. Facets Wahl, die Wiederherstellung zu blockieren und manuelle Eingriffe zu verlangen, stellt sicher, dass die Datenintegrität niemals zugunsten der Verfügbarkeit kompromittiert wird.

Was Sie tun können

  • Überprüfen Sie Ihre Backup-Auswahllogik daraufhin, ob sie bei Konfliktauflösungen Zeitstempeln gegenüber Sequenznummern Vorrang gibt.
  • Implementieren Sie änderungsgetriebene Upload-Mechanismen, um Speicherkosten für inaktive Datenbanken in mandantenfähigen Setups zu senken.
  • Verifizieren Sie die Backup-Integrität, indem Sie bei regelmäßigen Übungen die Anzahl der Zeilen in wiederhergestellten Tabellen mit denen der Live-Datenbanken vergleichen.
  • Stellen Sie sicher, dass Backup-Prozesse Lebenszyklusereignisse von Mandanten wie Migrationen kennen, um Desynchronisationen des Status zu verhindern.
  • Konfigurieren Sie Systeme so, dass sie mehrdeutige Wiederherstellungen ablehnen, anstatt zu versuchen, die richtige Datenkette zu erraten.
  • Speichern Sie Backup-Metadaten remote, anstatt sich ausschließlich auf lokale Kopien zu verlassen.

Weitere News

Alle News