1. 程式人生 > 其它 >postgresql-索引碎片處理

postgresql-索引碎片處理

識別/回收索引碎片

create extension pgstattuple;
postgres=# SELECT * FROM pgstatindex('idx_fragmented');
-[ RECORD 1 ]------+----------
version            | 4
tree_level         | 2
index_size         | 539639808
root_block_no      | 290
internal_pages     | 189
leaf_pages         | 42739
empty_pages        | 0
deleted_pages      | 22945
avg_leaf_density   | 73.1
leaf_fragmentation | 37.18

碎片率達到37.18%,REINDEX索引,回收不必要的空間。

整個schema的索引碎片檢查

SELECT a.indexrelname, b.* FROM pg_stat_user_indexes a, LATERAL pgstatindex(indexrelname) b where a.schemaname='xxx' and b.leaf_fragmentation>30 ORDER BY leaf_fragmentation DESC; 

但在生產環境中,要執行reindex之類的昂貴操作是非常困難的。由於該操作阻止正在執行的DML語句,因此在業務高峰期間進行重建是完全不可能的,該操作通常需要在停機時執行。而在PostgreSQL 12版之後, 新增了REINDEX CONCURRENTLY

選項,它可以線上重建不會阻塞DML操作。最後建議在REINDEX操作後再執行ANALYZE更新一下統計資訊。

檢查損壞索引

INDEX 和 資料是一體的,到底是資料損壞還是索引損壞的問題. 要驗證這個問題,有一個比較笨的方法,就是通過pg_dump的方式把表匯出,如果這個表被匯出的情況下,則證明表的索引已經損壞了;

如果覺得這樣的操作對於大表不是太合理,可以通過查詢 explain analyze 的方式來進行,檢視查詢中的資料結果是否一致

set enable_indexscan='off';

如果兩次查詢的結果是不一致的,使用索引和不使用索引的結果是不同的. 這已經能證明索引出了問題。

也可以用pg_catcheck

來進行系統的資料的完整性的檢查.