Zum Inhalt springen
← Impulse

Datenbankschema ändern: So gelingt die Bereitstellung ohne Dienstunterbrechung

Erfahren Sie, wie Sie Schemaänderungen mit parallel laufenden Anwendungsversionen, gezielten Prüfungen und schrittweisem Rückbau bereitstellen und Risiken senken.

Diagramm einer schrittweisen Schemaänderung mit parallel laufenden Anwendungsversionen und späterer Entfernung des alten Schemas.

Eine Tabelle zu ändern, wirkt vielleicht wie eine interne Anpassung. In einer produktiven Umgebung greifen jedoch selten nur eine einzige Anwendung oder ein einziger Dienst auf die Datenbank zu. Während einer Bereitstellung können verschiedene Versionen eines Dienstes parallel laufen. Außerdem gibt es möglicherweise Berichtsabfragen, Integrationen oder geplante Aufgaben, die vom aktuellen Schema abhängen. Ist eine Änderung mit einem dieser Verbraucher nicht mehr kompatibel, kann das zu sichtbaren Fehlern oder einem Ausfall führen.

Am sichersten ist es, Schema und Anwendungscode nicht gleichzeitig zu ändern, sondern die Arbeit in kompatible Schritte aufzuteilen. So kann jede Version weiterarbeiten, während die nächste bereitgestellt und ihr Verhalten überprüft wird. Dieser Ansatz beseitigt nicht jedes Risiko: Er setzt voraus, dass Abhängigkeiten bekannt sind, das System beobachtet wird und vorab feststeht, wie das Team bei Problemen reagiert.

Warum eine kleine Änderung den Dienst beeinträchtigen kann

Warum eine kleine Änderung den Dienst beeinträchtigen kann

Das Schema ist ein Vertrag zwischen der Datenbank und jeder Software, die sie abfragt. Eine ältere Anwendung erwartet möglicherweise eine Spalte, die eine Migration entfernt. Eine neue Anwendung wiederum kann davon ausgehen, dass eine Spalte bereits vorhanden ist, obwohl sie noch nicht angelegt wurde. Beides kommt häufig vor, wenn Anwendungs- und Datenbankbereitstellung nicht exakt gleichzeitig stattfinden.

Auch die Ausführung der Änderung spielt eine Rolle. Je nach Datenbankmodul und Art der Anpassung kann ein Vorgang Schreibzugriffe blockieren, lange dauern oder mit der üblichen Auslastung um Ressourcen konkurrieren. Gehen Sie nicht davon aus, dass eine Operation sofort abgeschlossen ist oder in jeder Umgebung die gleiche Auswirkung hat. Prüfen Sie das Verhalten für Ihr Datenbankmodul und dessen Version, die Größe und Nutzung der Tabellen sowie den konkreten Migrationsmechanismus.

Ermitteln Sie vor der Planung, wer Daten liest und schreibt: Anwendungsversionen, verbundene Dienste, Analyseabfragen, Batch-Prozesse, Skripte und manuelle Abläufe. Berücksichtigen Sie auch weniger sichtbare Abhängigkeiten wie gespeicherte Prozeduren, Sichten und Einschränkungen. Wenn Sie nicht feststellen können, welche Komponenten ein Feld verwenden, entfernen Sie es noch nicht.

Das Expand-and-Contract-Muster anwenden

Das Expand-and-Contract-Muster teilt eine inkompatible Änderung in mehrere Phasen auf. Zunächst wird das Schema auf additive Weise erweitert. Anschließend wird Code bereitgestellt, der mit der bisherigen Version zusammenarbeiten kann. Erst wenn keine Verbraucher das alte Element mehr benötigen, wird es entfernt. Entscheidend ist die Kompatibilität zwischen den Phasen: Während des Übergangs muss jede aktive Version mit dem verfügbaren Schema arbeiten können.

  1. Erweitern: Fügen Sie die neue Spalte, Tabelle oder Struktur hinzu, ohne die bisherige zu entfernen oder zu verändern. Vermeiden Sie zunächst Einschränkungen, die bestehende Daten oder die alte Anwendung nicht erfüllen können.
  2. Anwendung vorbereiten: Veröffentlichen Sie eine Version, die je nach Bedarf sowohl mit dem alten als auch mit dem neuen Schema umgehen kann. Rollen Sie die Version schrittweise aus und bestätigen Sie, dass keine alten Instanzen mehr aktiv sind, bevor Sie davon ausgehen, dass es keine alten Lese- oder Schreibzugriffe mehr gibt.
  3. Übergang vollziehen: Stellen Sie Lese- oder Schreibzugriffe auf die neue Darstellung um. Müssen beide Spalten vorübergehend bestehen bleiben, legen Sie fest, welche davon maßgeblich ist und wie sie während dieser Zeit synchron gehalten werden.
  4. Altes Schema entfernen: Sobald geprüft ist, dass weder Code noch Prozesse das alte Element verwenden, entfernen Sie es in einer späteren Änderung. Diese Phase sollte unabhängig von der Bereitstellung erfolgen, mit der der Übergang begonnen hat.

