尝试创建尚不存在的函数引用表时 pg_restore 失败

问题描述 投票:0回答:4

我已经使用

pg_dump --no-privileges --format custom --compress=0 some_database > my-dump.pgdump
转储数据库,但当我尝试恢复它时遇到了问题。

具体来说,它似乎是在表定义之前加载函数定义:

$ pg_restore ./my-dump.pgdump
…

create function my_function() returns …
language sql $$
  select …
  from some_table
  where …
$$;

… later in the dump …

create table some_table ( … );

…

当我尝试恢复转储时,这会导致错误:

pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 4863; 0 16735 TABLE DATA some_table some_database
pg_restore: [archiver (db)] COPY failed for table "some_table": ERROR:  relation "some_table" does not exist
LINE 3:                     from some_table
                                 ^
QUERY:
                    select …
                    from some_table
                    where …

CONTEXT:  SQL function "my_function" during inlining

这是怎么回事?我怎样才能欺骗

pg_dump
/
pg_restore
按正确的顺序做事?

postgresql pg-dump pg-restore
4个回答
6
投票

检查转储文件中是否有与

search_path
混淆的命令,例如:

SELECT pg_catalog.set_config('search_path', '', false);

在我继承的遗留项目中,我遇到了与您相同的错误(关系xxx不存在......在内联期间),即使它运行的是 PostgreSQL 9.4.x。

我追踪到了上面的命令。

我的解决方案是从转储文件中删除此命令。

完成此操作后,我能够毫无错误地恢复数据库。


3
投票

注意:OP 使用的是自定义格式。无需编辑发出的二进制文件。

根据我的经验,使用自定义格式(-Fc)的 pg_dump 不会设置 check_function_bodies = false。但由于它在转储文件的顶部添加了随机函数(而不是将所有例程放在末尾),这会导致 pg_restore 崩溃。

我可以通过设置 PGOPTIONS 来解决此问题:

export PGOPTIONS="-c check_function_bodies=false"
pg_restore ...

0
投票

这很奇怪。自从 2003 年提交 ef88199f611e625b496ff92aa17a447d254b9796 以来,

pg_dump
pg_restore
已经发出了

SET check_function_bodies = false;

此设置可确保不会发生您所描述的错误,因为 PostgreSQL 不会检查函数体的有效性。

您是否正在使用古老的 PostgreSQL 版本,或者您是否正在做任何其他可能会造成混乱的事情?

如果您在转储上运行

pg_restore
(未指定目标数据库),它会发出该行吗?


0
投票

我晚了 5 年,但答案是:这是一个“已知”错误。您可以阅读 Bruce Momjian 的更多相关内容。这是因为您使用的是“纯”

SQL
函数,并且这些函数不会被
check_function_bodies=false
忽略。

就我而言,我需要重新访问我的数据库结构,然后才能从 pg15 升级到 pg16。

© www.soinside.com 2019 - 2024. All rights reserved.