问题概述
现场实施发来求救,简单查询数据表报错, 业务应用出现异常
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.....'