SELECT COUNT(*) 返回错误结果

RUN*_*CMD 4 postgresql index unique-constraint aurora amazon-rds

我在 RDS Aurora 上的 PostgreSQL 9.6.3 上看到了一些非常奇怪的行为。

我从某些查询中得到重复的结果:

=> select count(id) from foos where id = 'deadbeef';
 count 
-------
 2
(1 row)

=> select id from foos where id = 'deadbeef';
            id            
--------------------------
 deadbeef
 deadbeef
(2 rows)

=> select id, created_at from foos where id = 'deadbeef';
            id            |         created_at         
--------------------------+----------------------------
 deadbeef                 | 2018-01-01 10:00:00.000000
(1 row)
Run Code Online (Sandbox Code Playgroud)

(id 值、时间戳和表名已被混淆)

我在这张桌子或任何其他桌子上都没有桌子继承。

这似乎只影响恰好命中foos表上一个索引的查询。

因为这似乎与单个索引隔离,我想运行REINDEX 可能会解决这个问题。

但是,我不知道有多少索引表现出这种行为。

例如,这是通过不同索引对同一记录的类似行为:

=> select bar from foos where bar = 'qux';
                  bar                  
-----------------------------------------
 qux
 qux
(2 rows)

=> select id from foos where bar = 'qux';
            id            
--------------------------
 deadbeef
(1 row)

=> select bar, id from foos where bar = 'qux';
                  bar                    |            id            
-----------------------------------------+--------------------------
 qux                                     | deadbeef
(1 row)

=> select bar, created_at from foos where bar = 'qux';
                  bar                    |         created_at         
-----------------------------------------+----------------------------
 qux                                     | 2018-01-01 10:00:00.000000
(1 row)
Run Code Online (Sandbox Code Playgroud)

以下是该表的相关索引:

Indexes:
    "pk_foos" PRIMARY KEY, btree (id)
    "index_foos_on_bar" UNIQUE, btree (bar)
Run Code Online (Sandbox Code Playgroud)

以下是前几个示例的解释计划:

=> explain select id from foos where id = 'deadbeef';
                                 QUERY PLAN                                 
----------------------------------------------------------------------------
 Index Only Scan using pk_foos on foos  (cost=0.42..8.44 rows=1 width=25)
   Index Cond: (id = 'deadbeef'::text)
(2 rows)

=> explain select id, created_at from foos where id = 'deadbeef';
                              QUERY PLAN                               
-----------------------------------------------------------------------
 Index Scan using pk_foos on foos  (cost=0.42..8.44 rows=1 width=33)
   Index Cond: (id = 'deadbeef'::text)
(2 rows)
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

或者,我怎样才能弄清楚这里发生了什么?

jja*_*nes 5

这当然看起来像一个损坏的索引。首先,获取数据库快照并将其存储在没有人具有写访问权限的地方。

这是 RDS Aurora 而不是社区 PostgreSQL,您的第一个(也可能是最后一个)求助方法是与 AWS 支持人员交谈。

如果需要,您可以尝试重新索引整个数据库,但如果索引损坏,则表中也可能损坏。当然,如果您执行的任何数据修改未能更新它们应该拥有的所有行,或者如果您根据业务决策修改了任何数据,这些数据依赖于具有错误结果的查询,则这种类型的损坏将是不可见的。重新索引(或任何继续使用数据库)可能会破坏对腐败的取证分析可能有用的证据,因此是上面的“第一件事”。

如果您设置了数据保留,以便您可以将时间点恢复到很远的过去,您可以进行测试以查看任何特定损坏实例出现的时间。