Datenbankänderungen automatisiert erkennenLiquibase – Versionskontrolle für die Datenbank
Von
Dr. Dirk Koller
6 min Lesedauer
In der Welt der Datenbanken helfen verschiedene Werkzeuge beim Tracken, Versionieren und Deployen von Änderungen. In diesem Beitrag betrachten wir die Datenbank-Versionkontrolle Liquibase genauer.
Liquibase legt die Tabellen DATABASECHANGELOG und DATABASECHANGELOGLOCK automatisch an.
(Bild: Koller)
Der Weg einer Code-Änderung von der Entwicklung über Test bis hin zum produktiven Deployment ist in den meisten Projekten dank Versionsverwaltung und Continuous-Integration und -Delivery- oder kurz CI/CD-Werkzeugen stets sauber nachvollziehbar. Jederzeit ist klar, welche Version wo ausgeliefert ist.
Was für den Code gilt, sollte natürlich auch für die Datenbankanpassungen gelten. Schließlich kommt nur im Zusammenspiel eine lauffähige Anwendung heraus. Die in der Java-Welt bekanntesten Versionskontrollsysteme für Datenbanken sind Liquibase und Flyway. Beide sind weit verbreitet und bieten ein ähnliches Set an Features.
Als Ausgangspunkt wird hier ein Spring Boot-Projekt verwendet, wie es sich mit dem Initializr oder der Spring Toolsuite (File > New > Spring Starter Project) erstellen lässt. Dabei werden die Dependencies H2 Database, Spring Data JPA, Spring Web, Spring Boot Devtools und Liquibase Migration zugefügt. Liquibase Migration entspricht folgendem Eintrag in pom.xml:
Die H2-Datenbank soll hier im Persistenzmodus betrieben werden, nur so lassen sich einige der Liquibase-Features ausprobieren. Der Speicherort wird zusammen mit Username und Password sowie der Aktivierung der h2-Konsole in der Datei application.properties konfiguriert:
Datenbankänderungen werden von Liquibase in Form von Changesets verwaltet. Anders als beim Konkurrenten Flyway lassen sich diese Datenbankübergreifend in Form von XML oder JSON formulieren. Im Folgenden ist ein Beispiel im XML-Format für das Anlegen einer Tabelle Person wiedergegeben. Die Datei mit Namen create.xml wird im Verzeichnis src/main/resources/db/changelog abgelegt:
Damit Liquibase das ChangeSet findet, ist eine weitere Datei erforderlich: db.changelog-master.xml, ebenfalls in src/main/resources/db/changelog anzulegen, listet alle durchzuführenden Changes auf. Hier wird die zuvor angelegte Datei inkludiert:
Die Eigenschaft spring.liquibase.enabled=true in application.properties veranlasst Liquibase dazu, beim Start der Anwendung alle nicht bereits eingespielten ChangeSets ausführen. Danach kann die Anwendung gestartet werden. Logausgaben weisen schon darauf hin, dass die Tabelle angelegt wurde.
17:53:08.772 INFO 230924 --- [ restartedMain] liquibase.database : Set default schema name to PUBLIC 17:53:08.953 INFO 230924 --- [ restartedMain] liquibase.lockservice : Changelog-Protokoll erfolgreich gesperrt. 17:53:09.267 INFO 230924 --- [ restartedMain] liquibase.changelog : Creating database history table with name: PUBLIC.DATABASECHANGELOG 17:53:09.271 INFO 230924 --- [ restartedMain] liquibase.changelog : Reading from PUBLIC.DATABASECHANGELOG Running Changeset: db.changelog-master.xml::1::dirk 17:53:09.366 INFO 230924 --- [ restartedMain] liquibase.changelog : Table person created 17:53:09.367 INFO 230924 --- [ restartedMain] liquibase.changelog : ChangeSet db.changelog-master.xml::1::dirk ran successfully in 5ms 17:53:09.376 INFO 230924 --- [ restartedMain] liquibase.lockservice : Successfully released change log lock
Liquibase legt die Tabellen DATABASECHANGELOG und DATABASECHANGELOGLOCK automatisch an.
(Bild: Koller)
Wer dem nicht traut, kann die h2-Konsole unter http://localhost:8080/h2-console öffnen und sich das Datenbankschema anschauen. Neben der Tabelle Person mit den definierten Spalten finden sich dort zwei weitere Tabellen, die Liquibase automatisch anlegt.
In der Tabelle DATABASECHANGELOG merkt sich Liquibase, welche ChangeSets bereits ausgeführt wurden. Damit wird also verhindert, dass ein bereits eingespieltes ChangeSet erneut angewendet wird. Mithilfe der DATABASECHANGELOGLOCK-Tabelle wird sichergestellt, dass nur eine Liquibase-Instanz läuft und keine konkurrierenden Zugriffe, zum Beispiel von mehreren gleichzeitig startenden Anwendungsinstanzen, stattfinden können. Beide interne Tabellen sollte man selbstverständlich nur lesend verwenden.
Ein ChangeSet zum Einspielen von Testdaten könnte folgendermaßen aussehen:
An bekannter Stelle (src/main/resources/db/changelog) abgelegt und in db.changelog-master.xml inkludiert, wird es beim erneuten Start der Anwendung ausgeführt. Die im ChangeSet vergebene id muss übrigens eindeutig sein, hier empfiehlt sich eine sinnvolle Namenskonvention (aufsteigende Nummern, Datum mit Uhrzeit oder Ähnliches).
Arbeiten mit dem Plug-in
Im einfachen Beispiel oben wurde Liquibase in die Anwendung integriert. Beim Start werden eventuell vorhandene neue Changelogs ausgeführt und der Stand der Datenbank entspricht dem Stand des zugreifenden Codes.
Wenn man unabhängig vom Starten der App bleiben möchte (zum Beispiel, weil der alte Code mit der neuen DB-Version klarkommt), lässt sich Liquibase auch mithilfe von Maven-Goals ausführen. Dazu ist in pom.xml das Liquibase-Plug-in einzubinden:
In liquibase.properties werden die Verbindungsdaten zur Datenbank (url, username, password) und der Pfad zu db.changelog-master.xml (changeLogFile) für das Plug-in hinterlegt. Das Ausführen der ChangeSets erfolgt dann mit dem Kommando mvn liquibase:update. Das lässt sich natürlich auch von CI/CD-Tools wie zum Beispiel Jenkins starten.
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel IT-Medien GmbH, Max-Josef-Metzger-Straße 21, 86157 Augsburg, einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von Newslettern und Werbung nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung.
Das Plug-in enthält aber noch eine Menge weiterer nützlicher Werkzeuge. Mit dem Goal liquibase:updateSQL erzeugt man aus dem ChangeSet ein SQL-Skript, das dann vom Datenbankadministrator geprüft und womöglich mit besonderen DBA-Rechten eingespielt werden kann. Auch das generierte SQL-Skript pflegt natürlich die Liquibase-Tabellen, so dass im Endergebnis kein Unterschied zum einfachen update-Goal resultiert.
Ebenfalls sehr hilfreich ist das Goal rollback, mit dem sich ChangeSets rückgängig machen lassen. Für einige Änderungen funktioniert das automatisch, für andere spezifiziert man die Anweisungen explizit mit <rollback>. Weitere Anweisungen ermöglichen das Aufspüren von Unterschieden zwischen zwei Datenbanken (liquibase:diff) oder das Generieren von ganzen ChangeLogs aus einer Datenbank (liquibase:generateChangeLog).
Je nach Kommando können weitere Einträge in liquibase.properties erforderlich sein (zum Beispiel referenceUrl, referenceUsername und referencePassword für den Vergleich zweier Datenbanken). In der Praxis werden das automatische Update und das Maven-Plug-in durchaus nebeneinander eingesetzt (z.B. Startup in Dev, updateSQL in prod). Näheres dazu findet sich im Beitrag „3 Ways to Run Liquibase“.