392 Stimmen

Liquibase-Sperre - Gründe?

Ich bekomme das, wenn ich viele Liquibase-Skripte gegen einen Oracle-Server ausführe. SomeComputer bin ich.

Warten auf Changelog-Sperre....
Warten auf Changelog-Sperre....
Warten auf Changelog-Sperre....
Warten auf Changelog-Sperre....
Warten auf Changelog-Sperre....
Warten auf Changelog-Sperre....
Warten auf Changelog-Sperre....
Liquibase-Update fehlgeschlagen: Änderungsprotokollsperrung konnte nicht erworben werden. Aktuell gesperrt durch SomeComputer (192.168.15.X) seit 2013-03-20 13:39
SCHWERWIEGEND 2013-03-20 16:59:liquibase: Änderungsprotokollsperrung konnte nicht erworben werden. Aktuell gesperrt durch SomeComputer (192.168.15.X) seit 2013-03-20 13:39
liquibase.exception.LockException: Änderungsprotokollsperrung konnte nicht erworben werden. Aktuell gesperrt durch SomeComputer (192.168.15.X) seit 2013-03-20 13:39
        at liquibase.lockservice.LockService.waitForLock(LockService.java:81)
        at liquibase.Liquibase.tag(Liquibase.java:507)
        at liquibase.integration.commandline.Main.doMigration(Main.java:643)
        at liquibase.integration.commandline.Main.main(Main.java:116)

Könnte es sein, dass die Anzahl der gleichzeitigen Sitzungen/Transaktionen erreicht ist? Hat jemand Ideen?

858voto

Adrian Ber Punkte 18944

Manchmal bleibt das Schloss stecken, wenn die Aktualisierungsanwendung abrupt gestoppt wird.

Dann hilft es,

UPDATE DATABASECHANGELOGLOCK SET LOCKED=0, LOCKGRANTED=NULL, LOCKEDBY=NULL WHERE ID=1;

gegen die Datenbank auszuführen.

Sie müssen möglicherweise auch LOCKED=0 durch LOCKED=FALSE ersetzen.

Oder Sie können einfach die DATABASECHANGELOGLOCK-Tabelle löschen, sie wird neu erstellt.

80voto

e18r Punkte 6410

Bearbeiten Juni 2020

Folgen Sie nicht diesem Rat. Im Laufe der Jahre hat dies vielen Menschen Probleme bereitet. Es hat vor langer Zeit für mich funktioniert und ich habe es in gutem Glauben veröffentlicht, aber es ist klar nicht der richtige Weg. Die Tabelle DATABASECHANGELOCK muss gefüllt sein, daher ist es keine gute Idee, einfach alles daraus zu löschen, ohne die Tabelle zu löschen.

Leos Literak hat beispielsweise diesen Anweisungen gefolgt und der Server konnte nicht gestartet werden.

Ursprüngliche Antwort

Es liegt möglicherweise an einem beendeten Liquibase-Prozess, der sein Schloss an der DATABASECHANGELOGLOCK-Tabelle nicht freigegeben hat. Dann,

DELETE FROM DATABASECHANGELOGLOCK;

könnte Ihnen helfen.

Bearbeiten: @Adrian Bers Antwort bietet eine bessere Lösung als diese. Tun Sie dies nur, wenn Sie Probleme haben, seine Lösung umzusetzen.

28voto

Peter Punkte 5022

Das Problem war die fehlerhafte Implementierung von SequenceExists in Liquibase. Da die Changesets mit diesen Anweisungen sehr lange dauerten und versehentlich abgebrochen wurden. Beim nächsten Versuch, die Liquibase-Skripte auszuführen, wurde das Lock gehalten.

Ein Workaround besteht darin, stattdessen einfaches SQL zu verwenden, um dies zu überprüfen:

              select count(*) from user_sequences where sequence_name = 'SEQUENCE_NAME_SEQ';

Lockdaten werden in der Tabelle DATABASECHANGELOCK gespeichert. Um das Lock loszuwerden, ändern Sie einfach die 1 auf 0 oder löschen Sie diese Tabelle und erstellen Sie sie neu.

16voto

k_o_ Punkte 3939

Es wird nicht erwähnt, in welcher Umgebung Liquibase ausgeführt wird. Im Falle von Spring Boot 2 ist es möglich, liquibase.lockservice.StandardLockService zu erweitern, ohne direkte SQL-Anweisungen ausführen zu müssen, was viel sauberer ist. Z. B.:

/**
 * Diese Klasse erzwingt das Freigeben des Schlosses aus der Datenbank.
 *
 */
 public class ForceReleaseLockService extends StandardLockService {

    @Override
    public int getPriority() {
        return super.getPriority()+1;
    }

    @Override
    public void waitForLock() throws LockException {
        try {
            super.forceReleaseLock();
        } catch (DatabaseException e) {
            throw new LockException("Das Sperren konnte nicht erzwungen werden.", e);
        }
        super.waitForLock();
    }
}

Der Code erzwingt das Freigeben des Schlosses. Dies kann in Testumgebungen nützlich sein, in denen der Freigabeaufruf möglicherweise nicht bei Fehlern aufgerufen wird oder wenn das Debuggen abgebrochen wird.

Die Klasse muss im Paket liquibase.ext platziert werden und wird von der Spring Boot 2 Auto-Konfiguration erkannt.

Liquibase 4

Beachten Sie, dass sich der Mechanismus zum Laden von Erweiterungen in Liquibase 4 geändert hat.

Jetzt muss eine Datei unter META-INF/services mit dem implementierten vollständigen Schnittstellennamen erstellt werden und in dieser Datei müssen alle Erweiterungen aufgelistet werden.

Dies könnte bedeuten, dass in META-INF/services/liquibase.lockservice.LockService

Diese Zeile hinzugefügt werden muss:

com.company.liquibase.impl.ForceReleaseLockService

Ich habe es nicht ausprobiert, benutze immer noch Liquibase 3, bitte bearbeiten und korrigieren.

10voto

Mike Punkte 18362

Sie können die Tabelle sicher manuell oder mithilfe einer Abfrage löschen. Sie wird automatisch neu erstellt.

DROP TABLE DATABASECHANGELOGLOCK;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X