Warum Datenbank-Deployments schwieriger sind als Anwendungs-Deployments
Sie haben die ganze Woche Anwendungscode deployed. Neue Funktion rein, alter Prozess stoppt, neuer Prozess startet. Wenn etwas schiefgeht, wechseln Sie zurück zur vorherigen Version. Der gesamte Zyklus dauert Minuten. Es fühlt sich sicher an, weil Code ersetzbar ist.
Dann kommt eine Datenbank-Migration. Eine neue Spalte muss hinzugefügt werden. Eine Tabelle muss umbenannt werden. Sie führen das Migrationsskript aus, und plötzlich hat die Produktionsdatenbank eine andere Struktur. Die Anwendung läuft zunächst einwandfrei, aber eine Stunde später meldet jemand fehlende Daten in einem Report. Sie versuchen, die Migration zurückzurollen, aber die Daten, die während der Migration transformiert wurden, lassen sich nicht sauber rückgängig machen. Einige Zeilen haben noch die neue Struktur. Einige alte Werte sind verschwunden.
In diesem Moment wird vielen Teams klar, dass Datenbank-Deployment nicht einfach „Deployment für eine andere Art von Sache“ ist. Es ist ein grundlegend anderes Problem.
Code ist wegwerfbar, Daten sind es nicht
Als Sie zum ersten Mal gelernt haben, Anwendungen zu bauen, haben Sie wahrscheinlich eine Anwendung als eine Sammlung von Code betrachtet. Sie schreiben Code, führen ihn aus, sehen das Ergebnis und ändern den Code erneut, wenn etwas nicht stimmt. Wenn eine neue Version nicht funktioniert, gehen Sie zurück zur vorherigen Version. Dieser Prozess fühlt sich leichtgewichtig an, weil es keine langfristigen Konsequenzen gibt. Falscher Code kann weggeworfen, ersetzt oder von Grund auf neu geschrieben werden.
Aber sobald eine Anwendung von anderen Menschen genutzt wird, wächst etwas mit ihr mit: Daten. Benutzerdaten, Transaktionsdaten, Bestelldaten, Verlaufsaufzeichnungen. Diese Daten sind nicht nur der Inhalt einer Datenbank. Daten sind eine Aufzeichnung dessen, was im Unternehmen bereits passiert ist. Jede Zeile in einer Tabelle speichert etwas Wertvolles. Wenn Daten verloren gehen, wird sie das Neuschreiben von Code nicht zurückbringen. Verlorene Daten können nicht regeneriert werden.
Dies ist der grundlegende Unterschied zwischen Anwendungscode und einer Datenbank. Anwendungscode kann als ersetzbares Artefakt behandelt werden. Sie können einen Projektordner löschen, ihn erneut aus einem Repository klonen, und die Anwendung läuft genau wie zuvor. Aber eine Datenbank ist nicht so. Eine Datenbank speichert Zustand, den aktuellen Zustand der Geschäftsdaten. Dieser Zustand entsteht aus der Akkumulation von Operationen, die bereits stattgefunden haben. Wenn die Datenbank gelöscht wird, ist der Zustand weg. Es gibt kein Git Clone, das über ein Jahr gesammelte Kundendaten wiederherstellen kann.
Die Auswirkung auf das Deployment
Die Auswirkung dieses Unterschieds wird während des Deployments sofort deutlich. Wenn Sie eine neue Version einer Anwendung deployen, senden Sie den neuesten Code an den Server, stoppen den alten Prozess und starten den neuen. Wenn die neue Version Probleme hat, können Sie durch Zurücksetzen auf die vorherige Version ein Rollback durchführen. Die Anwendung läuft dann wie vor dem Update.
Aber wenn ein Datenbank-Deployment die Tabellenstruktur ändert, sind vorhandene Daten betroffen. Eine neue Spalte könnte mit Standardwerten gefüllt werden. Datentypen könnten sich ändern. Alte Daten müssen möglicherweise transformiert werden. Wenn diese Änderungen Probleme verursachen, ist ein Rollback nicht so einfach wie das Austauschen von Code-Versionen. Daten, die bereits geändert wurden, kehren nicht automatisch in ihre ursprüngliche Form zurück.
Betrachten Sie eine einfache Migration, die eine Spalte hinzufügt und mit Daten befüllt:
-- Forward-Migration
ALTER TABLE users ADD COLUMN age INT;
UPDATE users SET age = 25 WHERE age IS NULL;
-- Rollback-Skript
ALTER TABLE users DROP COLUMN age;
Wenn die Forward-Migration ausgeführt wurde und die Anwendung begonnen hat, neue Alter zu schreiben, verwirft das Rollback die Spalte und diese neuen Werte sind weg. Anders als bei Anwendungscode können Sie nicht einfach die alte Version erneut deployen, um die verlorenen Daten wiederherzustellen.
Aus diesem Grund werden viele Teams bei Datenbank-Deployments vorsichtig. Sie können mehrmals täglich Anwendungsversionen austauschen, zögern aber, bei jedem Deployment eine Datenbank-Migration auszuführen. Nicht weil Migrationen technisch schwierig sind, sondern weil die Konsequenzen anders sind. Falscher Code kann durch Neuschreiben behoben werden. Falsche Daten zu korrigieren kann Tage dauern, und manchmal können sie nicht genau so wiederhergestellt werden wie zuvor.
Wie dies Ihren Deployment-Prozess verändert
Der Unterschied zwischen Code und Daten wirkt sich darauf aus, wie Sie Ihren Deployment-Prozess gestalten. Für Anwendungen müssen Sie hauptsächlich sicherstellen, dass neuer Code ausgeführt werden kann. Für Datenbanken müssen Sie sicherstellen, dass strukturelle Änderungen keine vorhandenen Daten beschädigen, die laufende Anwendung nicht stören und im Fehlerfall rückgängig gemacht werden können.
Hier sind die praktischen Auswirkungen:
Anwendungs-Deployments sind additiv. Sie fügen neuen Code hinzu, entfernen alten Code, und das System läuft weiter. Die alte Version ist weiterhin in Ihrem Repository oder Artefakt-Speicher verfügbar.
Datenbank-Deployments sind transformativ. Sie ändern die Struktur vorhandener Daten. Die alte Struktur ist weg, sobald die Migration läuft. Selbst wenn Sie ein Backup haben, bedeutet die Wiederherstellung, dass alle Daten verloren gehen, die nach dem Backup erstellt wurden.
Anwendungs-Rollbacks sind günstig. Sie leiten den Load Balancer auf die alte Version um oder starten den alten Prozess neu. Der Anwendungszustand wird durch den ausgeführten Code bestimmt.
Datenbank-Rollbacks sind teuer. Sie müssen eine Reverse-Migration schreiben, die die Daten in ihre vorherige Struktur zurücktransformiert. Diese Reverse-Migration muss getestet werden. Sie könnte fehlschlagen, wenn neue Daten hinzugefügt wurden, die nicht in die alte Struktur passen. Und wenn die Forward-Migration Daten irreversibel transformiert hat (z. B. durch Zusammenführen von Vor- und Nachnamen in eine einzige Spalte), könnte die Reverse-Migration Informationen verlieren.
Das eigentliche Risiko ist nicht technisch
Viele Teams behandeln Datenbank-Migrationen als rein technisches Problem. Sie schreiben Migrationsskripte, testen sie im Staging und führen sie in der Produktion aus. Wenn etwas schiefgeht, geben sie dem Migrationsskript oder dem Datenbank-Tool die Schuld.
Aber das eigentliche Risiko ist oft organisatorisch. Eine Datenbank-Migration berührt Daten, die echten Benutzern gehören. Ein Fehler kann Kundenaufzeichnungen, Finanzdaten oder Compliance-Protokolle beschädigen. Das Team, das die Migration durchführt, versteht möglicherweise nicht vollständig, wie die Daten von anderen Systemen genutzt werden. Eine Spaltenumbenennung könnte eine monatlich laufende Reporting-Abfrage zerstören. Eine Datentypänderung könnte dazu führen, dass ein Legacy-Dienst stillschweigend ausfällt.
Deshalb erfordern Datenbank-Deployments eine andere Sorgfalt. Die technische Komplexität ist beherrschbar. Die organisatorische Komplexität ist es, die Teams verlangsamt.
Praktische Checkliste für Datenbank-Deployments
Bevor Sie eine Datenbank-Migration in der Produktion ausführen, sollten Sie diese Punkte prüfen:
- Kann die Migration rückgängig gemacht werden? Schreiben und testen Sie das Rollback-Skript, bevor Sie die Forward-Migration ausführen.
- Wird die Migration die aktuelle Anwendung zerstören? Wenn die Anwendung aus einer Spalte liest, die Sie umbenennen, wird die Anwendung fehlschlagen, bis sie ebenfalls aktualisiert wird.
- Kann die Migration ausgeführt werden, während die Anwendung live ist? Einige Migrationen sperren Tabellen, was zu Ausfallzeiten führen kann.
- Gibt es ein Backup? Erstellen Sie ein Backup, bevor Sie eine Migration ausführen, die Daten transformiert.
- Wer muss informiert werden? Benachrichtigen Sie Teams, die diese Daten konsumieren, einschließlich Reporting, Analytics und Data Science.
Das Fazit
Anwendungscode ist wegwerfbar. Sie können ihn wegwerfen, neu schreiben und eine neue Version deployen, ohne etwas Wertvolles zu verlieren. Datenbankdaten sind nicht wegwerfbar. Jede Migration ändert etwas, das nicht einfach neu erstellt werden kann.
Behandeln Sie Datenbank-Deployments mit der gleichen Sorgfalt wie Produktionsvorfälle. Schreiben Sie Rollback-Skripte. Testen Sie Migrationen mit realistischen Daten. Kommunizieren Sie mit Teams, die von den Daten abhängen. Und gehen Sie niemals davon aus, dass eine Migration sicher ist, nur weil sie im Staging bestanden hat.
Der Unterschied zwischen Code und Daten ist kein technisches Detail. Es ist der Grund, warum Datenbank-Deployments ihren eigenen Prozess, ihre eigene Teststrategie und ihre eigene Risikobewertung verdienen.