DatabaseChangeLogLock gesperrt

Einleitung

Die Sperre auf der Changelog-Tabelle konnte nicht aufgehoben werden. Der Relution-Dienst startet nicht mehr oder fährt immer wieder neu hoch (Docker). Im Log sind folgende Meldungen zu sehen:

ion.boot.LiquibaseConfig: Relution build version is … []
ion.boot.LiquibaseConfig: Database is … (Data source 'dataSource') []
ion.boot.LiquibaseConfig: Detected database type '…', version '…' []
ion.boot.LiquibaseConfig: Registering Liquibase customizations []
iquibase.MariaDBDatabase: Connected to relution@… []
iquibase.MariaDBDatabase: Setting auto commit to false from true []
vice.StandardLockService: Waiting for changelog lock.... []
vice.StandardLockService: Waiting for changelog lock.... []

Die letzte Meldung wiederholt sich dabei periodisch, bis der Dienst schließlich mit einem Timeout beendet wird und ggf. automatisch neu startet (Docker).

Ursachen

Beim Start prüft der Relution-Dienst zunächst, ob Datenbank-Updates ausgeführt werden müssen. Um zu verhindern, dass im Cluster-Betrieb zwei Knoten zur selben Zeit das Datenbankschema verändern, wird dazu immer eine Sperre in der DATABASECHANGELOGLOCK-Tabelle gesetzt. Diese wird nach Abschluss der Prüfung und/oder der Updates wieder aufgehoben.

Wird der Relution-Dienst in diesem Zustand hart beendet, so bleibt diese Sperre bestehen. Beim nächsten Startvorgang wartet Relution darauf, dass die Sperre aufgehoben wird, da der Dienst davon ausgeht, dass ein anderer Knoten die Datenbank aktualisiert. Ist das nach ca. 5 Minuten nicht der Fall, beendet sich der Dienst mit einer entsprechenden Fehlermeldung.

Dieser Zustand tritt meist dann auf, wenn Relution während des Ausführens von größeren Datenbankupdates frühzeitig beendet wird, da der Startvorgang ungewohnt lange dauert.

DatabaseChangeLogLock Wert ändern

Um den Zustand zu beheben, kann entweder der (einzige) Eintrag aus der Tabelle DATABASECHANGELOGLOCK entfernt oder der Wert der Spalte LOCKED von 1 auf 0 geändert werden. Je nach Datenbank wird anstelle von 1 ggf. auch True angezeigt und muss entsprechend auf False geändert werden.

Zum Aktualisieren der Datenbank kann das entsprechende Verwaltungstool der Datenbank oder auch eine freie Alternative verwendet werden (BeeKeeper, DBeaver, HeidiSQL, …). Je nach Datenbank ist das Update auch über entsprechende Kommandozeilentools möglich. Im Fall von MariaDB/MySQL zum Beispiel:

mysql --host=<hostname> --user=<username> --password --database=<database> --execute="TRUNCATE TABLE DATABASECHANGELOGLOCK;"

Die Platzhalter in spitzen Klammern müssen entsprechend mit den Werten aus der application.yml bzw. docker-compose.yml ersetzt werden.