CI/CD für Schemamigrationen (Flyway/Liquibase)
Symptom
Ziel: Änderungen am Datenbankschema mit versionierten Migrationsdateien verwalten; sie in CI/CD mit Flyway oder Liquibase automatisch, aber kontrolliert anwenden.
1. Versionierte Migrationsdateien anlegen (Vxxx__name.sql)
Schreibe jede Schemaänderung in eine benannte Datei mit steigender Versionsnummer; die Flyway-Konvention lautet V<version>__<description>.sql (z. B. V1__initial_schemas.sql, V2__orders_table.sql). Diese Dateien liegen in Git und werden in Versionsreihenfolge angewendet. Angewendete Migrationen werden in einer Tracking-Tabelle protokolliert (in Flyway flyway_schema_history), sodass jede Migration genau einmal läuft.
PostgreSQL
-- V2__orders_table.sql
CREATE TABLE orders (
id bigserial PRIMARY KEY,
amount numeric(12,2) NOT NULL,
created_at timestamptz DEFAULT now()
);2. Unveränderlichkeit mit Checksummen wahren
Flyway/Liquibase speichern die Checksumme jeder angewendeten Migration. Bearbeitest du später eine bereits angewendete Datei, stimmt die Checksumme nicht mehr, und das Werkzeug bricht mit einem Fehler ab. Regel: Bearbeite NIE eine angewendete Migration; führe die Korrektur mit einer neuen Versionsdatei durch. So ist garantiert, dass alle Umgebungen (dev/staging/prod) dieselbe Historie haben.
PostgreSQL
# repair on checksum mismatch (use with care):
flyway repair
# the right way: add the change in a new Vx file3. Baseline für eine bestehende Datenbank setzen
Verwende baseline, wenn du das Migrationswerkzeug an eine bereits befüllte Datenbank ohne Historie anbindest; es behandelt den aktuellen Zustand als 'Startversion' und versucht nicht, vorhandene Objekte neu anzulegen. Migrationen nach baselineVersion werden angewendet. In einer von Grund auf neu aufgebauten Umgebung ist keine Baseline nötig; die Migrationen laufen ab V1.
PostgreSQL
flyway baseline -baselineVersion=1 -baselineDescription="existing schema"4. In der CI-Pipeline automatisch migrieren
Führe das Migrationswerkzeug in einem CI-Schritt aus, um Änderungen automatisch auf die Test- und Staging-Datenbanken anzuwenden; der Befehl migrate führt nur neue (nicht angewendete) Dateien aus und ist idempotent. Wird die Migration zuerst auf eine temporäre/kurzlebige Datenbank angewendet und validiert, fällt fehlerhaftes SQL auf, bevor es Prod erreicht. Das Schema muss VOR dem Deployment des Anwendungscodes migriert werden (mit abwärtskompatiblen Änderungen).
PostgreSQL
# CI step (Flyway)
flyway -url=jdbc:postgresql://staging/appdb \
-user=ci -password=$PW migrateMySQL
flyway -url=jdbc:mysql://staging/appdb \
-user=ci -password=$PW migrate5. Manuelles Freigabe-Gate für Prod hinzufügen
Test/Staging laufen automatisch, aber das migrate auf Prod sollte eine manuelle Freigabe erfordern; füge in CI/CD einen Schritt 'Approval Gate' (manuelle Freigabe) hinzu. Zeige vor der Freigabe mit 'flyway info' oder 'liquibase status', welche Migrationen laufen werden. Erstelle vor dem Anwenden auf Prod immer ein frisches Backup, damit du bei Problemen zurückrollen kannst.
PostgreSQL
# what will run before approval?
flyway info
# liquibase equivalent:
liquibase status --verbose6. Umkehrbarkeit und Rollback-Strategie festlegen
Flyway Community hat kein automatisches Undo; verfolge das Prinzip Forward-only-Migration: Statt einen Fehler rückgängig zu machen, schreibe eine neue Migration, die ihn korrigiert. Liquibase-Changesets können einen Rollback-Block definieren und mit 'liquibase rollback' zurückgerollt werden. Die robusteste Strategie: Halte Änderungen klein und abwärtskompatibel, erstelle vor riskanten Operationen (Löschen von Spalten) ein Backup und bereite einen schriftlichen Rollback-Plan vor.
PostgreSQL
-- Liquibase rollback example (inside a changeset)
--changeset dev:2
CREATE TABLE orders (...);
--rollback DROP TABLE orders;