KSl*_*moe 33 postgresql backup restore
我正在使用 pg_dump / pg_restore 来备份和恢复 PostgreSQL 数据库,但是从 pg_restore 收到一些错误消息(和非零退出状态)。我尝试了一个超级简单的基本案例(如下所述),但仍然出现以下错误:
pg_restore: [archiver (db)] 处理 TOC 时出错:
pg_restore: [archiver (db)] 目录条目 5 中的错误;2615 2200 SCHEMA公共postgres
pg_restore: [archiver (db)] 无法执行查询:错误:架构“public”已经存在
命令是:CREATE SCHEMA public;
重现步骤:
创建一个测试数据库。我只是在做:
vagrant@vagrant-ubuntu-trusty-64:~$ psql --username=postgres postgres psql (9.3.5) 输入“帮助”以获得帮助。 postgres=# 创建数据库 mydb; 创建数据库 postgres=# \q vagrant@vagrant-ubuntu-trusty-64:~$ psql --username=postgres mydb psql (9.3.5) 输入“帮助”以获得帮助。 mydb=# 创建表数据(条目 bigint); 创建表 mydb=# 插入数据值(1); 插入 0 1 mydb=# 插入数据值(2); 插入 0 1 mydb=# 插入数据值(3); 插入 0 1 mydb=# \q
像这样创建数据库的备份:
PGPASSWORD="postgres" pg_dump --dbname=mydb --username=postgres --format=custom > pg_backup.dump
从 mydb 中的数据表中删除一些行,以便我们能够判断是否成功恢复了数据。
使用以下命令恢复数据库:
PGPASSWORD="postgres" pg_restore --clean --create --dbname=postgres --username=postgres pg_backup.dump
数据已恢复,但步骤 6 中的 pg_restore 命令以状态退出1并显示以下输出:
pg_restore: [archiver (db)] 处理 TOC 时出错:
pg_restore: [archiver (db)] 目录条目 5 中的错误;2615 2200 SCHEMA公共postgres
pg_restore: [archiver (db)] 无法执行查询:错误:架构“public”已经存在
命令是:CREATE SCHEMA public;
警告:还原时忽略的错误:1
我不能忽略这一点,因为我正在以编程方式运行此命令,并且需要使用退出状态来确定还原是否失败。最初,我想知道这个问题是否是因为我将我的数据库公开(默认模式)。我推断--create在恢复数据之前 pg_restore的选项会创建 public (可以想象也可以尝试创建该模式,因为那是我的表所在的位置),但是当我对我的表尝试上述步骤时在不同的模式中,结果是相同的,错误消息是相同的。
难道我做错了什么?为什么我看到这个错误?
Dan*_*ité 25
该错误是无害的,但要摆脱它,我认为您需要将此还原分解为两个命令,如下所示:
dropdb -U postgres mydb && \
pg_restore --create --dbname=postgres --username=postgres pg_backup.dump
Run Code Online (Sandbox Code Playgroud)
--cleanpg_restore 中的选项看起来并不多,但实际上引发了不小的问题。
对于版本高达 9.1
pg_restore 选项中的--create和组合--clean曾经是旧 PG 版本(最高 9.1)中的错误。之间确实存在一些矛盾(引用 9.1 联机帮助页):
--clean 在重新创建之前清理(删除)数据库对象
和
--create 在恢复之前创建数据库。
因为在一个全新的数据库内部进行清理有什么意义?
从 9.2 版本开始
该组合现在已被接受,并且文档这样说(引用 9.3 联机帮助页):
--clean 在重新创建之前清理(删除)数据库对象。(如果目标数据库中不存在任何对象,这可能会生成一些无害的错误消息。)
--create 在恢复之前创建数据库。如果还指定了 --clean,则在连接之前删除并重新创建目标数据库。
现在将两者放在一起会导致恢复期间的这种序列:
DROP DATABASE mydb;
...
CREATE DATABASE mydb WITH TEMPLATE = template0... [other options]
...
CREATE SCHEMA public;
...
CREATE TABLE...
Run Code Online (Sandbox Code Playgroud)
DROP每个单独的对象都没有,只有一个DROP DATABASE开头。如果不使用--create这将是相反的。
无论如何,这个序列会引发public模式已经存在的错误,因为创建mydb自template0已经导入了它(这是正常的,这是模板数据库的重点)。
我不确定为什么这种情况不是由pg_restore. 当管理员决定自定义template0和/或更改 的目的时public,这可能会导致不良副作用,即使我们不应该这样做。
小智 9
就我而言,原因是我使用pg_restorepostgresql-contrib 版本 11.2 将pg_dump9.6 生成的转储恢复到 PostgreSQL 集群 9.6。
在我降级pg_restore到 9.6 后,这个schema "public" already exists错误消失了,恢复过程和以前一样工作。
小智 7
就我而言,我能够通过先运行CREATE DATABASE target_db;然后运行pg_restore来解决这个问题--schema=public -d target_db。这假设您只需要公共模式,但我认为这是很常见的情况。