我正在使用 PostgreSQL 8.4.15。运行pg_dump
备份数据库时,出现以下错误:
pg_dump: SQL command failed
pg_dump: Error message from server: ERROR: missing chunk number 0 for toast value 123456789 in pg_toast_987654321
pg_dump: The command was: COPY public.my_table (id, .... all the columns ...)
在搜索此错误消息时,我发现了一些建议重新索引表的参考资料(此处和此处)。(在这些讨论中,有提到查询pg_class
表以找到正确的pg_toast_XXXXXX
值,但似乎是因为它没有显示在他们的错误消息中。我跳过了这部分,因为我在错误消息中显示了一个值. 我想这可能是由于 PostgreSQL 的更高版本而带来的便利。)
我运行了以下内容:
REINDEX table pg_toast.pg_toast_987654321;
VACUUM ANALYZE my_table;
我现在可以毫无错误地使用pg_dump
。
pg_toast
这些命令实际上是做什么的?这些仅仅是简单的清理,还是他们已经摆脱了该表中的某些行?首先是什么导致了这个问题?
该表中大约有 300000 行,但我预计自上次成功备份以来只有大约 250 条新行(该表仅用于 INSERT/SELECT,没有 UPDATE)。
鉴于您所做的是重新索引,可能发生的情况是它使用索引扫描来尝试定位表中的烘烤值并且找不到。这听起来像是一个损坏的索引。真空分析确实会改变表,但重新索引不会,并且更改非常小。
考虑这一点的方法是,TOASTed 属性实际上被分解成大约 4k 大小的块,并且这些块存储在行中。它们在查询时被查找并与主行排序/重新连接。听起来这里使用的索引已损坏,因此重新索引解决了问题。
我发现损坏的索引通常表明服务器出现问题。最好检查并确保内存、CPU 和硬盘驱动器都正常并且没有报告问题。我发现过热的服务器特别容易导致索引损坏,如果索引可能会损坏,则必须担心数据也会损坏。