问题概述

现场实施发来求救,简单查询数据表报错,  业务应用出现异常

select * from middXXXXX.t_geo_mv_xxxxxegment_var;
 ERROR: missing chuunk number 0 for toast value 142340922 in pg_toast_2619

问题原因

此报错信息一般为数据库中有坏块导致 。

https://www.postgresql.org/message-id/20211018042128.GB4679@telsasoft.com

解决方案

定位坏块数据,删除坏块数据,从备份还原坏块数据。

查询出哪个表存在坏块:

select relname from pg_class where reltoastrelid = (select oid from pg_class where relname = 'pg_toast_2619');
   relname    
--------------
 pg_statistic

查询出是存储统计信息的表  pg_statistic出现坏块。直接查询该表验证

select * from pg_statistic 
 >ERROR:missing chunk number 0 for toast value 14230922 in pg_toast_2619

和现场实施反馈的错误一致。 因为是统计信息,并不是业务数据,决定删除在坏块中的数据。表修复后再收集该表统计信息

select  * from  pg_statistic  limit 20000;
select  * from  pg_statistic  limit 20000 offset 20000  ; 
select  * from  pg_statistic  limit 20000 offset 40000  ; 
select  * from  pg_statistic  limit 20000 offset 60000  ; 
....依次执行,进行坏块定位

表修复后再收集该表统计信息

select * from pg_statistic  limit 22000 offset  23000;
  >ERROR:missing chunk number 0 for toast value 14230922 in pg_toast_2619
  --其他范围并没用异常

删除出现在坏块的数据

delete from   pg_statistic  where ctid in (   select ctid from  pg_statistic  limit 23000 offset 24000 )

删除后验证

select * from  pg_statistic ;--- 未报错
select * from  middXXXXX.t_geo_mv_xxxxxegment_var;--- 查询之前报错的表,并未再次报错

至此,问题解决。解决之后收集该表统计信息。

如果是业务表。

select  * from   t_geo_xxxxx;
  >ERROR:missing chunk number 0 for toast value 30270345 in pg_toast_47238
....依次执行,进行坏块定位

1 先定位坏块

select  * from   t_geo_xxxxx where obj_id= '26dx45cd.....'
  >ERROR:missing chunk number 0 for toast value 30270345 in pg_toast_47238
select  * from   t_geo_xxxxx where  obj_id= '26dx45cd.....'
---并未报错 证明该条数据再坏块中

2 删除在坏块中的数据

delete from  t_geo_xxxxx   where  obj_id= '26dx45cd.....'

3 从备份表中恢复该条数据( 可以从业务角度评估,该条数据是否可以忽略)

insert into t_geo_xxxxx  
selete  *  from  t_geo_xxxxx_bak   where  obj_id= '26dx45cd.....'