Durch die Trennung der Phasen wird verhindert, dass eine schrittweise bereitgestellte Anwendung plötzlich auf ein Schema trifft, das sie noch nicht versteht. Zudem lässt sich bei Problemen klarer reagieren: Häufig kann die Codeänderung angehalten werden, ohne eine kompatible Schemaerweiterung sofort zurücknehmen zu müssen.

Spalten, Umbenennungen und Typänderungen behandeln

Neue Spalten: Fügen Sie zuerst die Spalte hinzu und stellen Sie Code bereit, der auch dann funktioniert, wenn sie noch nicht den erwarteten Wert enthält. Beginnen Sie danach, in die Spalte zu schreiben, und prüfen Sie, ob neue Schreibvorgänge korrekt ausgeführt werden. Müssen bestehende Datensätze ergänzt werden, behandeln Sie dies als separaten Vorgang: Er kann Zeit und Ressourcen beanspruchen, daher sollte sein Fortschritt überwacht werden. Erst wenn die Daten vorbereitet sind und der Code das neue Feld verwendet, kommt das Entfernen des alten Feldes infrage.

Umbenennungen: Eine direkte Umbenennung ist häufig nicht mit Versionen kompatibel, die weiterhin den alten Namen abfragen. Sicherer ist es, eine Spalte mit dem neuen Namen hinzuzufügen, Schreibvorgänge vorübergehend zu koordinieren und Lesezugriffe schrittweise umzustellen. Entfernen Sie den alten Namen erst, wenn bestätigt ist, dass ihn keine aktive Version und kein abhängiger Prozess mehr verwendet.

Typänderungen: Gehen Sie nicht davon aus, dass eine Konvertierung alle Werte erhält. Legen Sie fest, was mit Daten geschieht, die nicht zum neuen Typ passen, prüfen Sie Stichproben und planen Sie eine Konvertierung, die sich steuern und überprüfen lässt. Erfordert der neue Typ strengere Regeln, prüfen Sie die vorhandenen Daten, bevor Sie diese Regeln anwenden.

Einschränkungen und Pflichtwerte: Eine Spalte, die verpflichtend wird, kann Probleme verursachen, wenn noch Zeilen ohne Wert vorhanden sind oder schreibende Komponenten keinen Wert bereitstellen. Bereiten Sie zuerst Daten und Code vor. Wenden Sie die Einschränkung erst an, wenn Sie nachweisen können, dass sie erfüllt ist. Die genaue Reihenfolge hängt vom Datenbankmodul und davon ab, wie es Validierung und Sperren handhabt.

Prüfungen vor, während und nach der Bereitstellung

