【问题标题】:How does LIMIT interact with DELETE by primary key in Postgres? (Fix corrupt unique index)Postgres 中 LIMIT 如何通过主键与 DELETE 交互? (修复损坏的唯一索引)
【发布时间】:2014-04-03 17:11:17
【问题描述】:

我收到了一个陷入奇怪状态的数据库。在过去的某个不确定的时间,我最终遇到了这样一种情况,即我在同一个表中使用相同的主键有重复的行:

=> \d my_table
Table "public.my_table"
       Column       |          Type           | Modifiers 
--------------------+-------------------------+-----------
 id                 | bigint                  | not null
 some_data          | bigint                  | 
 a_string           | character varying(1024) | not null
Indexes:
"my_table_pkey" PRIMARY KEY, btree (id)

=> SELECT id, count(*) FROM my_table GROUP BY id HAVING count(*) > 1 ORDER BY id;
#50-some results, non-consecutive rows.

我不知道数据库是如何进入这种状态的,但我希望能够安全地摆脱它。如果,对于每个重复的主键,如果我执行以下形式的查询:

DELETE FROM my_table WHERE id = "a_duplicated_row" LIMIT 1;

它只是要从表中删除 一个 行,还是要删除具有给定主键的两行?

【问题讨论】:

  • 据我所知,您输入的 SQL 无效 - the Postgres manual page for DELETE statements 没有提及 LIMIT 子句。所以直接问题的答案是“不会,它会出错”。 “如何删除一对重复项中的一行”这个隐含问题的答案可以在别处找到。
  • 问题的标题应该更像“如何修复损坏的唯一索引”

标签: postgresql indexing corruption unique-index


【解决方案1】:

唉,PostgreSQL 还没有为 DELETE 或 UPDATE 实现 LIMIT。如果行在其他方面无法区分,则需要小心使用隐藏的ctid 列来打破关系,就像讨论过的here 一样。或者只是通过从现有表中选择不同的元组并重命名来创建表。

【讨论】:

  • @AndrewRueckert 另外,请阅读wiki.postgresql.org/wiki/Corruption。在您做任何其他事情之前,您应该进行备份 - 最好是文件系统级别的副本 (pg_basebackup) 和带有pg_dump 的逻辑转储。解决冲突后,您应该重新编制索引,然后开始认真调查可能的原因。
猜你喜欢
  • 2013-09-13
  • 2011-04-10
  • 1970-01-01
  • 2014-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多