【问题标题】:ERROR: more than one owned sequence found in Postgres错误:在 Postgres 中发现多个拥有的序列
【发布时间】:2019-09-04 09:57:57
【问题描述】:

我正在为Patient 表的现有列设置一个标识列。
在这里我想使用 GENERATED ALWAYS AS IDENTITY

所以我使用以下语句设置身份列(以前是serial):

ALTER TABLE Patient ALTER PatientId
   ADD GENERATED ALWAYS AS IDENTITY (START WITH 1);

对于现有的患者表,我总共有 5 条记录。 (patientId 1 到 5)
当我在身份设置后插入新记录时,它会抛出如下错误:

more than one owned sequence found

即使在重置标识列之后,我仍然会收到同样的错误。

ALTER TABLE Patient ALTER COLUMN PatientId RESTART WITH 6;

如果您有任何解决方案,请告诉我。

【问题讨论】:

  • 在您更改之前是否将 patientid 定义为 serial
  • yes 之前定义为serial

标签: postgresql identity-column database-sequence


【解决方案1】:

更新:此错误已在 PostgreSQL v12 中通过提交 19781729f78 修复。
其余答案与旧版本相关。

serial 列有一个由该列拥有的序列和一个获得净序列值的DEFAULT 值。

如果您尝试将该列更改为标识列,则会收到错误,指出该列已经存在默认值。

现在您必须删除默认值,而不是属于serial 列的序列。然后,当您将该列转换为标识列时,会创建该列拥有的第二个序列。

现在当您尝试插入一行时,PostgreSQL 会尝试查找并使用列所拥有的 序列,但有两个,因此出现错误消息。

我认为这是 PostgreSQL 中的一个错误:在我看来,它应该重新利用标识列的现有序列,或者给你一个错误,表明该列已经拥有一个序列,你应该算了吧。 I'll try to get this bug fixed.

同时,您应该手动删除serial 列中留下的序列。 运行以下查询:

SELECT d.objid::regclass
FROM pg_depend AS d
   JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                             d.refobjsubid = a.attnum
WHERE d.classid = 'pg_class'::regclass
  AND d.refclassid = 'pg_class'::regclass
  AND d.deptype <> 'i'
  AND a.attname = 'patientid'
  AND d.refobjid = 'patient'::regclass;

这应该会给你从serial 列留下的序列的名称。删除它,标识列的行为应符合要求。

【讨论】:

  • 作为一个对 postgres 完全陌生的人,当在 pgAdmin 中编写表格以显示屏幕时,看到 PK 字段被列出两次(!!!),我感到非常沮丧。然后同时发现 Uber 的博客指出了一个涉及死元组的错误……我不得不问……我前面有多少错误?我很高兴能继续使用 Postgres,但今天的经历确实挫伤了我的热情。也就是说,感谢您解释原因和解决方案。我现在可以看到我的 PK 字段被列出(这有多疯狂?)只是...一次。
  • 好吧,bug 无处不在,这只是一个不便(这就是为什么它只在 v12 中修复而没有回补的原因)。优步的故事是另一回事。他们在没有透露有关其工作负载的详细信息的情况下对 PostgreSQL 进行了诋毁。 Markus wrote an interesting analysis 他试图猜测发生了什么,这似乎是 a) 滥用关系数据库作为键值存储和 b) 运行大量更新的组合,这是 PostgreSQL 的弱点。跨度>
  • 是的,我看过this,我绝不是想让优步所说的一切合法化。只是在 30 分钟的时间里,我自己发现了一个 bug,然后又参考了 Uber 的 bug,这结合起来确实让我有些不寒而栗。我仍然很高兴继续使用 Postgres。
  • 好吧,您发现了一个已修复的错误。这往往会给我一种很好的感觉。
  • 幽默地说,当我的客户没有发现很多最近出处的错误时,他们会感觉更好,不管是固定的还是其他的。但说真的,我会道歉,因为我可能在这次交流中遇到过挑剔的印象。我不想对这个很棒的 OSS 工具显得忘恩负义。刚开始看this,我意识到你是我应该感谢的众多人之一,尤其是在这段学习期间。感谢您的贡献。
【解决方案2】:

这不是一个答案——道歉,但这让我能够以生动的形象展示我今天早上(无意中)发现的疯狂行为......

