Liquibase锁 - 原因?

Pet*_*erg 227 database oracle liquibase

我在针对Oracle服务器运行大量liquibase脚本时得到了这个.有些电脑是我.

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)
Run Code Online (Sandbox Code Playgroud)

可能会达到同时进行的会话/交易次数吗?有人有什么想法吗?

Adr*_*Ber 502

有时,如果更新应用程序突然停止,则锁定仍然卡住.

然后跑

UPDATE DATABASECHANGELOGLOCK SET LOCKED=FALSE, LOCKGRANTED=null, LOCKEDBY=null where ID=1;
Run Code Online (Sandbox Code Playgroud)

对数据库的帮助.

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

  • 我需要为`FALSE'切换出`0`,但除此之外,它运行正常.谢谢 (19认同)
  • 在Liquibase中有一个名为releaseLocks的内置命令可以执行@Adrian Ber的回答,但我认为它与数据库无关. (6认同)
  • 我需要将“b'0”的“FALSE”切换掉 (3认同)
  • 这是正确的解决方案,不要尝试清空表,因为这无济于事.DROP它或将LOCKED标志更新为'FALSE' (2认同)

e18*_*18r 51

这可能是由于一个被杀死的liquibase进程未在DATABASECHANGELOGLOCK表上释放其锁定.然后,

DELETE FROM DATABASECHANGELOGLOCK;
Run Code Online (Sandbox Code Playgroud)

可能会帮助你.

编辑: @Adrian Ber的答案提供了比这更好的解决方案.只有在解决问题时遇到任何问题才能执行此操作.

  • 不要按照上面的建议.DATABASECHANGELOGLOCK必须包含没有任何行的行,您将获得异常 (8认同)
  • 这并没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论。 (4认同)

Pet*_*erg 22

问题是Liquibase中的SequenceExists的错误实现.由于这些陈述的变更集需要很长时间,并且意外中止.然后下一次尝试执行liquibase-scripts锁定.

  <changeSet author="user" id="123">
    <preConditions onFail="CONTINUE">
      <not><sequenceExists sequenceName="SEQUENCE_NAME_SEQ" /></not>
    </preConditions>
    <createSequence sequenceName="SEQUENCE_NAME_SEQ"/>
  </changeSet>
Run Code Online (Sandbox Code Playgroud)

解决方法是使用纯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>
Run Code Online (Sandbox Code Playgroud)

Lockdata存储在表DATABASECHANGELOCK中.要摆脱锁定,只需将1更改为0或删除该表并重新创建.

  • 在 liquibase 3.0.2(我正在使用的版本)中,不要从锁表中删除一行,否则下次运行 liquibase 时会出现不同的错误,因为 liquibase 期望该行存在(或整个表丢失)。正如彼得所说,只是想添加该信息,因为在旧版本中,它似乎也可以删除该行。 (2认同)

Myk*_*ych 12

您可以手动或使用查询安全地删除表。它将自动重新创建。

DROP TABLE DATABASECHANGELOGLOCK;
Run Code Online (Sandbox Code Playgroud)


k_o*_*_o_ 5

没有提到哪个环境用于执行Liquibase。如果是Spring Boot 2,则可以扩展liquibase.lockservice.StandardLockService而无需运行直接得多的SQL语句。例如:

/**
 * This class is enforcing to release the lock from the database.
 *
 */
 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("Could not enforce getting the lock.", e);
        }
        super.waitForLock();
    }
}
Run Code Online (Sandbox Code Playgroud)

该代码正在强制释放锁。这在测试设置中很有用,在测试设置中,如果发生错误或调试中止,则可能不会调用release调用。

该类必须放在liquibase.ext包中,并由Spring Boot 2自动配置获取。