Postgresql 损坏的索引怎么查出来,解决了他

当PostgreSQL的表或索引文件损坏时,查询可能会出现异常。损坏的索引可能导致全表扫描、idx_scan远小于seq_scan,以及数据读取错误。通过查询pg_class和pg_namespace可以定位损坏的文件。若查询计划显示使用索引与不使用索引结果不同,说明索引存在问题。可以使用pg_dump验证或通过EXPLAIN ANALYZE观察查询行为。修复方法包括使用pg_reindex或在POSTGRES 12及以上版本中使用reindex concurrently在线重建索引。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

POSTGRESQL 中如果你的表文件有损坏,则在查询中会直接告诉你某些文件缺失,你无法对这个表进行查询,或操作. 如果是索引可能就没有这么的简单了.

当一个索引文件有问题的情况下,会遇到什么情况

1  查询的时候明明有索引,但查询的时候大部分情况走全表扫描

2  通过pg_stat_user_tables可以看到 idx_scan 明显比 seq_scan要小的多

3  部分数据有时候无法获得

(postgresql 页面的结构)

当读取信息时会遇到错误,并在错误日志中对数据无法读取的信心进行记录.

通过pg_class 和   pg_namespace 进行查询,发现到底 24643 是那个文件

select n.nspname AS schema, c.relname AS realtion 

from pg_class c 

inner join pg_namespace n on (c.relnamespace = n.oid) where c.relfilenode = '3456'; 

文件和物理文件就有了一一对应.

而此时会有一个问题,就是INDEX 和 数据是一体的,到底是数据损坏还是索引损坏的问题. 要验证这个问题,有一个比较笨的方法,就是通过pg_dump的方式把表导出,如果这个表被导出的情况下,则证明表的索引已经损坏了.

如果觉得这样的操作对于大表不是太合理,可以通过查询 explain analyze 的方式来进行,查看查询中的数据结果是否一致.

例如

postgres=# explain analyze select * from pgbench_accounts where  aid>1 and aid <10000 ;                                                           QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan on pgbench_accounts  

(cost=174.61..21830.00 rows=11126 width=97)

(actual time=1.775..4.469 rows=9998 loops=1)   

Recheck Cond: ((aid > 1) AND (aid < 10000))  

Heap Blocks: exact=164   ->  Bitmap Index Scan on idx_pgbench_accounts  (cost=0.00..171.83 rows=11126 width=0) (actual time=1.720..1.720 rows=9998 loops=1)    

Index Cond: ((aid > 1) AND (aid < 10000)) Planning time: 0.242 ms Execution time: 5.286 ms (7 rows)

postgres=# set enable_indexscan='off';

SET 

postgres=# explain analyze select * from pgbench_accounts where aid >10000000; 

                                                         

QUERY PLAN 

Seq Scan on pgbench_accounts  (cost=0.00..4889345.00 rows=89592207 width=97) (actual time=1859.666..15070.333 rows=90000000 loops=1)   

Filter: (aid > 10000000)  

Rows Removed by Filter: 10000000 Planning time: 0.161 ms Execution time: 18394.457 ms (12 rows) 

明显两次查询的结果是不一致的,使用索引和不使用索引的结果是不同的. 这已经能证明索引出了问题.

当然可以通过 pg_catcheck 来进行系统的数据的完整性的检查.

在索引出现问题后,我们通过reindex的方式,在一个 maintenance windows 的情况下进行相关的数据索引的建立.

或者采用POSTGRESQL 12 版本中的 reindex concurrently 的方式进行在线的索引建立.

如果你的POSTGRESQL 版本低于12 ,则也可以通过建立一个重复的索引,通过 create index concurrently 的方式,在建立索引后,在清理失效的索引.(PG 11)

PostgreSQL中,索引失效可能有多种原因。以下是一些常见的原因: 1. 索引重复:在同一列上创建多个相同的索引可能会导致索引失效。这可能会导致性能问题,因为查询优化器可能会选择错误的索引。 2. 数据分布不均匀:如果索引列的数据分布不均匀,即某些值的频率很高,而其他值的频率很低,那么索引可能会失效。这是因为查询优化器可能会认为使用索引不划算,而选择全表扫描。 3. 数据类型不匹配:如果查询中使用的数据类型与索引列的数据类型不匹配,索引可能会失效。例如,如果索引列是字符串类型,而查询中使用的是数字类型,那么索引将无法使用。 4. 查询条件不适合索引:如果查询条件不适合索引索引可能会失效。例如,如果查询中使用了函数、表达式或运算符,这些无法使用索引进行优化。 5. 索引过期或损坏:如果索引过期或损坏,它们可能会失效。在这种情况下,您可能需要重新创建索引。 以下是一个示例,演示了如何在PostgreSQL中创建索引以及可能导致索引失效的情况: ```sql -- 创建表 CREATE TABLE tb_l1 AS SELECT * FROM pg_class; -- 创建索引 CREATE INDEX idx_tb_l1 ON tb_l1 (oid); -- 创建重复索引(会导致性能问题) CREATE INDEX idx_tb_l1 ON tb_l1 (oid); -- 创建多个索引(可能导致性能问题) CREATE INDEX idx_tb_l1 ON tb_l1 (oid); CREATE INDEX idx_tb_l2 ON tb_l1 (oid); ``` 请注意,以上示例中的重复索引和多个索引都可能导致性能问题和索引失效。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值