【问题标题】:Liquibase - Error on SYSTEM.DATABASECHANGELOGLOCK while re-executing a migrationLiquibase - 重新执行迁移时 SYSTEM.DATABASECHANGELOGLOCK 出错
【发布时间】:2013-07-29 22:07:35
【问题描述】:

我正在使用 Liquibase 3.0.2、Ant 任务 updateDatabase 和使用 cmets 等直接在 SQL 脚本中定义的更改集

--liquibase formatted sql
--changeset com.noemalife:1 dbms:oracle

等等

第一次运行正常,所有更改集都已执行,数据库对象(oracle)已部署。我可以看到 DATABASECHANGELOG 和 DATABASECHANGELOGLOCK 表已填满。

然后我尝试使用完全相同的配置重新运行 Ant 任务,期望 Liquibase 会说“好的,一切都已部署,这里无事可做。”

但我得到了这个:

C:\Users\dmusiani\Desktop\liquibase-test>ant migrate
Buildfile: build.xml

migrate:
     [copy] Copying 1 file to C:\Users\dmusiani\Desktop\liquibase-test

BUILD FAILED
liquibase.exception.LockException: liquibase.exception.DatabaseException: Error executing SQL CREATE
 TABLE SYSTEM.DATABASECHANGELOGLOCK (ID INTEGER NOT NULL, LOCKED NUMBER(1) NOT NULL, LOCKGRANTED TIM
ESTAMP, LOCKEDBY VARCHAR2(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID)); on jdbc:oracl
e:thin:@localhost:1521:WBMDINSERT INTO SYSTEM.DATABASECHANGELOGLOCK (ID, LOCKED) VALUES (1, 0): ORA-
00955: nome giÓ utilizzato da un oggetto esistente

        at liquibase.lockservice.LockServiceImpl.acquireLock(LockServiceImpl.java:122)
        at liquibase.lockservice.LockServiceImpl.waitForLock(LockServiceImpl.java:62)
        at liquibase.Liquibase.update(Liquibase.java:123)
        at liquibase.integration.ant.DatabaseUpdateTask.executeWithLiquibaseClassloader(DatabaseUpda
teTask.java:45)
        at liquibase.integration.ant.BaseLiquibaseTask.execute(BaseLiquibaseTask.java:70)
        at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:288)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
        at org.apache.tools.ant.Task.perform(Task.java:348)
        at org.apache.tools.ant.Target.execute(Target.java:357)
        at org.apache.tools.ant.Target.performTasks(Target.java:385)
        at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1337)
        at org.apache.tools.ant.Project.executeTarget(Project.java:1306)
        at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
        at org.apache.tools.ant.Project.executeTargets(Project.java:1189)
        at org.apache.tools.ant.Main.runBuild(Main.java:758)
        at org.apache.tools.ant.Main.startAnt(Main.java:217)
        at org.apache.tools.ant.launch.Launcher.run(Launcher.java:257)
        at org.apache.tools.ant.launch.Launcher.main(Launcher.java:104)
Caused by: liquibase.exception.DatabaseException: Error executing SQL CREATE TABLE SYSTEM.DATABASECH
ANGELOGLOCK (ID INTEGER NOT NULL, LOCKED NUMBER(1) NOT NULL, LOCKGRANTED TIMESTAMP, LOCKEDBY VARCHAR
2(255), CONSTRAINT PK_DATABASECHANGELOGLOCK PRIMARY KEY (ID)); on jdbc:oracle:thin:@localhost:1521:W
BMDINSERT INTO SYSTEM.DATABASECHANGELOGLOCK (ID, LOCKED) VALUES (1, 0): ORA-00955: nome giÓ utilizza
to da un oggetto esistente

        at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:56)
        at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:98)
        at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:64)
        at liquibase.database.AbstractJdbcDatabase.checkDatabaseChangeLogLockTable(AbstractJdbcDatab
ase.java:771)
        at liquibase.lockservice.LockServiceImpl.acquireLock(LockServiceImpl.java:95)
        ... 21 more
Caused by: java.sql.SQLException: ORA-00955: nome giÓ utilizzato da un oggetto esistente

        at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:113)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
        at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:754)
        at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:210)
        at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:963)
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1192)
        at oracle.jdbc.driver.OracleStatement.executeInternal(OracleStatement.java:1731)
        at oracle.jdbc.driver.OracleStatement.execute(OracleStatement.java:1701)
        at liquibase.executor.jvm.JdbcExecutor$1ExecuteStatementCallback.doInStatement(JdbcExecutor.
java:86)
        at liquibase.executor.jvm.JdbcExecutor.execute(JdbcExecutor.java:49)
        ... 25 more

Total time: 1 second
C:\Users\dmusiani\Desktop\liquibase-test>

在我看来,Liquibase 正在尝试重新创建 DATABASECHANGELOGLOCK 表。

当我使用 Oracle“系统”用户运行 Liquibase 时遇到了这个问题(我的补丁关心创建几个其他用户,因此出于测试目的,我直接使用系统来执行此操作)。 另一个奇怪的是,系统补丁运行成功后,在锁表中我仍然可以看到锁处于活动状态。 当我在其他模式中运行其他补丁时(例如由系统补丁创建的补丁),我的补丁成功完成并且锁表中的锁被释放;重新启动该补丁会按预期运行:Liquibase 检测到该补丁已就位,但不执行任何操作。

这就是说,现在我怀疑 Liquibase 是否存在问题,在系统架构中,在检测锁定表是否已经存在(并且尝试部署它失败)或者是否存在某种锁定/提交问题。

欢迎提出建议

谢谢

大卫

【问题讨论】:

  • 同样的问题,使用 Maven 插件。
  • 你不应该永远,在任何情况下都不能在SYSTEM帐户中创建用户表,但我已经告诉过你了。
  • (在我的例子中,我不在那里创建表,我只是在其他模式之间删除/创建同义词)

标签: liquibase


【解决方案1】:

我和你面临同样的问题。 根据我从sources 看到的情况,当以 SYSTEM 身份运行时,以下条件 (DatabaseSnapshot#include) 被评估为 true。

    if (database.isSystemObject(example)) {
        return null;
    }

因此,将始终尝试创建。 我会在补丁上进一步工作并为您提供最新信息。

这是patch proposal

【讨论】:

  • 我看到了更改提案,我承认我不是 Java 开发专家,但听起来不错。但是我有一个疑问:硬编码表的名称(搜索的字符串“DATABASECHANGELOG”)会不会有风险?我正在考虑允许更改版本和锁定表名的 ant“updateDatabase”参数......如果有人想使用不同的表名会发生什么?
  • 啊,好地方,无论如何我可能不得不更改我的 PR,以便它通过主要来源。我也会等 Liquibase 的人来检查一下。
  • 我将拉取请求的修改版本提交到 3.0.3,它没有硬编码表名。希望下周初能推出 3.0.3。
猜你喜欢
  • 2017-09-29
  • 1970-01-01
  • 2021-02-12
  • 2018-11-01
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-29
相关资源
最近更新 更多