PostgreSQL 表文件损坏异常
PostgreSQL 表文件损坏异常
一次意外断电后重启数据库服务,发现一个表对象数据文件损坏,其他的表对象正常,下面是查询该表对象的报错信息。
ERROR: invalid page in block 10 of relation "base/13593/11025587"
提示:PostgreSQL 如何定位一个表对象在系统文件中的位置
SELECT pg_relation_filepath(oid) FROM pg_class WHERE relname = 'test';
接下来我们分析下这个错误信息:
ERROR: invalid page in block 10 of relation "base/13593/11025587"
其中 13593 表示数据库 OID,11025587 表示表对象的 relfilenode。block 10 则表示文件的块号。遇到这种情况时,我们需要尽快将数据恢复。恢复的方法可以从备份中恢复,或者如果有从库并且从库的数据没有损害的情况下,从从库查询到数据,然后重建这个对象以及高可用正常的情况下进行主从切换。
当我们在真实的环境中遇到这种情况时,最理想的恢复是有从库并且从库正常,数据文件没有损坏,将数据从从库拷贝出来然后恢复到主库。那么当我们的环境不满足这个条件时,除了使用备份进行恢复外,还有没有比这个稍微好一些但是又快速的数据恢复的方法呢?因为如果使用备份进行恢复数据往往意味着会丢失一些数据,并且如果后面再进行进一步的数据恢复会非常麻烦,甚至都无法实现数据修复,因为对文件进行了二次伤害。
我们可以使用如下的策略进行数据修复:
先连接到数据库,然后通过系统库找到报错的是哪个数据库下的哪个表对象,然后通过设置损坏块 0 填充的方法,最后回收以及重建该对象的方法进行数据修复。在数据表对象可以正常操作之后,再与用前一天的备份恢复的表进行撞表操作,进行数据对比,下面主要讲一下使用 0 填充的这部分操作。
ERROR: invalid page in block 10 of relation "base/13593/11025587"
SELECT * FROM pg_database WHERE oid = '13593';
\c dbname
SELECT * FROM pg_catalog.pg_class where relfilenode=11025587;
SET zero_damaged_pages = on;
VACUUM FULL tc_customer;
REINDEX TABLE tc_customer;