【问题标题】:PostgreSQL 9.1 pg_restore error regarding PLPGSQL关于 PLPGSQL 的 PostgreSQL 9.1 pg_restore 错误
【发布时间】:2012-04-27 11:49:03
【问题描述】:

我正在为一个 django 项目使用 Postgres,我目前正在实现一个数据库备份/恢复系统,该系统尽可能简单地在用户单击备份时执行 pg_dump,然后在他们单击恢复备份时执行 pg_restore。

在它实际尝试执行 pg_restore 并给出此错误之前,一切看起来都很好:

pg_restore: [archiver (db)] 来自 TOC 条目 3206 的错误; 0 0 条评论 EXTENSION plpgsql pg_restore: [archiver (db)] 无法执行查询: 错误:必须是扩展 plpgsql 命令的所有者:注释打开 扩展 plpgsql 是“PL/pgSQL 过程语言”;

我已经研究了 plpgsql 是什么等,我明白这一点,关于错误,我尝试手动将“扩展的所有者”设置为执行脚本并拥有数据库本身但没有改变的用户,它真的很烦人,因为它在尝试设置所有事物的评论时出错

这一切都是由 pg_dump 自动创建的,因此无法删除注释行,也没有禁用 cmets 的标志(我知道这是关闭的),所以我真的不知道如何解决这个问题。

【问题讨论】:

  • 如果您使用 psql 连接并输入 \l,您会在该数据库的“所有者”列中看到什么?由于 plpgsql 是一种不受信任的语言,它只能由数据库所有者或数据库超级用户修改(我猜这甚至适用于对它的评论)。
  • 我可以确认数据库的所有者是正确的,并且与 pg_restor 命令的 -U 选项指定的用户匹配(以及 pg_dump 也是)
  • 不幸的是,事情没那么简单。我有 pg_dump 输出,希望能够使用这些语言创建语言和函数。如果我以 DB 超级用户的身份手动创建语言,则函数创建会因权限错误而失败。如果我不这样做,程序语言安装会由于权限错误而失败。在任何一种情况下,也无法创建依赖于这些现有功能的更下方的触发器,因为这些功能不存在。

标签: postgresql plpgsql database-restore


【解决方案1】:

似乎 pg_restore 试图恢复一些您不拥有的额外数据。尝试将-n public 选项添加到您的 pg_restore 命令行。它会告诉 pg_restore 只恢复公共模式的内容。你的命令行应该是这样的

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

【讨论】:

  • 此选项是否涉及恢复后的信息丢失?也就是说,它会丢失任何重要数据吗?
  • @C2H5OH 这取决于。当您的数据库备份包含多个模式时,上述命令将仅导入模式“公共”(=信息丢失)。如果您转储仅包含模式“公共”,那么您没有问题(请参阅:pg_dump --exclude-schema)。要检查转储文件中的模式,请运行以下命令:pg_restore -l -F t dumpfile.tar | grep 架构 | awk -F " " '{print $(NF-1)}' -
  • 这解决了我 pg_restore 尝试加载其他扩展的问题,在我们的场景中这是不允许的。
  • 如果你使用大对象也需要小心,它们不会被恢复
【解决方案2】:

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

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

【讨论】:

  • 这对我有用。虽然是一个警告,第二个命令会将所有内容打印到STDOUT,因此您可能希望将其重定向到文件。
  • 有没有办法在一个命令中做到这一点?我有一个自动化的流程,但这是行不通的。
【解决方案3】:

如果您正在运行 Postgres 11's (or higher) version of pg_dump,那么您可以利用新的 --no-comments 标志。

【讨论】:

  • 如果您使用 tableplus 并且您使用的是 postgres:9.6,那么您可以在选项侧边栏上写下这个。
【解决方案4】:

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

您可以这样做:

COMMENT ON EXTENSION plpgsql IS null;

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

之后创建的转储应该可以正常恢复。

【讨论】:

    【解决方案5】:

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

    【讨论】:

    • 为了确保所有内容都使用“-U 用户名”标志作为同一用户调用
    【解决方案6】:

    在这个命令之后为我工作 -

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 2014-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多