postgresql-索引碎片處理
阿新 • • 發佈:2022-04-13
識別/回收索引碎片
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
REINDEX
操作後再執行ANALYZE更新一下統計資訊。
檢查損壞索引
INDEX 和 資料是一體的,到底是資料損壞還是索引損壞的問題. 要驗證這個問題,有一個比較笨的方法,就是通過pg_dump的方式把表匯出,如果這個表被匯出的情況下,則證明表的索引已經損壞了;
如果覺得這樣的操作對於大表不是太合理,可以通過查詢 explain analyze 的方式來進行,檢視查詢中的資料結果是否一致
set enable_indexscan='off';
如果兩次查詢的結果是不一致的,使用索引和不使用索引的結果是不同的. 這已經能證明索引出了問題。
也可以用pg_catcheck