【问题标题】:Liquibase fails to perform migration due to "duplicate" index on PostgreSQL database由于 PostgreSQL 数据库上的“重复”索引,Liquibase 无法执行迁移
【发布时间】:2017-10-28 12:59:02
【问题描述】:

我有一个 Liquibase 迁移作为我的 Spring Boot 应用程序的一部分来初始化我的数据库。出于开发目的,在 H2 内存数据库下,Liquibase 执行了迁移,没有任何问题。但是,当我针对 PostgreSQL 数据库运行它时,Liquibase 无法迁移,因为 PostgreSQL 返回以下内容:

原因:org.postgresql.util.PSQLException:错误:关系“idx_channel_id”已经存在

请注意,正在应用索引的表是全新的,并且 Liquibase 迁移文件中没有其他同名索引。如果我删除这个索引创建,它只会在下一个失败。如果我删除索引(或将它们移动到单独的迁移,该迁移通过调用 PostgreSQL 数据库的前提条件排除),迁移成功但根本没有索引。

我一直在摸索这个问题,但我被困住了。完整的 Liquibase 迁移如下:

databaseChangeLog:
  - changeSet:
      id: 1
      author: rmorrison
      changes:
        - createTable:
            tableName: shouts
            columns:
              - column:
                  name: id
                  type: bigint
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: discord_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: author_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: channel_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: guild_nickname
                  type: varchar(255)
                  constraints:
                    nullable: false
              - column:
                  name: content
                  type: varchar(2000)
                  constraints:
                    nullable: false
              - column:
                  name: created
                  type: blob
                  constraints:
                    nullable: false
        - createTable:
            tableName: contexts
            columns:
              - column:
                  name: id
                  type: bigint
                  autoIncrement: true
                  constraints:
                    primaryKey: true
                    nullable: false
              - column:
                  name: discord_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: author_id
                  type: varchar(18)
                  constraints:
                    nullable: false
              - column:
                  name: guild_nickname
                  type: varchar(255)
                  constraints:
                    nullable: false
              - column:
                  name: content
                  type: varchar(2000)
                  constraints:
                    nullable: false
              - column:
                  name: created
                  type: blob
                  constraints:
                    nullable: false
        - createTable:
            tableName: shouts_contexts
            columns:
              - column:
                  name: shout_id
                  type: bigint
                  constraints:
                    nullable: false
              - column:
                  name: context_id
                  type: bigint
                  constraints:
                    nullable: false
        - createIndex:
            indexName: idx_channel_id
            tableName: shouts
            unique: false
            columns:
              - column:
                  name: channel_id
                  type: varchar(18)
        - createIndex:
            indexName: idx_author_channel_id
            tableName: shouts
            unique: false
            columns:
              - column:
                  name: author_id
                  type: varchar(18)
              - column:
                  name: channel_id
                  type: varchar(18)
        - createIndex:
            indexName: idx_content
            tableName: shouts
            unique: true
            columns:
              - column:
                  name: content
                  type: varchar(2000)

编辑:我重新配置了 PostgreSQL 以启用语句日志记录,现在我看到了 - 看起来这毕竟可能不是 Liquibase。继续调查...

< 2017-05-27 19:13:19.697 EDT > LOG:  execute <unnamed>: BEGIN
< 2017-05-27 19:13:19.698 EDT > LOG:  execute <unnamed>: CREATE TABLE public.shouts (id BIGSERIAL NOT NULL, discord_id VARCHAR(18) NOT NULL, author_id VARCHAR(18) NOT NULL, channel_id VARCHAR(18) NOT NULL, guild_nickname VARCHAR(255) NOT NULL, content VARCHAR(2000) NOT NULL, created OID NOT NULL, CONSTRAINT PK_SHOUTS PRIMARY KEY (id))
< 2017-05-27 19:13:19.718 EDT > LOG:  execute <unnamed>: CREATE TABLE public.contexts (id BIGSERIAL NOT NULL, discord_id VARCHAR(18) NOT NULL, author_id VARCHAR(18) NOT NULL, guild_nickname VARCHAR(255) NOT NULL, content VARCHAR(2000) NOT NULL, created OID NOT NULL, CONSTRAINT PK_CONTEXTS PRIMARY KEY (id))
< 2017-05-27 19:13:19.725 EDT > LOG:  execute <unnamed>: CREATE TABLE public.shouts_contexts (shout_id BIGINT NOT NULL, context_id BIGINT NOT NULL)
< 2017-05-27 19:13:19.727 EDT > LOG:  execute <unnamed>: CREATE INDEX idx_channel_id ON public.shouts(channel_id)
< 2017-05-27 19:13:19.727 EDT > ERROR:  relation "idx_channel_id" already exists
< 2017-05-27 19:13:19.727 EDT > STATEMENT:  CREATE INDEX idx_channel_id ON public.shouts(channel_id)
< 2017-05-27 19:13:19.741 EDT > LOG:  execute S_1: ROLLBACK

【问题讨论】:

    标签: java spring spring-boot liquibase


    【解决方案1】:

    我解决了这个问题。事实证明 PostgreSQL 要求索引名称在表中是唯一的。我有一个“备份”表,其中包含具有相同索引名称的旧数据导致冲突。我删除了有问题的表,现在迁移成功没有问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-22
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 2018-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多