PostgreSQL:损坏的主键,不一致的表

Ada*_*tan 6 postgresql primary-key

在从云故障中恢复时,我发现PostgreSQL数据库中的某些表行为异常。这些表使用主键编制索引,但pg_dump产生重复字段,pg_restore在备份服务器上失败。

我试图REINDEX

REINDEX INDEX rank_details_pkey;
ERROR:  could not create unique index "rank_details_pkey"
DETAIL:  Table contains duplicated values.
Run Code Online (Sandbox Code Playgroud)

指数定义为:

<table info here>
Indexes:
    "rank_details_pkey" PRIMARY KEY, btree (user_id)
Run Code Online (Sandbox Code Playgroud)

而且,奇怪的是,

SELECT user_id, COUNT(*) FROM <table name> GROUP BY 1 HAVING COUNT(*) > 1;
 user_id | count 
---------+-------
(0 rows)
Run Code Online (Sandbox Code Playgroud)

总而言之 - 我的表中有重复的值,无法找到或清除

任何想法如何解决这一问题?这是一个生产服务器,所以所有修复都应该在不影响服务的情况下完成。

Jac*_*las 5

在 Oracle 中,这种情况可以通过多种方式发生 - 我不确定 postgres,但我想我会称其为“完整性违规”而不是“腐败”

也许您可以执行此处建议的操作之一,即set enable_indexscan = off

begin;
drop index rank_details_pkey;
select user_id, count(*) from rank_details group by user_id having count(*) > 1;
rollback;
Run Code Online (Sandbox Code Playgroud)

但是“这可能存在一些锁定问题,因此在生产中要小心”

这个想法是强制查询扫描表而不仅仅是索引(没有重复项)。更简单地说,您还可以通过以下方式实现相同的目标:

select user_id, f(<some other column>), count(*)
from rank_details
group by user_id, f(<some other column>)
having count(*) > 1
Run Code Online (Sandbox Code Playgroud)

其中 f() 返回一个常量,这可能会欺骗规划器进行表扫描。