Postgresql 我在postgres上发现了不一致的数据

Postgresql 我在postgres上发现了不一致的数据,postgresql,Postgresql,我有一个关于postgres的数据表。此表称为“table1”,对字段“id”具有唯一约束。此表还有3个其他字段,“写入日期”、“状态”、“状态详细信息” 一直以来,我在访问这些表并将其与另一个以字段“id”作为关系字段的表连接时都没有遇到任何问题。但是,这一次,当我查询这个表1时,我得到了一个奇怪的结果 当我运行此查询(称为Query1)时: 它为我提供了两行数据,具有相同的id,但其他字段的值不同: id || write_date || state |

我有一个关于postgres的数据表。此表称为“table1”,对字段“id”具有唯一约束。此表还有3个其他字段,“写入日期”、“状态”、“状态详细信息”

一直以来,我在访问这些表并将其与另一个以字段“id”作为关系字段的表连接时都没有遇到任何问题。但是,这一次,当我查询这个表1时,我得到了一个奇怪的结果

当我运行此查询(称为Query1)时:

它为我提供了两行数据,具有相同的id,但其他字段的值不同:

id     ||         write_date        || state || state_detail

168972      2019-07-30 14:29:06.945      1           80
168972      2019-07-30 19:42:49.314      2          120
但是,当我运行这个查询(称为Query2)时:

它只给我一行:

id     ||         write_date        || state || state_detail
168972      2019-07-30 19:42:49.314      2          120
为什么会有不同的结果呢。我的意思是,我选中了“table1”,它有唯一的约束“id”作为主键。但是,这怎么会发生呢


我已重新启动postgres服务,并再次运行这两个查询。它仍然给出与上面相同的结果。

这看起来像是索引损坏的情况,特别是在id列上的唯一索引上。能否运行以下查询:

SELECT ctid, id, write_date, state, state_detail FROM table1
WHERE write_date = '2019-07-30 19:42:49.314' or write_date = '2019-07-30 14:29:06.945'
您可能会收到2行返回的id,带有两个不同的CTID。ctid表示每行在磁盘上的物理位置。假设返回两行,则需要选择一行并删除另一行,以便“修复”数据。此外,您还需要在表上重新创建唯一索引,以防止这种情况再次发生


哦,如果您在表中找到其他类似的行,请不要感到惊讶。根据损坏的来源(坏磁盘、坏内存、最近的崩溃、升级到glibc?),这可能是未来麻烦的征兆。我可能会仔细检查所有表是否存在任何问题,重新创建任何唯一索引,并查看操作系统级别是否存在磁盘损坏或I/O错误的迹象。如果你没有使用最新版本的Postgres,你应该升级

id
的数据类型是什么?Postgres的确切版本是什么(
select version()
会告诉您)。一些旧版本确实存在唯一索引损坏的bug,但它们现在都已修复。
reindex table1
是否更改了此项?@KaushikNayak列“id”是整数类型。@一个没有名字的马,这是在我使用postgres8.4时发生的。我还没有重新编制table1的索引,因为我想table1只有一个id为168972的数据。因此,这不会违反“id”的唯一约束。让我感到困惑的是,当我在table1.id=table2.tbl1_id列上选择这些行数据id=168972并将其与另一个表(假设它是“table2”,假设它只有一行数据)连接时,它会给我两个具有不同细节的数据。你不应该再使用那个版本了。如果这确实是由Postgres中的一个bug引起的,那么你永远也无法修复这个bug。谢谢@xzilla,这对我帮助很大。现在我可以删除未使用的数据,并修复唯一约束。
id     ||         write_date        || state || state_detail
168972      2019-07-30 19:42:49.314      2          120
SELECT ctid, id, write_date, state, state_detail FROM table1
WHERE write_date = '2019-07-30 19:42:49.314' or write_date = '2019-07-30 14:29:06.945'