pg_restore错误:函数raise_err(unknown)不存在。

7

我使用pg_dump和pg_restore每天备份我的数据库,但最近在我推送更新后备份停止了。

我有一个名为validate_id的函数,它是一个Case/When语句,用于快速检查一些具有完整性问题的数据。大致如下:

CREATE OR REPLACE FUNCTION validate_id(
    _string text,
    _type type
) RETURNS boolean AS
$$
SELECT
    CASE WHEN (stuff) THEN TRUE
    WHEN (other stuff) THEN TRUE
    When (more stuff) THEN raise_err('Not an accepted type, the accepted types are: x y z')
ELSE FALSE
$$
LANGUAGE SQL;

自从我添加了这个函数后,当我使用以下命令进行转储时: pg_dump -U postgres -h ipaddress -p 5432 -w -F t databaseName > backupsfolder/databaseName.tar 当我使用以下命令时: pg_restore -U postgres -h localhost -p 5432 -d postgres -C "backupsfolder/databaseName.tar" 从两天前开始,现在会抛出一个错误: pg_restore: error: could not execute query: ERROR: function raise_err(unknown) does not exist 我很困惑该怎么办。 我认为可能正在恢复raise_err函数之前尝试恢复这个函数。 我认为raise_err是Postgres内置函数(我可以SELECT raise_err('Hello, World');)。 这是可能的吗? 是我的CASE语句因为我需要返回布尔值吗? 所有权限似乎都正确,并且用先前的备份进行还原没有问题。

2
使用 psql 登录源数据库,然后执行\df+ raise_err。据我所知,这不是一个标准函数。你应该不需要另一个函数来引发错误,因为你可以直接使用 raise error - Mike Organek
这个在用sql编写的函数中能行吗,还是必须要用plpgsql - HelpMeExitVim
\df+ raise_err 返回函数。我不记得曾经明确创建过它,但是,事情总会发生。 - HelpMeExitVim
1
抱歉我没有想到那个。 语言sql不支持它,这可能解释了为什么你将其编写为函数。此外,是raise exception,而不是我在早期评论中错误地说的raise error。看起来有时会发生这种情况:https://stackoverflow.com/q/30707533/13808319 - Mike Organek
1
不要觉得自己很蠢,我认为创建那个函数是完全有道理的。我怀疑这是一个“语言sql”函数,在pg_backup期间寻找依赖关系时可能会使算法混淆。 - Mike Organek
显示剩余2条评论
2个回答

6

问题在于您的函数代码中raise_err没有模式限定。

这可能很危险:恶意用户可以创建自己的函数raise_err,并设置search_path,从而调用错误的函数。

由于pg_restore通常是由超级用户运行的,因此这可能会造成安全问题。想象一下这样一个函数在索引定义中被使用!

出于这些原因,在当前版本的PostgreSQL中,pg_dumppg_restoresearch_path设置为空。

解决您的问题的方法是在SQL语句中显式地使用函数的模式。


1
我最终通过明确设置 raise_err()validate_id() 函数的搜索路径为 public 来解决了这个问题。
ALTER FUNCTION validate_id(text,text) SET search_path=public;
ALTER FUNCTION raise_err(text,text) SET search_path=public;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接