Eine Migration ist nicht allein deshalb erfolgreich, weil die Anweisung ausgeführt wurde. Prüfen Sie, ob das funktionale und operative Verhalten weiterhin korrekt ist. Erfassen Sie vor der Änderung den relevanten Ausgangszustand, damit Sie anschließend vergleichen können, und legen Sie fest, welche Signale einen Stopp der Bereitstellung rechtfertigen.

  • Kompatibilität: Stellen Sie fest, welche Anwendungsversionen in jeder Phase aktiv sein werden, und testen Sie, ob sie mit dem jeweils verfügbaren Schema arbeiten können.
  • Daten: Prüfen Sie relevante Datensatzmengen, Nullwerte und Geschäftsregeln vor und nach der Änderung. Vergleichen Sie bei einer Transformation das Ergebnis mit bekannten Kriterien, statt sich nur darauf zu verlassen, dass keine Fehler aufgetreten sind.
  • Leistung: Beobachten Sie Dauer der Migration, Sperren, Auslastung und Latenz der betroffenen Vorgänge. Verschlechtert sich die Leistung, halten Sie die nächste Phase an und bewerten Sie die Auswirkungen, bevor Sie fortfahren.
  • Fehler: Prüfen Sie fehlgeschlagene Abfragen, Anwendungsausnahmen sowie Fehler in Integrationen und geplanten Aufgaben. Dass keine Warnmeldungen auftreten, beweist für sich genommen nicht, dass alle Verbraucher berücksichtigt wurden.
  • Nutzung des alten Schemas: Suchen Sie nach Verweisen im Code und in Abfragen. Prüfen Sie außerdem über einen angemessenen Zeitraum, ob das Feld, das entfernt werden soll, noch gelesen oder beschrieben wird.

Testen Sie das Verfahren nach Möglichkeit in einer repräsentativen Umgebung und beziehen Sie die Prüfschritte mit ein. Ein Testlauf kann Abhängigkeiten und langsame Vorgänge sichtbar machen, garantiert jedoch nicht, dass Produktionsumgebung, Auslastung und Datenverteilung identisch sind. Stellen Sie außerdem sicher, dass die Migration eindeutig identifizierbar ist und das Team weiß, wer über Fortsetzen, Pausieren oder Zurücknehmen entscheidet.

Rollback, Korrektur nach vorn und Grenzen

Eine Migration lässt sich nicht immer sicher zurücknehmen. Eine additive Erweiterung kann oft leichter bestehen bleiben, als dass sie rückgängig gemacht wird – insbesondere, wenn die Anwendung bereits Daten in die neue Spalte geschrieben hat. Diese Daten zu löschen, um zum vorherigen Zustand zurückzukehren, kann Informationen vernichten. Ein Rollback-Plan sollte daher erklären, was zurückgenommen wird – der Code, das Schema oder beides – und welche Daten erhalten bleiben.

Lassen sich neue Schreibvorgänge nicht zuverlässig in das alte Schema übertragen, kann es sinnvoller sein, die Bereitstellung anzuhalten und eine Korrektur nach vorn vorzubereiten. Legen Sie das Entscheidungskriterium vorher fest, etwa Fehler bei kritischen Vorgängen, eine anhaltende Verschlechterung oder inkonsistente Daten. Versprechen Sie kein sofortiges Rollback, ohne geprüft zu haben, ob es bei dieser konkreten Änderung tatsächlich möglich ist.

Checkliste für die Planung einer Änderung

Checkliste für die Planung einer Änderung
  • Sind alle Leser, Schreiber und Prozesse erfasst, die das betroffene Schema verwenden?
  • Ist die anfängliche Änderung mit den Versionen kompatibel, die während der Bereitstellung weiterhin aktiv sind?
  • Sind Schemaerweiterung, Codeübergang und Entfernung des alten Elements voneinander getrennt?
  • Ist die maßgebliche Datenquelle festgelegt, falls vorübergehend zwei Darstellungen bestehen?
  • Sind Prüfungen für Daten, Fehler und Leistung definiert – einschließlich Verantwortlichen und Kriterien für eine Pause?
  • Erklärt der Plan, was sich zurücknehmen lässt und wann eine Korrektur nach vorn erforderlich ist?

Wenn Sie ein Datenbankschema ohne Dienstunterbrechung ändern möchten, sollten Sie in Kompatibilität zwischen den einzelnen Phasen denken, nicht in einer isolierten Anpassung. Fügen Sie Neues hinzu, bevor Sie Altes entfernen, halten Sie parallel laufende Versionen arbeitsfähig und prüfen Sie jeden Übergang anhand beobachtbarer Signale. Lässt sich die Änderung nicht additiv umsetzen, benennen Sie das Risiko ausdrücklich und planen Sie ein geeignetes Wartungsfenster oder eine passende Wiederherstellungsstrategie. Gehen Sie nicht davon aus, dass sich jede Änderung ohne Unterbrechung bereitstellen lässt.

Fuentes y referencias

  1. MDN Web DocsMozilla
  2. Web performanceweb.dev
  3. OWASP Cheat Sheet SeriesOWASP Foundation