Замок Liquibase - причины?

132

Я получаю это при запуске большого количества скриптов Liquibase против Oracle-сервера. 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)

Может ли быть достигнуто количество одновременных сеансов/транзакций? У кого-нибудь есть идеи?

  • 1
    Вы убили JVM, пока жидкостьбаза держала замок? Это единственный случай, когда это происходит для меня.
  • 0
    Похоже, здесь задействован другой компьютер: Konsultpc74. Может быть, вы одновременно запускали жидкость на разных компьютерах? Если нет, у вас есть объяснение для другого ПК?
Показать ещё 2 комментария
Теги:
database
liquibase

5 ответов

18
Лучший ответ

Проблема заключалась в ошибочной реализации SequenceExists в Liquibase. Поскольку изменения с этими утверждениями заняли очень много времени и были случайно прерваны. Затем, следующая попытка выполнить скрипты 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>

Lockdata хранится в таблице DATABASECHANGELOCK. Чтобы избавиться от блокировки, вы просто меняете 1 на 0 или бросаете эту таблицу и воссоздаете.

  • 1
    В liquibase 3.0.2 (версия, которую я использую), не удаляйте одну строку из таблицы блокировок, иначе у вас будет другая ошибка при запуске liquibase в следующий раз, потому что liquibase ожидает, что там будет одна строка (или вся таблица отсутствует). Точно так же, как сказал Питер, просто хотел добавить эту информацию, потому что в старых версиях, кажется, работал, чтобы удалить строку.
293

Иногда, если приложение обновления резко останавливается, блокировка остается застрявшей.

Затем запустите

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

против базы данных помогает.

Или вы можете просто отбросить таблицу DATABASECHANGELOGLOCK, она будет воссоздана.

  • 14
    Мне нужно было переключить 0 для FALSE , но в остальном он работал нормально. Спасибо
  • 5
    В Liquibase есть встроенная команда releaseLocks, которая будет выполнять то, что ответил @Adrian Ber, но я думаю, что это не зависит от базы данных.
Показать ещё 4 комментария
22

Возможно, это связано с тем, что убитый процесс ликбазы не освобождает его замок на таблице DATABASECHANGELOGLOCK. Тогда,

DELETE FROM DATABASECHANGELOGLOCK;

может помочь вам.

Изменить: Ответ @Adrian Ber обеспечивает лучшее решение, чем это. Только делайте это, если у вас возникнут проблемы с его решением.

  • 1
    Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий под своим постом.
  • 0
    @Rachcha Я объяснил это лучше. Надеюсь, вам понравится больше, как это.
Показать ещё 3 комментария
0

Иногда усечение или отбрасывание таблицы DATABASECHANGELOGLOCK не работает. Я использую базу данных PostgreSQL и часто сталкивался с этой проблемой. То, что я делаю для решения, - это откат подготовленных операторов, работающих в фоновом режиме для этой базы данных. Попытайтесь отменить все подготовленные заявления и повторите изменения Liquibase.

SQL:

SELECT gid FROM pg_prepared_xacts WHERE database='database_name';

Если вышеприведенный оператор возвращает любую запись, тогда откат, который подготовил оператор с помощью следующего оператора SQL.

ROLLBACK PREPARED 'gid_obtained_from_above_SQL';
0

Я понимаю, что это не проблема OP, но я столкнулся с этой проблемой недавно с другой причиной. Для справки я использовал плагин Liquibase Maven (linibase-maven-plugin: 3.1.1) с SQL Server.

Во всяком случае, я ошибочно скопировал и вставил инструкцию SQL Server "use" в один из моих сценариев, который переключает базы данных, так что Liquibase запускает и обновляет DATABASECHANGELOGLOCK, приобретая блокировку в правильной базе данных, но затем переключая базы данных для применения изменений. Я не только не мог видеть мои изменения или ревизию Liquibase в правильной базе данных, но, конечно, когда я снова запускал Liquibase, он не мог получить блокировку, поскольку блокировка была выпущена в "неправильной" базе данных, и так было все еще заблокирован в "правильной" базе данных. Я бы ожидал, что Liquibase проверит, что блокировка все еще применяется, прежде чем выпустить ее, и, возможно, это ошибка в Liquibase (я еще не проверял), но ее можно решить в более поздних версиях! Тем не менее, я полагаю, это можно считать особенностью!

Довольно немного школьной ошибки, я знаю, но я поднимаю ее здесь, если кто-то столкнется с той же проблемой!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню