ProCust
Datenbank-Migrationen ohne Downtime: So gelingt das Update

Datenbank-Migrationen ohne Downtime: So gelingt das Update

Wie Sie Datenbank-Migrationen ohne Ausfallzeit durchführen: Expand-and-Contract, Sperren vermeiden, Daten in Etappen migrieren und sicher zurückrollen.

Kurz gefasst: Datenbank-Migrationen ohne Downtime gelingen, wenn jede Änderung am Schema mit der alten und der neuen Version Ihrer Anwendung gleichzeitig funktioniert. Das Standardverfahren heißt Expand-and-Contract: erst erweitern, dann Daten umziehen, dann den Code umstellen und erst ganz am Ende das Alte entfernen. Dazu kommen Befehle, die keine langen Tabellensperren auslösen, und Datenmigrationen in kleinen Etappen statt in einem großen Schritt.

Warum Migrationen Ausfälle verursachen

Bei einem Deployment laufen für kurze Zeit alte und neue Instanzen Ihrer Anwendung parallel, vor allem bei Rolling Deployments mit mehreren Servern oder Containern. Benennt eine Migration eine Spalte um, findet der alte Code sie nicht mehr und wirft Fehler. Das ist die erste typische Ursache.

Die zweite ist das Sperrverhalten der Datenbank. Manche Schemaänderungen brauchen eine exklusive Sperre auf der Tabelle. Solange diese gehalten wird, warten alle Lese- und Schreibzugriffe. Bei einer kleinen Tabelle merkt das niemand, bei einer Tabelle mit Millionen Zeilen steht die Anwendung womöglich minutenlang. Noch tückischer: Wartet die Migration selbst auf eine Sperre, stauen sich hinter ihr alle weiteren Anfragen.

Das Expand-and-Contract-Muster

Phase 1: Erweitern

Sie fügen Neues hinzu, ohne Bestehendes zu verändern. Statt eine Spalte name in full_name umzubenennen, legen Sie full_name zusätzlich an. Die neue Spalte ist zunächst optional, damit der alte Code weiter Zeilen einfügen kann.

Phase 2: Doppelt schreiben und Daten nachziehen

Die Anwendung schreibt ab jetzt in beide Spalten. Parallel füllt ein Hintergrundjob die neue Spalte für alle bestehenden Zeilen, in kleinen Paketen von einigen tausend Zeilen mit kurzen Pausen dazwischen. So bleiben Transaktionen kurz und die Last kontrollierbar.

Phase 3: Umstellen

Sobald alle Daten übertragen sind, liest der Code nur noch aus der neuen Spalte. Jetzt können Sie auch Pflichtfelder und Constraints ergänzen.

Phase 4: Aufräumen

Erst wenn sicher ist, dass keine Version der Anwendung die alte Spalte mehr nutzt, wird sie in einem eigenen Deployment entfernt. Diese Trennung ist der Kern des Musters: Jeder Schritt lässt sich einzeln ausrollen und notfalls zurücknehmen.

Sperren vermeiden am Beispiel PostgreSQL

Viele Datenbanken bieten Varianten, die ohne lange Sperre auskommen. In PostgreSQL legen Sie Indizes mit CREATE INDEX CONCURRENTLY an, damit Schreibzugriffe weiterlaufen. Fremdschlüssel und Check-Constraints fügen Sie zunächst mit NOT VALID hinzu und prüfen sie anschließend mit VALIDATE CONSTRAINT, was eine schwächere Sperre braucht. Eine neue Spalte mit konstantem Standardwert ist seit PostgreSQL 11 eine reine Metadatenänderung und damit schnell.

Setzen Sie außerdem einen lock_timeout für Migrationen. Bekommt die Migration ihre Sperre nicht innerhalb weniger Sekunden, bricht sie ab, statt die gesamte Anwendung zu blockieren. Sie wiederholen sie dann zu einem ruhigeren Zeitpunkt. Welche Datenbank für Ihr Projekt passt, beleuchtet unser Leitfaden zur Datenbankauswahl.

Migrationen in den Deployment-Prozess einbauen

Migrationen gehören versioniert ins Repository, zusammen mit dem Code. Werkzeuge wie Prisma Migrate, Flyway, Liquibase oder die Migrationen Ihres ORMs halten fest, welche Änderung bereits angewendet wurde. In der CI/CD-Pipeline laufen sie automatisch, idealerweise zuerst gegen eine Staging-Datenbank mit realistischer Datenmenge. Wie eine solche Pipeline aussieht, zeigen wir in unserem praktischen Leitfaden zu CI/CD.

Vor jeder größeren Migration sollte ein aktuelles Backup vorliegen, das Sie auch schon einmal zurückgespielt haben. Während und nach dem Rollout beobachten Sie Fehlerraten, Antwortzeiten und Datenbanksperren. Ein gutes Monitoring für Web-Anwendungen zeigt Probleme, bevor Nutzer sie melden.

Häufige Fragen (FAQ)

Brauche ich für jede Schemaänderung Expand-and-Contract?

Nein. Eine neue optionale Spalte oder eine neue Tabelle ist von Haus aus abwärtskompatibel und kann direkt ausgerollt werden. Das Muster lohnt sich bei allem, was bestehende Strukturen verändert oder entfernt: Umbenennungen, Typänderungen, neue Pflichtfelder.

Wie rolle ich eine fehlgeschlagene Migration zurück?

Bei Expand-and-Contract ist jeder Schritt klein und rückwärtskompatibel, deshalb reicht meist ein Zurücksetzen des Codes. Destruktive Schritte wie das Löschen einer Spalte kommen erst ganz am Ende, wenn ein Rollback nicht mehr nötig ist. Für den Notfall bleibt das geprüfte Backup.

Ist ein Wartungsfenster nicht einfacher?

Für interne Systeme mit festen Arbeitszeiten kann ein Wartungsfenster eine vertretbare Lösung sein. Bei Shops, Kundenportalen oder SaaS-Produkten, die rund um die Uhr erreichbar sein sollen, ist der Aufwand für Migrationen ohne Downtime gut investiert.

Wie lange dauert eine Migration in mehreren Phasen?

Das hängt von der Datenmenge und Ihrem Release-Rhythmus ab. Oft verteilen sich die Phasen auf mehrere Deployments über einige Tage. Das wirkt umständlich, ist aber deutlich risikoärmer als ein einziger großer Schritt.

Fazit

Ausfallfreie Datenbank-Migrationen sind weniger eine Frage des Werkzeugs als der Disziplin: kleine, kompatible Schritte, sperrarme Befehle und Aufräumen erst zum Schluss. Wer das einmal als Teamroutine etabliert, verliert die Angst vor Schemaänderungen und kann seine Anwendung deutlich öfter weiterentwickeln.

Wenn Sie eine Anwendung mit wachsender Datenbank betreiben oder neu aufsetzen, unterstützen wir Sie gern im Rahmen unserer Webentwicklung.