在安装插件的时候使用\dx元命令的时候,突然发现报了一个错误:
postgres=# \dx
ERROR: missing chunk number 0 for toast value 32789 in pg_toast_2619
根据提示来看,主表字段还留存着Toast Pointer,但Toast表中已经没有对应的Chunk条目,怀疑toast表存在损坏或者缺失数据。
toast表的表名是字符串"pg_toast"与表的oid拼接而成,根据这个pg_toast_2619的2619的oid,可以定位到是pg_statistic的表。
postgres=# select 2619::regclass;
regclass
--------------
pg_statistic
(1 row)
postgres=# select * from pg_statistic;
ERROR: missing chunk number 0 for toast value 32789 in pg_toast_2619
postgres=#
对应toast表的数据可能存在损坏。
需要定位损坏的行的位置,然后可以删除有问题的行。因为pg_statistic的toast数据是更新统计信息的时候插入的,损坏后可以直接清理。vacuum analyze后会重新生成。
其他系统表损坏比较建议建议zero_damaged_pages设置为on来跳过损坏的块,然后备份业务数据,之后恢复到一个新的环境。
可以暂时先做下简单的修复,看是否能解决问题,可能执行过程会出现报错:
postgres=# REINDEX TABLE pg_toast.pg_toast_2619;
postgres=# REINDEX TABLE pg_statistic;
postgres=# VACUUM ANALYZE pg_statistic;
可以使用如下的存储过程
DO $$
DECLARE
rec record;
BEGIN
FOR rec in SELECT * FROM pg_statistic LOOP
raise notice 'Parameter is: %', rec.ctid;
raise notice 'Parameter is: %', rec;
END LOOP;
END;
$$
LANGUAGE plpgsql;
结果如下:
NOTICE: Parameter is: (0,1)
NOTICE: Parameter is: (1255,28,f,0.9830149,1294,-0.016985118,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,)
NOTICE: Parameter is: (0,2)
NOTICE: Parameter is: (1255,29,f,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,,,,,,,,)
NOTICE: Parameter is: (0,3)