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?

3voto

DarthPablo Punkte 156

Ich schätze, dass dies nicht das Problem des OP war, aber ich bin kürzlich auf dieses Problem gestoßen, das eine andere Ursache hatte. Zur Information: Ich habe das Liquibase Maven-Plugin (liquibase-maven-plugin:3.1.1) mit SQL Server verwendet.

Wie dem auch sei, ich hatte irrtümlicherweise eine SQL Server "use"-Anweisung in eines meiner Skripte kopiert und eingefügt, das die Datenbanken wechselt. Daher wurde Liquibase ausgeführt und hat den DATABASECHANGELOGLOCK aktualisiert, den Lock in der richtigen Datenbank erworben, dann jedoch die Datenbanken gewechselt, um die Änderungen anzuwenden. Ich konnte meine Änderungen oder die Liquibase-Prüfung natürlich NICHT in der richtigen Datenbank sehen. Als ich Liquibase erneut ausführte, konnte es den Lock nicht erwerben, da der Lock in der "falschen" Datenbank freigegeben wurde und somit in der "richtigen" Datenbank immer noch gesperrt war. Ich hätte erwartet, dass Liquibase überprüft, ob der Lock noch vor dem Freigeben angewendet wird, und vielleicht ist dies ein Bug in Liquibase (den ich noch nicht überprüft habe), aber es könnte in späteren Versionen behoben sein! Trotzdem könnte man sagen, dass es sich um eine Funktion handelt!

Ein ziemlich grober Fehler, ich weiß, aber ich erwähne es hier, falls jemand auf dasselbe Problem stößt!

3voto

Manchmal funktioniert es nicht, die Tabelle DATABASECHANGELOGLOCK abzuschneiden oder zu löschen. Ich benutze die PostgreSQL-Datenbank und bin auf dieses Problem schon oft gestoßen. Was ich zur Lösung mache, ist die vorbereiteten Anweisungen, die im Hintergrund für diese Datenbank laufen, zurückzurollen. Versuchen Sie, alle vorbereiteten Anweisungen zurückzurollen und die Liquibase-Änderungen erneut zu versuchen.

SQL:

SELECT gid FROM pg_prepared_xacts WHERE database='database_name';

Wenn die obige Anweisung Datensätze zurückgibt, dann rollen Sie diese vorbereitete Anweisung mit der folgenden SQL-Anweisung zurück.

ROLLBACK PREPARED 'gid_obtained_from_above_SQL';

3voto

Danny Punkte 132

Bitte lassen Sie Liquibase seine eigenen Tabellen verwalten. Das Richtige zu tun, wie user1434769 erwähnt, ist Liquibases releaseLocks-Befehl zu verwenden.

Bei der Verwendung von Gradle wäre dies: gradlew releaseLocks

2voto

Sprooose Punkte 485

Früher habe ich die DatabaseChangeLogLock-Tabelle einfach abgeschnitten, wenn nach einem Fehler ein Sperrvorgang bestehen blieb (und das funktioniert im Allgemeinen immer noch für mich).

Allerdings gibt es jetzt dieses Projekt (https://github.com/blagerweij/liquibase-sessionlock), das native Datenbanksitzungssperren zur Sperrung von Liquibase verwendet, wenn Oracle, PostgreSQL und MySQL verwendet werden.

Die JAR-Datei kann in eine vorhandene Liquibase 4.x+-Anwendung eingefügt werden und wird automatisch von Liquibase erkannt. Dadurch werden Sitzungssperren zur Sperrung verwendet, die automatisch freigegeben werden, wenn die Anwendung abstürzt oder beendet wird, während die Sperre gehalten wird. Dies kann verhindern, dass der Sperrzustand eintritt (wenn eines der unterstützten Datenbanken verwendet wird).

1voto

g.momo Punkte 516

In Postgres 12 musste ich diesen Befehl verwenden:

UPDATE DATABASECHANGELOGLOCK SET LOCKED=false, LOCKGRANTED=null, LOCKEDBY=null where ID=1;

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