Cloudflare D1
Migrations
Schema
Deploy
SQLite

Migrationen in D1: Wie man ein Schema versioniert und was passiert, wenn es schief geht

Das Migrationssystem von D1 ist einfach und funktioniert gut – bis Sie eine Migration, die bereits in der Produktion ausgeführt wurde, rückgängig machen müssen und feststellen, dass es kein natives Rollback gibt.

Migrationen in D1: Wie man ein Schema versioniert und was passiert, wenn es schief geht

Das Migrationssystem von D1 wurde auf Einfachheit und nicht auf Sicherheit ausgelegt. Dateien .sql fortlaufend nummeriert, übernommen über wrangler d1 migrations apply, ohne Rollback. Im Vergleich zu Tools wie Flyway, Liquibase oder sogar dem Rails-Migrationssystem, die Downmigrationen und bidirektionale Versionierung ermöglichen, bietet D1 einen einseitigen Ablauf. Dies funktioniert gut, wenn die Migration gründlich getestet wurde und genau wie geplant verläuft. Wenn dies nicht der Fall ist, sind die Wiederherstellungsoptionen begrenzt und müssen vorbereitet werden, bevor das Problem auftritt, nicht während.

So funktioniert das Migrationssystem von D1

wrangler d1 migrations create NOME erstellt eine Datei .sql mit der Nummer im Projektverzeichnis migrations/. Die Nummer ist fortlaufend und bestimmt die Reihenfolge der Anwendung – 0001_create_users.sql, 0002_add_status_column.sql usw. Wrangler verfolgt in einer internen Tabelle namens D1_MIGRATIONS innerhalb der Datenbank selbst, welche Migrationen bereits angewendet wurden.

wrangler d1 migrations apply NOME_DO_BANCO wendet alle ausstehenden Migrationen der Reihe nach an. wrangler d1 migrations list --remote zeigt den aktuellen Status – welche angewendet wurden und welche ausstehen. Dieser Fluss reicht für die meisten Fälle aus.

Die strukturelle Einschränkung: Es gibt kein --rollback. Eine auf eine D1-Datenbank angewendete Migration kann nicht automatisch rückgängig gemacht werden. Wenn durch die Migration 0015 ein Fehler im Schema aufgetreten ist und Sie eine Wiederherstellung durchführen müssen, gibt es zwei Möglichkeiten. Die erste besteht darin, Migration 0016 zu schreiben, die manuell rückgängig macht, was 0015 getan hat – möglich für nicht destruktive Operationen wie das Hinzufügen einer Spalte, aber unmöglich für Operationen, die Daten löschen, wie DROP COLUMN oder DROP TABLE. Die zweite besteht darin, Time Travel von D1 zu verwenden, um die Datenbank auf einen Stand vor der Migration wiederherzustellen, der für kostenpflichtige Pläne mit einem 30-Tage-Fenster verfügbar ist.

Das Schemakonsistenzproblem am Rande

Die D1-Replikation birgt ein Bereitstellungsrisiko, das bei herkömmlichen Banken nicht besteht: Die Migration kann auf dem Primärserver erfolgen, während die Replikate weiterhin das alte Schema laden. Ein Worker, der von einem veralteten Replikat liest, führt Abfragen für ein anderes Schema als erwartet aus.

Das konkrete Szenario: Sie fügen die Spalte status zur Tabelle orders mit der Migration 0020 hinzu. Die Migration wird auf dem Primärserver ausgeführt. Gleichzeitig stellen Sie den aktualisierten Worker bereit, der SELECT status FROM orders ergibt. Eine Anfrage, die ein Replikat trifft, das die Migration noch nicht erhalten hat, schlägt mit einem unbekannten Spaltenfehler fehl – ​​selbst wenn die Bereitstellung gut verlief und die Primärdatenbank bereits über das richtige Schema verfügt.

Das Ausbreitungsintervall kann 60 Sekunden erreichen. Die Lösung besteht darin, die Bereitstellung der Migration von der Bereitstellung des Codes zu trennen. Der richtige Ablauf: Wenden Sie die Migration an, warten Sie explizit mindestens 60 Sekunden und stellen Sie dann die neue Version des Workers bereit. Diese Wartezeit muss in die CI/CD-Pipeline integriert werden – der wrangler deploy verfügt nicht über das Flag „Warten auf Schemapropagierung“, daher müssen Sie diese Verzögerung manuell erstellen. In den allermeisten Fällen reicht ein sleep 60 zwischen den beiden Pipeline-Schritten aus.

