Liquibaselocking – 原因?

我在运行大量针对Oracle服务器的liquibase脚本时遇到了这个问题。 SomeComputer是我的。

Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Waiting for changelog lock.... Liquibase Update Failed: Could not acquire change log lock. Currently locked by SomeComputer (192.168.15.X) since 2013-03-20 13:39 SEVERE 2013-03-20 16:59:liquibase: Could not acquire change log lock. Currently locked by SomeComputer (192.168.15.X) since 2013-03-20 13:39 liquibase.exception.LockException: Could not acquire change log lock. Currently locked by SomeComputer (192.168.15.X) since 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) 

是否可以达到同时进行的会话/交易的数量? 任何人有任何想法?

有时如果更新应用程序突然停止,那么锁仍然卡住。

然后运行

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

对数据库有帮助。

或者您可以简单地删除DATABASECHANGELOGLOCK表,它将被重新创build。

这可能是由于liquibase进程没有释放对DATABASECHANGELOGLOCK表的locking。 然后,

 DELETE FROM DATABASECHANGELOGLOCK; 

可能会帮助你。

编辑: @Adrian Ber的答案提供了一个比这更好的解决scheme。 只有这样做,如果你有任何问题做他的解决scheme。

问题是Liquibase中SequenceExists的错误实现。 由于这些陈述的变化花了很长时间,并意外中止。 然后下一次尝试执行liquibase脚本锁被保留。

  <changeSet author="user" id="123"> <preConditions onFail="CONTINUE"> <not><sequenceExists sequenceName="SEQUENCE_NAME_SEQ" /></not> </preConditions> <createSequence sequenceName="SEQUENCE_NAME_SEQ"/> </changeSet> 

解决方法是使用普通的SQL来检查,而不是:

  <changeSet author="user" id="123"> <preConditions onFail="CONTINUE"> <sqlCheck expectedResult="0"> select count(*) from user_sequences where sequence_name = 'SEQUENCE_NAME_SEQ'; </sqlCheck> </preConditions> <createSequence sequenceName="SEQUENCE_NAME_SEQ"/> </changeSet> 

锁数据存储在表DATABASECHANGELOCK中。 要摆脱locking,只需将1更改为0或删除该表并重新创build。

我感谢这不是OP的问题,但最近我遇到了这个问题,原因不同。 作为参考,我在SQL Server中使用了Liquibase Maven插件(liquibase-maven-plugin:3.1.1)。

无论如何,我错误地将SQL Server“use”语句复制并粘贴到我的脚本之一切换数据库,所以liquibase正在运行并更新DATABASECHANGELOGLOCK ,获取正确的数据库中的锁,但然后切换数据库以应用更改。 我不仅可以在正确的数据库中看到我的更改或liquibase审计,当然,当我再次运行liquibase时,它不能获得锁,因为锁已经在“错误的”数据库中释放了,所以仍然locking在“正确的”数据库中。 我曾经期待liquibase在释放之前检查这个锁是否仍然被应用,也许这是一个liquibase中的错误(我还没有检查过),但是它可能会在以后的版本中得到解决! 这就是说,我想这可以被认为是一个function!

我知道,这是一个小学生的错误,但是我会在这里提出来,以防有人遇到同样的问题!

有时截断或删除表DATABASECHANGELOGLOCK不起作用。 我使用PostgreSQL数据库并且遇到了这个问题很多次。 我所要解决的是回滚为该数据库在后台运行的预准备语句。 尝试回滚所有准备好的语句,并再次尝试liquibase更改。

SQL:

 SELECT gid FROM pg_prepared_xacts WHERE database='database_name'; 

如果上面的语句返回任何logging,则使用以下SQL语句回滚该准备好的语句。

 ROLLBACK PREPARED 'gid_obtained_from_above_SQL';