对于索引,Postgres pg_dump缓存查找失败

时间:2017-12-07 22:22:35

标签: postgresql runtime-error

我正在尝试使用以下命令创建postgres数据库的备份(省略详细信息):

$ pg_dump -h $host -p 5432 -U $user $db > db.sql

一段时间后,我收到错误(格式化)

pg_dump: [archiver (db)] query failed: ERROR:  cache lookup failed for index 1184605879
pg_dump: [archiver (db)] query was: 
SELECT  t.tableoid, 
        t.oid, 
        t.relname AS indexname, 
        pg_catalog.pg_get_indexdef(i.indexrelid) AS indexdef, 
        t.relnatts AS indnkeys, 
        i.indkey, 
        i.indisclustered, 
        false AS indisreplident, 
        t.relpages, 
        c.contype, 
        c.conname, 
        c.condeferrable, 
        c.condeferred, 
        c.tableoid AS contableoid, 
        c.oid AS conoid, 
        pg_catalog.pg_get_constraintdef(c.oid, false) AS condef, 
        (SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) AS tablespace, 
        t.reloptions AS indreloptions 
FROM pg_catalog.pg_index i 
JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) 
LEFT JOIN pg_catalog.pg_constraint c ON (i.indrelid = c.conrelid AND i.indexrelid = c.conindid AND c.contype IN ('p','u','x')) 
WHERE i.indrelid = '1184605870'::pg_catalog.oid AND i.indisvalid AND i.indisready 
ORDER BY indexname

然后我验证了pg_index中的索引ID不存在。有没有办法解决这个问题,或者某种方式忽略这个错误并继续这样我可以继续导出非pg_catalog数据?

3 个答案:

答案 0 :(得分:1)

我编写了一个快速脚本,将每个表单独转储到一个sql文件中,发现它是一些导致缓存失败的临时登录信息。我只是从导出中排除了该表,这很好。

我不是最好的bash程序员,所以它肯定可以改进,但这里是我用来单独转储每个表的脚本,以找出导致错误的表。

#!/bin/bash
host=$1
port=$2
user=$3
db=$4

# Get all table names that you will be dumping individually
query="SELECT tablename FROM pg_tables WHERE tableowner=$user;"
tables=( $(psql -h $host -p $port -U $user $d -c $query) )
mkdir db_dump

dump_command="pg_dump -h $host -p $port -U $user"
for table in $(tables[@]); do
    eval "$dump_command -t $table $db > db_dump/$table.sql"
done

答案 1 :(得分:0)

您的数据库已损坏,您应该从备份中恢复。

如果不害怕搞乱目录(首先进行物理备份!):

将配置参数allow_system_table_mods设置为on,以便修改系统目录。然后

DELETE FROM pg_catalog.pg_index WHERE indexrelid = 1184605879;

可能会使您的数据库处于可以转储它的状态(减去该索引)。

如果还有更多问题,您最终可能会使用COPY逐个提取表数据,并查看还可以挽救的其他内容。

答案 2 :(得分:0)

系统索引可能会被破坏。我尝试以下方法:

  1. 停止数据库服务器
  2. 以单用户模式启动数据库,忽略系统和用户定义的索引:

    postgres --single -D /path/to/data --ignore_system_indexes=on --enable_indexscan=off --enable_bitmapscan=off <database>

  3. 重新索引整个数据库(包括目录):REINDEX DATABASE <database>;

  4. 重新启动数据库并尝试再次转储...
  5. 更多:ignore_system_indexesREINDEXenable_bitmapscan/enable_indexscansingle-user mode;