Versionierung mit Liquibase
Diese Seite ist ein Teil der IsyFact-Standards.
Alle Inhalte der Seite, insbesondere Texte und Grafiken, sind urheberrechtlich geschützt.
Alle urheberrechtlichen Nutzungs- und Verwertungsrechte liegen beim Bundesverwaltungsamt.
Die Nutzung ist unter den Lizenzbedingungen der Creative Commons Namensnennung 4.0 International gestattet.
Die Schemaversionierung mit Liquibase erfolgt gemäß den Richtlinien in Versionierung mit Liquibase mit Fokus auf die Integration in Spring Boot und die Nutzung mit Maven. Liquibase wird in Spring Boot über die Konfigurationsdateien eingebunden, während das zugehörige Maven-Plugin Schemaänderungen direkt in der Build-Pipeline ausführt.
Durch strukturierte Änderungsprotokolle lassen sich Schemaanpassungen kontrolliert, nachvollziehbar und automatisiert verwalten. Bestehende Datenbanken bleiben unverändert und dienen als Basis für zukünftige Änderungen. Die Kombination mit JDBC erlaubt eine flexible Anbindung an verschiedene Datenbanken.
Zudem lässt sich Liquibase nahtlos in CI/CD-Pipelines wie GitLab CI oder GitHub Actions integrieren, um Migrationen und Rollbacks zu automatisieren und so eine sichere Bereitstellung zu gewährleisten.
1. Einrichtung von Liquibase
IT-Systeme nutzen Liquibase direkt sowie als Maven-Plugin. Neben der Einbindung in Maven ist auch eine Konfiguration über Spring Boot notwendig.
1.1. Maven-Konfiguration
Liquibase benötigt JDBC, um mit der Datenbank zu kommunizieren und Änderungen auszuführen.
Daher ist neben der Bibliothek liquibase-core
, die Kernfunktionen von Liquibase enthält, auch der jeweilige JDBC-Treiber der verwendeten Datenbank notwendig.
<dependencies>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<dependency>
<!-- JDBC-Treiber der Datenbank -->
</dependency>
</dependencies>
Neben den Abhängigkeiten ist die Konfiguration des Liquibase Maven Plugin erforderlich.
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<configuration>
<changeLogFile>src/main/resources/db/changelog/db.changelog-master.xml</changeLogFile>
<url>${spring.datasource.url}</url>
<username>${spring.datasource.username}</username>
<password>${spring.datasource.password}</password>
<driver>${spring.datasource.driver-class-name}</driver>
</configuration>
</plugin>
</plugins>
</build>
Offizielle Dokumentation von Liquibase: Using JDBC URL in Liquibase |
1.2. Spring Boot Konfiguration
Um Liquibase beim Start eines IT-Systems automatisch Schemaänderungen durchführen zu lassen, kann dies in der application.properties
konfiguriert werden.
spring.liquibase.enabled=true
Standardmäßig verwendet Liquibase das Root Changelog db/changelog/db.changelog-master.xml
.
Es dient als zentrale Steuerungsdatei, in der alle Schemaänderungen verwaltet werden.
Es enthält entweder direkte Änderungen oder bindet weitere Changelog-Dateien ein, um eine strukturierte Verwaltung zu ermöglichen.
Falls ein anderer Ablageort genutzt werden soll, muss dies explizit angegeben werden.
spring.liquibase.change-log=classpath:pfad/zur/changelog.xml
Stattdessen empfiehlt sich die Nutzung von:
-
Umgebungsvariablen (
$DB_USER
,$DB_PASSWORD
), -
einer zentralen Konfiguration (zum Beispiel Spring Cloud Config), oder
-
Secrets-Management-Tools (zum Beispiel AWS Secrets Manager, HashiCorp Vault, Kubernetes Secrets).
Offizielle Dokumentation von Liquibase: |
2. Erstellung einer Baseline
Die folgenden Schritte beschreiben die Erstellung einer Baseline zur Verwaltung eines bestehenden Schemas.
- 1. Erstellung der
db.changelog-master.xml
-
Damit eine Baseline korrekt verwaltet werden kann, muss zuerst das Root Changelog
db.changelog-master.xml
erzeugt werden.Diese Datei dient als Einstiegspunkt für alle Schemaänderungen und stellt sicher, dass die Baseline zuerst und dann alle weiteren Release-Changelogs in der richtigen Reihenfolge angewendet werden.
Bei Verwendung von Spring Boot sollte sich diese Datei im Ordner
src/main/resources/db/changelog
befinden:Listing 5. Beispiel für das Root Changelog in XML<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.8.xsd"> <include file="baseline.xml" relativeToChangelogFile="true"/> </databaseChangeLog>
Listing 6. Beispiel für das Root Changelog in YAMLdatabaseChangeLog: - include: file: baseline.yml relativeToChangelogFile: true
Offizielle Dokumentation von Liquibase: Design Your Liquibase Project
- 2. Generierung der
baseline.xml
-
mvn liquibase:generateChangeLog -Dliquibase.outputChangeLogFile=src/main/resources/db/changelog/baseline.xml
Nach der Generierung sollte die Datei manuell überprüft und bereinigt werden.
- 3. Markierung der Baseline
-
Damit Liquibase die bestehende Datenbank nicht erneut verändert, aber die bereits vorhandenen Strukturen als Referenz speichert, muss die Baseline als ausgeführt markiert werden.
Listing 7. Markierung der Baseline als ausgeführtmvn liquibase:changelogSync
Dadurch werden alle im Changelog definierten Änderungen als bereits angewendet registriert, ohne tatsächlich Änderungen an der Datenbank vorzunehmen.
Listing 8. Optionale Vorabprüfung ohne Ausführungmvn liquibase:changelogSyncSQL
Dieser Befehl zeigt die SQL-Befehle an, die Liquibase ausführen würde, ohne sie tatsächlich anzuwenden.
Offizielle Dokumentation von Liquibase:
- 4. Tabellen
DATABASECHANGELOG
- undDATABASECHANGELOGLOCK
anlegen -
Beim ersten Liquibase-Update oder Sync-Vorgang legt Liquibase automatisch zwei Tabellen an:
-
DATABASECHANGELOG
: Speichert ausgeführte Changesets. -
DATABASECHANGELOGLOCK
: Sperrt die Datenbank, um gleichzeitige Änderungen zu verhindern.
Falls die Sperre aus einem vorherigen Prozess hängen geblieben ist, kann sie mit folgendem Befehl entfernt werden:
Listing 9. Entfernung der Sperremvn liquibase:releaseLocks
Offizielle Dokumentation von Liquibase: Tracking Tables
-
- 5. Integration der Baseline in das Versionskontrollsystem
-
Nachdem die Baseline erstellt wurde, sollten sowohl diese als auch das Root Changelog
db.changelog-master.xml
in das Versionskontrollsystem aufgenommen werden. Dies gewährleistet eine nachvollziehbare Historie der Datenbankänderungen.
3. Release-orientierte Umsetzung von Schemaänderungen
In den folgenden Schritten werden Changelogs in XML als Beispiel verwendet.
Es wird eine Baseline als Ausgangspunkt für die Datenbankstruktur genutzt, auf die alle nachfolgenden Release-Changelogs aufbauen.
Für eine genauere Steuerung, beispielsweise bei Stored Procedures, Triggern oder komplexen Optimierungen, können Changelogs auch als SQL-Dateien integriert werden.
3.1. Verzeichnisstruktur
Die Verzeichnisstruktur ist so aufgebaut, dass die Baseline als erster Schritt dient und alle nachfolgenden Releases über Changelogs (changelog-X.Y.xml
) angewendet werden.
Sie definiert die grundlegende Datenbankstruktur und bleibt nach der ersten Anwendung unverändert.
/db/changelog/
├── db.changelog-master.xml
├── baseline.xml
├── changelog-1.0.xml
├── changelog-1.1.xml
└── changelog-1.2.xml
Offizielle Dokumentation von Liquibase: |
3.2. Root Changelog
Das Root Changelog ist die db.changelog-master.xml
und stellt sicher, dass die Baseline zuerst und dann alle weiteren Release-Changelogs in der richtigen Reihenfolge angewendet werden.
<databaseChangeLog>
<include file="db/changelog/baseline.xml"/>
<include file="db/changelog/changelog-1.0.xml"/>
<include file="db/changelog/changelog-1.1.xml"/>
<include file="db/changelog/changelog-1.2.xml"/>
</databaseChangeLog>
3.3. Tagging von Baseline und Releases
Vor jedem neuen Release sollte ein Tag gesetzt werden, um ein sauberes Rollback des gesamten Releases zu erleichtern. Der erste Tag definiert die Baseline und markiert diesen Zustand als Referenzpunkt. Dadurch kann bei Bedarf gezielt auf die Baseline zurückgerollt werden. Eine einheitliche sinnvolle Namenskonvention ist empfehlenswert.
mvn liquibase:tag -Dliquibase.tag=v1.0-baseline
mvn liquibase:rollback -Dliquibase.rollbackTag=v1.0-baseline
Offizielle Dokumentation von Liquibase: Maven tag |
3.4. Erste Änderungen nach der Baseline
Das erste Update nach der Baseline ist Release-Changelog 1.0. Alle nachfolgenden Release-Changelogs enthalten ausschließlich inkrementelle Änderungen zur Baseline.
<databaseChangeLog>
<changeSet id="1.0-001" author="dev1">
<addColumn tableName="customers">
<column name="email" type="varchar(255)"/>
</addColumn>
</changeSet>
<changeSet id="1.0-002" author="dev2">
<createIndex indexName="idx_orders_date" tableName="orders">
<column name="order_date"/>
</createIndex>
</changeSet>
</databaseChangeLog>
3.5. Preconditions
Preconditions in Liquibase prüfen vor der Ausführung eines Changesets definierte Bedingungen. Wird eine Bedingung nicht erfüllt, kann die Migration abgebrochen, übersprungen oder mit einer Warnung fortgesetzt werden. Dadurch werden Fehler frühzeitig erkannt und nur zulässige Änderungen ausgeführt.
<databaseChangeLog>
<changeSet id="1.0-001" author="dev1">
<preConditions onFail="HALT">
<not>
<columnExists tableName="customers" columnName="email"/>
</not>
</preConditions>
<addColumn tableName="customers">
<column name="email" type="varchar(255)"/>
</addColumn>
</changeSet>
<changeSet id="1.0-002" author="dev2">
<preConditions onFail="HALT">
<not>
<indexExists tableName="orders" indexName="idx_orders_date"/>
</not>
</preConditions>
<createIndex indexName="idx_orders_date" tableName="orders">
<column name="order_date"/>
</createIndex>
</changeSet>
</databaseChangeLog>
Offizielle Dokumentation von Liquibase: Preconditions |
3.6. Manuelles Rollback im Changelog
Rollback-Anweisungen in der changelog.xml
ermöglichen Rollbacks einzelner Changesets für mehr Kontrolle.
<databaseChangeLog>
<changeSet id="1.0-001" author="dev1">
<addColumn tableName="customers">
<column name="email" type="varchar(255)"/>
</addColumn>
<rollback>
<dropColumn tableName="customers" columnName="email"/>
</rollback>
</changeSet>
<changeSet id="1.0-002" author="dev2">
<createIndex indexName="idx_orders_date" tableName="orders">
<column name="order_date"/>
</createIndex>
<rollback>
<dropIndex indexName="idx_orders_date" tableName="orders"/>
</rollback>
</changeSet>
</databaseChangeLog>
3.7. Befehle zum Rollback
Befehl | Bedeutung |
---|---|
|
Rollback auf einen zuvor gesetzten Tag ( |
|
Rollback um eine bestimmte Anzahl an Changesets (hier: 1 Changeset). |
|
Rollback auf einen spezifischen Zeitpunkt im Format |
|
Rollback auf ein bestimmtes Datum ( |
Offizielle Dokumentation von Liquibase: Liquibase Rollback Workflow |
4. Einsatz von CI/CD-Pipelines für automatisierte Migrationen
Liquibase kann nahtlos in GitLab CI/CD-Pipelines integriert werden, um Datenbankmigrationen automatisiert, sicher und kontrolliert auszuführen.
Die erforderlichen Konfigurationen werden in der Datei .gitlab-ci.yml
definiert.
- 1. Validierung der Changelogs
-
Vor dem Deployment sollte sichergestellt werden, dass alle Changelogs validiert und fehlerfrei sind. Tritt ein Fehler auf, wird der Prozess abgebrochen, um fehlerhafte Migrationen zu verhindern.
Listing 16. Beispiel für ein Validierungsskriptliquibase --url=$DB_URL --username=$DB_USER --password=$DB_PASSWORD validate
- 2. Deployment auf Staging
-
Die Datenbankmigration wird durchgeführt und das Release mit einem Tag versehen, um Rollbacks zu ermöglichen. Mit
liquibase history
werden die durchgeführten Änderungen angezeigt. Falls alle Tests erfolgreich sind, wird das Deployment für die Produktion freigegeben.Listing 17. Beispiel für ein Deployment-Skriptliquibase --url=$DB_URL --username=$DB_USER --password=$DB_PASSWORD update liquibase --url=$DB_URL --username=$DB_USER --password=$DB_PASSWORD tag $RELEASE_VERSION liquibase --url=$DB_URL --username=$DB_USER --password=$DB_PASSWORD history
- 3. Deployment in Produktion
-
Die gleichen Deployment-Befehle wie für Staging werden auf der Produktionsdatenbank ausgeführt.
- 4. Automatisches Rollback bei Fehlern
-
Falls die Pipeline einen Fehler erkennt, kann ein automatischer Rollback erfolgen:
Listing 18. Beispiel für ein Rollback-Skriptliquibase --url=$DB_URL --username=$DB_USER --password=$DB_PASSWORD rollbackToTag $RELEASE_VERSION liquibase --url=$DB_URL --username=$DB_USER --password=$DB_PASSWORD history
Ähnliche Konfigurationen können zum Beispiel für GitHub Actions erstellt werden.
Offizielle Dokumentation von Liquibase: Using Liquibase with GitLab CI/CD
5. Nützliche Liquibase-Befehle zur Schema-Verwaltung
Liquibase bietet verschiedene Befehle zur Überprüfung der Aktualität des Schemas und zur Verwaltung von Änderungen. Hier sind einige der wichtigsten Befehle:
Befehl | Bedeutung |
---|---|
|
Überprüft, ob alle Changesets korrekt formatiert und konsistent sind. Falls Probleme auftreten, gibt Liquibase eine Fehlermeldung aus, die auf fehlerhafte oder fehlende Changesets hinweist. |
|
Überträgt alle noch nicht angewendeten Änderungen aus den Changelogs auf die Datenbank. |
|
Zeigt an, welche Änderungen noch nicht auf die Datenbank angewendet wurden. Liquibase gibt eine Liste der ausstehenden Changesets zurück. |
|
Vergleicht zwei Datenbanken und zeigt Unterschiede an. Dies ist nützlich, um zu überprüfen, ob und wie sich die Datenbanken in verschiedenen Umgebungen unterscheiden. |
|
Erstellt eine Momentaufnahme der aktuellen Datenbankstruktur, die zum Beispiel für Analysen oder den Vergleich mit späteren Versionen verwendet werden kann. |
|
Führt ein Rollback aus. Dies stellt den Zustand der Datenbank auf einen definierten Punkt zurück und entfernt alle nachfolgenden Änderungen. |
Offizielle Dokumentation von Liquibase: Liquibase-Befehlen. |