Postgresql

SELECT COUNT(*) 返回不正確的結果

  • March 24, 2018

我在 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)

(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)

以下是該表的相關索引:

Indexes:
   "pk_foos" PRIMARY KEY, btree (id)
   "index_foos_on_bar" UNIQUE, btree (bar)

這是前幾個範例的解釋計劃:

=> 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)

這裡發生了什麼?

或者,我怎樣才能弄清楚這裡發生了什麼?

這當然看起來像一個損壞的索引。首先,拍攝數據庫快照並將其儲存在沒有人可以寫入的地方。

這是 RDS Aurora 而不是社區 PostgreSQL,您的第一個(也可能是最後一個)資源將是與 AWS 支持人員交談。

如果需要,您可以嘗試重新索引整個數據庫,但如果索引損壞,表中也可能損壞。當然,如果您執行的任何數據修改未能更新他們應該擁有的所有行,或者如果您根據業務決策修改了任何數據,這些決策依賴於錯誤結果的查詢,那麼這種類型的損壞將是不可見的。重新索引(或任何繼續使用數據庫)可能會破壞可能對腐敗的取證分析有用的證據,因此上面的“第一件事”。

如果您設置數據保留,以便您可以將時間點恢復到遙遠的過去,您可以進行測試以查看任何特定損壞實例出現的時間點。

引用自:https://dba.stackexchange.com/questions/202044