Playbook für sichere Migrationen in der Produktion

Bevor Sie eine Migration auf eine Produktionsdatenbank anwenden, exportieren Sie einen vollständigen Dump: wrangler d1 export --remote --database NOME_DO_BANCO --output backup-$(date +%Y%m%d-%H%M).sql. Diese Datei ist Ihr manueller Wiederherstellungspfad für den Fall, dass etwas schief geht und Time Travel nicht verfügbar oder nicht ausreichend ist.

Testen Sie die Migration in einer Staging-Datenbank mit Daten, deren Volumen der Produktion entspricht. Eine Migration, die bei einer Tabelle mit 1.000 Zeilen in 50 ms ausgeführt wird, kann bei einer Tabelle mit 5 Millionen Zeilen 20 Sekunden dauern – und während dieser 20 Sekunden ist die Datenbank möglicherweise nicht für Abfragen verfügbar, die von der geänderten Tabelle abhängen. D1 verfügt nicht über eine Neuindizierung im Hintergrund wie PostgreSQL mit CREATE INDEX CONCURRENTLY.

Für Schemaänderungen, die keine Ausfallzeiten erfordern, verwenden Sie das phasenweise Bereitstellungsmuster. Um eine Spalte umzubenennen, führen Sie den Vorgang in unabhängigen Schritten aus: Fügen Sie zunächst die neue Spalte als Nullable hinzu. Zweitens stellen Sie den Code bereit, den Sie in beiden Spalten (alt und neu) schreiben. drittens ein Backfill-Job, der Daten aus der alten in die neue Spalte in vorhandenen Datensätzen kopiert; Viertens: Aktualisieren Sie den Code so, dass er nur aus der neuen Spalte gelesen werden kann. Fünftens: Entfernen Sie die alte Spalte bei einer nachfolgenden Migration. Durch die Kombination all dieser Schritte in einer einzigen Migration entsteht ein Zeitfenster der Inkonsistenz und ein teilweises Rollback ist nicht möglich.

Migrationen lokal testen, bevor sie in die Produktion gehen

wrangler dev --local erstellt eine echte SQLite-Datei in .wrangler/state/v3/d1/. Sie können mit wrangler d1 migrations apply NOME --local Migrationen für diese Datei anwenden, sie direkt mit dem sqlite3-Client überprüfen und EXPLAIN QUERY PLAN für die Abfragen ausführen, um vor jeder Bereitstellung zu überprüfen, ob die Indizes korrekt verwendet werden.

Die Lücke zwischen lokal und remote ist die Replikation. Die lokale Umgebung ist eine reine SQLite-Instanz ohne Primärschicht und Replikate – eventuelle Konsistenzprobleme werden in lokalen Tests nicht angezeigt. Um diese Lücke zu schließen, erstellen Sie eine separate D1-Staging-Bank in Ihrem Cloudflare-Konto, wenden Sie dort zunächst Migrationen an und validieren Sie das Verhalten mit Daten, die ungefähr dem Produktionsvolumen entsprechen.

Zeitreisen sind Plan B, wenn alles andere fehlschlägt. Mit wrangler d1 time-travel restore --timestamp="2026-10-07T08:00:00Z" wird die Bank innerhalb eines 30-Tage-Fensters bei kostenpflichtigen Plänen auf den Stand zu diesem Zeitpunkt zurückgesetzt. Dadurch werden durch destruktive Migrationen gelöschte Daten wiederhergestellt und Schemaänderungen rückgängig gemacht, die durch eine Vorwärtsmigration nicht rückgängig gemacht werden können. Der Vorgang ersetzt den Zustand der gesamten Datenbank – es erfolgt keine selektive Wiederherstellung bestimmter Tabellen. Wenn durch die Migration eine Tabelle beschädigt wurde, andere Tabellen jedoch in dem Intervall normale Aktivität aufwiesen, werden durch die Wiederherstellung auch diese anderen Tabellen auf ihren vorherigen Zustand zurückgesetzt.

Lesen Sie auch