我所要做的就是:

alter TABLE db.generic_items alter column generic_item_id drop default;
alter TABLE db.generic_items alter column generic_item_id add generated by default as identity;

现在在将表编写为 SQL 脚本时,我得到(缩写):

CREATE TABLE db.generic_items
(
    generic_item_id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    generic_item_id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    generic_item_name character varying(50) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT pk_generic_items PRIMARY KEY (generic_item_id),
)

感谢 Laurenz Albe 在上面发布的答案!正如他解释的那样,只需删除用于串行默认值的序列,这种疯狂就会消失,表格看起来又正常了。

【讨论】:

  • 这里也一样,谢谢你写了同样的问题,一开始这不是很明显:)
【解决方案3】:

同样,这不是答案,但评论并没有让我添加足够的文字。 道歉。继续我之前的评论。 这就是我执行的操作,它表明,imo,手动修复是不够的,并且对于大型表,我使用的重复技巧(见下文)将是不切实际的并且可能是错误的,因为采用属于已删除行的 id。

-- pls disregard the absence of 2 id rows, this is the final situation    
\d vaste_data.studie_type
                                  Table "vaste_data.studie_type"
     Column |         Type          | Collation | Nullable |             Default
    --------+-----------------------+-----------+----------+----------------------------------
     id     | integer               |           | not null | generated by default as identity
     naam   | character varying(25) |           | not null |
    Indexes:
        "pk_tstudytype_tstudytype_id" PRIMARY KEY, btree (id)
    Referenced by:
        TABLE "stuwadoors" CONSTRAINT "fk_t_stuwadoors_t_studytype" FOREIGN KEY (study_type_id) REFERENCES vaste_data.studie_type(id)
        TABLE "psux" CONSTRAINT "study_studytype_fk" FOREIGN KEY (studie_type_id) FOREIGN KEY (studie_type_id) REFERENCES vaste_data.studie_type(id)
    
    alter table vaste_data.studie_type alter column id drop default;
    ALTER TABLE
    alter table vaste_data.studie_type alter column id add generated by default as identity;
    ALTER TABLE
    -- I chose to show both sequences so I could try to drop either one.
    SELECT d.objid::regclass
    FROM pg_depend AS d
       JOIN pg_attribute AS a ON d.refobjid = a.attrelid AND
                                 d.refobjsubid = a.attnum
    WHERE d.classid = 'pg_class'::regclass
      AND d.refclassid = 'pg_class'::regclass
      AND a.attname = 'id'
      AND d.refobjid = 'vaste_data.studie_type'::regclass;
                      objid
    -----------------------------------------
     vaste_data.studie_type_id_seq
     vaste_data.tstudytype_tstudytype_id_seq
    (2 rows)
    
    drop sequence vaste_data.studie_type_id_seq;
    ERROR:  cannot drop sequence vaste_data.studie_type_id_seq because column id of table vaste_data.studie_type requires it
    HINT:  You can drop column id of table vaste_data.studie_type instead.
    
    \d vaste_data.studie_type_id_seq
                   Sequence "vaste_data.studie_type_id_seq"
      Type   | Start | Minimum |  Maximum   | Increment | Cycles? | Cache
    ---------+-------+---------+------------+-----------+---------+-------
     integer |     1 |       1 | 2147483647 |         1 | no      |     1
    Sequence for identity column: vaste_data.studie_type.id
    
    alter sequence vaste_data.studie_type_id_seq start 6;
    ALTER SEQUENCE
    drop sequence vaste_data.tstudytype_tstudytype_id_seq;
    DROP SEQUENCE
    insert into vaste_data.studie_type (naam) values('Overige leiding');
    ERROR:  duplicate key value violates unique constraint "pk_tstudytype_tstudytype_id"
    DETAIL:  Key (id)=(1) already exists.
    ...
    ERROR:  duplicate key value violates unique constraint "pk_tstudytype_tstudytype_id"
    DETAIL:  Key (id)=(5) already exists.
    insert into vaste_data.studie_type (naam) values('Overige leiding');
    INSERT 0 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-21
    • 2010-11-26
    • 2013-03-20
    • 2016-02-04
    • 2020-11-12
    相关资源
    最近更新 更多