关于PLPGSQL的PostgreSQL 9.1 pg_restore错误


74

我正在将Postgres用于django项目,并且当前正在实现一个数据库备份/还原系统,该系统尽可能简单,当用户单击“备份”时执行pg_dump,然后在用户单击“还原备份”时执行pg_restore。

一切看起来不错,直到它实际上尝试执行pg_restore时才给出此错误:

pg_restore:[归档器(db)]来自TOC条目3206的错误;0 0 COMMENT EXTENSION plpgsql pg_restore:[存档(db)]无法执行查询:错误:必须是扩展plpgsql的所有者命令是:COMMENT ON EXTENSION plpgsql是'PL / pgSQL程序语言';

我研究了plpgsql是什么,我理解了这一点,对于错误,我尝试手动将“扩展所有者”设置为执行脚本并拥有数据库本身的用户,但并没有改变,这确实令人讨厌试图对所有事物设置注释的错误

这都是由pg_dump自动创建的,因此不能删除注释行,并且没有禁用注释的标志(我知道这些标志已经关闭),因此我对于解决该问题确实很执着。


如果使用psql连接并键入\l,那么在该数据库的“所有者”列中会看到什么?由于plpgsql是一种不受信任的语言,因此数据库所有者或数据库超级用户只能对其进行修改(并且我想这甚至适用于它的注释)。
kgrittn

我可以确认数据库的所有者是正确的,并且与pg_restor命令的-U选项(以及pg_dump)指定的用户匹配
fury-s12 2012年

不幸的是,事情并非如此简单。我有pg_dump输出,期望能够使用这些语言创建语言和函数。如果我以数据库超级用户的身份手动创建语言,则由于权限错误,函数创建失败。如果不这样做,则由于权限错误,过程语言安装失败。无论哪种情况,都无法创建依赖于现有功能的触发器,因为这些功能不存在。
Quixadhal 2012年

Answers:


126

似乎pg_restore尝试还原一些您不拥有的额外数据。尝试-n public在pg_restore命令行中添加选项。它将告诉pg_restore只恢复公共模式的内容。您的命令行应如下所示

pg_restore -U username -c -n public -d database_name

9
恢复后此选项是否会丢失信息?也就是说,它会丢失任何重要数据吗?
C2H5OH

8
@ C2H5OH取决于。当您的数据库备份包含多个模式时,上述命令将仅导入模式“ public”(=信息丢失)。如果转储仅包含架构“ public”,则不会有问题(请参阅:pg_dump --exclude-schema)。要检查转储文件中包含哪些模式,请运行以下命令:pg_restore -l -F t dumpfile.tar | grep SCHEMA | awk -F“”'{print $ {NF-1)}'
DanielaWaranie

2
这解决了我pg_restore尝试加载其他扩展程序的问题,在我们的场景中不允许这样做。
nibbex

2
你还需要,如果你使用大对象要谨慎,他们不会被恢复
彼得·格柏

18

我在此页面上找到以下解决方法:

http://archives.postgresql.org/pgsql-general/2011-10/msg00826.php

这个想法是使用pg_restore -l列出归档文件的内容,grep删除用户无权恢复的扩展名,并使用pg_restore -L在还原时使用这个被删除的列表。

例如:

pg_restore -l ~/database.dump | grep -v "EXTENSION - plpgsql" > ~/restore_elements
pg_restore -L ~/restore_elements ~/database.dump

2
这对我有用。但是,警告是,第二个命令会将所有内容打印到,STDOUT因此您可能希望将其重定向到文件。
shrx 2014年

有一种方法可以仅用一个命令来完成吗?我有一个自动化的流程,这是行不通的。
迭戈

7

如果可能,我建议您在创建任何转储之前删除无法恢复的注释。

您可以通过以下方式进行操作:

COMMENT ON EXTENSION plpgsql IS null;

如果不想对每个新创建的数据库执行此操作,请从名为template1的数据库中删除注释(CREATE DATABASE…复制此数据库。)

此后创建的转储应无错误恢复。



3

您是否正在加载由其他用户创建的数据库?如果可能,请尝试使用创建数据库及其现有对象的同一用户进行还原。


不能确保以“ -U用户名”标志作为同一用户调用所有内容
fury-s12 2012年

3

此命令后对我有用-

Deepak@deepak:~$ sudo -i -u postgres
postgres@deepak:~$ psql 
psql (9.3.5)
Type "help" for help.

postgres=# GRANT ALL PRIVILEGES ON DATABASE database_name TO user;
postgres=# GRANT
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.