Wenn Ihre Datenbankmigration einen sauberen Schnitt braucht: Die Cutover-Phase

Stellen Sie sich folgendes Szenario vor: Ihr Team hat Wochen damit verbracht, Daten sorgfältig von einem alten Datenbankschema in ein neues zu migrieren. Das Expand-Contract-Pattern lief reibungslos. Ihre Anwendung hat in beide Strukturen geschrieben – in die alte und die neue. Backfill-Skripte haben historische Daten übertragen. Verifizierungsprüfungen waren erfolgreich. Auf dem Papier sieht alles gut aus.

Doch jetzt kommt der Moment, der viele Entwickler nervös macht: die Umstellung der Anwendung, sodass sie ausschließlich aus der neuen Struktur liest. Dies ist die Cutover-Phase, und sie ist der Punkt, an dem viele Datenbankmigrationen entweder sauber gelingen oder unerwartete Produktionsausfälle verursachen.

Was Cutover eigentlich bedeutet

Cutover ist der Zeitpunkt, an dem Ihre Anwendung aufhört, aus der alten Struktur zu lesen, und sich vollständig auf die neue verlässt. Das klingt einfach, erfordert aber in der Praxis sorgfältige Koordination und Verifikation.

Vor dem Cutover befand sich Ihre Anwendung in einem Dual-Read-Zustand. Neue Daten wurden seit Beginn der Migration in beide Strukturen geschrieben. Historische Daten wurden nachträglich befüllt (Backfill). Die Anwendung las aus zwei Quellen: aus der alten Struktur für Daten, die vor der Migration existierten, und aus der neuen Struktur für Daten, die danach geschrieben wurden.

Der Cutover entfernt diese Dual-Read-Logik. Der Anwendungscode wird so geändert, dass jede Leseanfrage nur noch an die neue Struktur geht. Dies ist in der Regel eine Codeänderung und ein Deployment, keine Schemaänderung. Sie aktualisieren den Lesepfad, bauen die Anwendung und deployen sie wie jedes andere Feature-Update.

Das folgende Sequenzdiagramm veranschaulicht den Übergang vom Dual-Read zum Cutover:

Hier ist ein vereinfachtes Beispiel, wie diese Codeänderung in einem Node.js-Service aussieht:

// Vor Cutover: Dual-Read-Logik
async function getUserProfile(userId) {
  // Zuerst neue Struktur für aktuelle Daten versuchen
  const newProfile = await db.query(
    'SELECT * FROM user_profiles_v2 WHERE user_id = $1', [userId]
  );
  if (newProfile.rows.length > 0) {
    return newProfile.rows[0];
  }
  // Fallback auf alte Struktur für Legacy-Daten
  const oldProfile = await db.query(
    'SELECT * FROM user_profiles WHERE user_id = $1', [userId]
  );
  return oldProfile.rows[0] || null;
}

// Nach Cutover: Single-Read-Logik
async function getUserProfile(userId) {
  const profile = await db.query(
    'SELECT * FROM user_profiles_v2 WHERE user_id = $1', [userId]
  );
  return profile.rows[0] || null;
}
sequenceDiagram participant OldApp as Alte App participant NewApp as Neue App participant OldDB as Datenbank (alte Struktur) participant NewDB as Datenbank (neue Struktur) Note over OldApp,NewDB: Vor Cutover OldApp->>OldDB: liest NewApp->>OldDB: liest (alte Daten) NewApp->>NewDB: liest (neue Daten) Note over OldApp,NewDB: Cutover findet statt NewApp->>NewDB: liest nur noch Note over OldApp: Alte App wird eingestellt

Das Risiko, das Sie nicht ignorieren können

Die Gefahr während des Cutovers liegt im teilweisen Fehlschlag. Wenn einige Anwendungsinstanzen noch aus der alten Struktur lesen, während andere bereits umgestellt haben, kann es zu inkonsistenten Ergebnissen kommen. Ein Benutzer könnte je nach Server, der seine Anfrage bearbeitet, unterschiedliche Daten sehen.

Deshalb ist die Cutover-Strategie entscheidend. Es gibt zwei Hauptansätze:

Big-Bang-Cutover schaltet alle Instanzen auf einmal um. Es ist schnell und einfach zu koordinieren, aber wenn etwas schiefgeht, sind sofort alle Benutzer betroffen.

Gradueller Cutover schaltet Instanzen in Batches um, oft nach Region, Availability Zone oder Benutzergruppe. Das begrenzt die Auswirkungen. Wenn Sie eine Availability Zone umstellen und Fehler sehen, können Sie nachforschen, bevor Sie mit der nächsten Zone fortfahren. Der Nachteil ist der höhere Koordinations- und Überwachungsaufwand.

Die meisten Teams mit Produktionserfahrung bevorzugen den graduellen Cutover für Datenbankmigrationen. Der zusätzliche Koordinationsaufwand ist den Sicherheitsnetz wert.

