我在 CentOS 7.3 上运行了一个 PostgreSQL 9.4 数据库。该数据库相当原始,通过以下方式安装https://yum.postgresql.org/。
我正在尝试备份此数据库,并在另一台主机上测试恢复。如果我尝试使用 进行恢复--set ON_ERROR_STOP=on
,则恢复会失败。这是为什么?
我的备份程序基于以下建议https://www.postgresql.org/docs/9.4/static/backup-dump.html。在全新安装 Postgres(包括 initdb)后,我使用以下命令。
pg_dumpall --clean | gzip | split --suffix-length=4 --numeric-suffixes --additional-suffix=.split.gz --bytes 1G - postgres.pg_dumpall.
这将生成一系列如下文件:
[postgres@db1 backups]$ ls
postgres.pg_dumpall.0000.split.gz
postgres.pg_dumpall.0001.split.gz
...
postgres.pg_dumpall.0040.split.gz
[postgres@db1 backups]$
为了恢复,我想我可以使用cat
,gunzip
和psql --set ON_ERROR_STOP=on
。然而这不起作用:
[postgres@db2 ~]$ cat postgres.pg_dumpall.*.split.gz | gunzip | psql --set ON_ERROR_STOP=on postgres
SET
SET
SET
ERROR: database "foo" does not exist
[postgres@db2 ~]$
如果我删除,命令将完成--set ON_ERROR_STOP=on
,但我不清楚备份档案是否有效。
答案1
选项--clean
添加pg_dumpall
了删除每个数据库然后重新创建它们的命令。如果数据库不存在,则命令DROP DATABASE foo
将失败并出现错误,这将停止启用的脚本ON_ERROR_STOP
。
使用--clean --if-exists
inpg_dumpall
生成命令,这些命令将首先检查数据库是否存在,然后再删除它。如果数据库不存在,这些命令将产生通知而不是错误。
要删除导致问题的其他命令,您可以使用sed
aftergunzip
从脚本中删除该命令。在删除命令之前,您应该了解该命令的作用(在本例中是尝试删除超级用户)。多个 sed 命令将在;
给出的带引号的字符串中用分隔sed
。此命令应d
删除脚本将尝试删除并重新创建postgres
超级用户帐户的行。
cat postgres.pg_dumpall.*.split.gz | gunzip | sed '/^DROP ROLE.*postgres/d;/^CREATE ROLE.*postgres/d' | psql --set ON_ERROR_STOP=on postgres