Versteckte Abhängigkeiten finden

Nach dem Cutover liest Ihre Anwendung nicht mehr aus der alten Struktur. Aber ist sie wirklich die einzige Anwendung, die das tut? In Produktionsumgebungen greifen oft mehrere Services, Batch-Jobs, Reporting-Skripte und manuelle Abfragen auf dieselbe Datenbank zu.

Ein häufiger Fehler ist die Annahme, dass die Aktualisierung der Hauptanwendung ausreicht. Währenddessen fragt ein nächtlicher Batch-Job um 2 Uhr morgens immer noch die alte Spalte ab. Oder ein Datenanalyst führt jeden Montag einen manuellen Report mit der alten Tabelle aus. Diese versteckten Abhängigkeiten führen nach dem Cutover zu Fehlern oder liefern veraltete Daten.

Der zuverlässigste Weg, sie zu finden, ist die Überwachung von Datenbankabfragen. Aktivieren Sie Tools wie pg_stat_statements in PostgreSQL oder performance_schema in MySQL. Suchen Sie nach Abfragen, die auf die alten Spalten oder Tabellen verweisen. Führen Sie diese Überwachung mindestens einen vollständigen Zyklus aller bekannten Prozesse lang durch. Wenn Sie einen wöchentlichen Reporting-Job haben, warten Sie eine ganze Woche nach dem Cutover, bevor Sie die alte Struktur als ungenutzt erklären.

Manche Teams führen auch einen Staging-Test durch, bei dem sie den Lesezugriff auf die alten Spalten entziehen und alle bekannten Anwendungsszenarien ausführen. Wenn keine Fehler auftreten, ist die Produktion wahrscheinlich sicher für den nächsten Schritt.

Was nach dem Cutover passiert

Sobald der Cutover abgeschlossen ist und alle Abhängigkeiten als bereinigt bestätigt wurden, läuft Ihre Anwendung vollständig auf dem neuen Format. Die alte Struktur existiert noch in der Datenbank, aber es liest niemand mehr daraus. Dies ist der Punkt, an dem Sie mit der Planung der Contract-Phase beginnen können: dem vollständigen Entfernen der alten Struktur.

Aber überstürzen Sie die Löschung nicht. Behalten Sie die alte Struktur auch nach dem Cutover für einen Sicherheitszeitraum. Die Dauer hängt vom Vertrauen Ihres Teams und den Kosten für das Vorhalten zusätzlicher Spalten oder Tabellen ab. Manche Teams behalten sie eine Woche, andere einen Monat, insbesondere wenn die Migration kritische Kundendaten betrifft.

Überwachen Sie in dieser Zeit auf Alarme oder Fehlerlogs, die auf eine unentdeckte Abhängigkeit hindeuten könnten. Wenn nichts auftaucht, können Sie zuversichtlich mit dem Löschen der alten Struktur fortfahren.

Praktische Checkliste für den Cutover

Bevor Sie den Cutover in der Produktion durchführen, gehen Sie diese Checkliste durch:

  • Alle historischen Daten wurden nachträglich befüllt (Backfill) und verifiziert
  • Dual-Write lief mindestens einen vollständigen Geschäftszyklus lang fehlerfrei
  • Die Codeänderung für den Lesepfad ist fertig und reviewed
  • Der Rollback-Plan ist dokumentiert: wie Sie die Lesevorgänge bei Bedarf wieder auf die alte Struktur umstellen
  • Die Überwachung von Datenbankabfragen ist aktiviert und konfiguriert, um Abfragen auf die alte Struktur zu erkennen
  • Alle bekannten abhängigen Anwendungen, Batch-Jobs und Reports wurden identifiziert und aktualisiert
  • Die Staging-Umgebung wurde getestet, nachdem der Lesezugriff auf die alte Struktur entfernt wurde
  • Der Plan für den graduellen Cutover ist definiert: welche Instanzen oder Regionen zuerst umgestellt werden
  • Monitoring-Dashboards sind eingerichtet, um Lesefehler oder Dateninkonsistenzen nach dem Cutover zu erkennen
  • Der Kommunikationsplan steht: wer muss wann über den Cutover informiert werden

Das Fazit

Der Cutover ist der Moment, in dem Ihr Migrationspattern aufhört, theoretisch zu sein, und anfängt, echte Benutzer zu beeinflussen. Behandeln Sie ihn nicht als einfache Codeänderung. Betrachten Sie ihn als Produktionsereignis, das Überwachung, Verifikation und einen klaren Rollback-Pfad erfordert. Der zusätzliche Tag, den Sie damit verbringen, sicherzustellen, dass keine versteckten Abhängigkeiten existieren, ist weit mehr wert als die Stunde, die Sie durch überstürztes Löschen der alten Struktur sparen könnten.