Postgresql 仅使用带有压缩参数的pg_dump可能会导致备份损坏?

Postgresql 仅使用带有压缩参数的pg_dump可能会导致备份损坏?,postgresql,backup,restore,pg,pg-dump,Postgresql,Backup,Restore,Pg,Pg Dump,我使用此命令备份200GB数据库(postgres 9.1,win7 x64): 使用pg\u还原-Ft: [tar archiver] corrupt tar header found in ▼ (expected 13500752, com puted 78268) file position 512 [tar archiver]在中找到损坏的tar头▼ (预计13500752,com 计算78268)文件位置512 Gzip还显示它已损坏。当我在Total Commander中打开备份文件

我使用此命令备份200GB数据库(postgres 9.1,win7 x64):

使用
pg\u还原-Ft

[tar archiver] corrupt tar header found in ▼ (expected 13500752, com puted 78268) file position 512 [tar archiver]在中找到损坏的tar头▼ (预计13500752,com 计算78268)文件位置512 Gzip还显示它已损坏。当我在Total Commander中打开备份文件时,内部文件只有1.8GB。 当我在寻找解决方案时,应该使用
-Cf
参数完成转储

现在文件的格式是什么?它只是tar还是gzip(winrar显示gzip)?
是否有任何方法可以正确还原此文件,或者它是否以某种方式损坏(转储时没有错误)?这可能是因为tar或gzip的文件大小限制吗?

您的转储是纯SQL,它不是tar格式,就像您尝试在pg_还原中使用的那样。如果需要压缩格式,请使用--format=custom或-Fc,并在pg_restore中使用此设置。检查。

在“备份”中作为输出的只是压缩的普通sql。 您可以通过提示进行检查:

gzip -l backup
不幸的是,pg_retore不提供恢复普通SQL的可能性, 因此,您只需解压缩文件并使用
psql-f
命令:

zcat backup > backup.sql
psql -f backup.sql
按照“Frank Heikens”的建议,无法使用postgres 9.1中的
pg_dump-Fc
进行转储, 因为转储格式在主版本之间不兼容,比如9.0->9.1->9.2
“pg_restore”将在9.2上给您一个错误,这是一个旧线程,尽管我遇到了完全相同的问题,并设法用fixgz修复了有点损坏的转储:

简短回答:在压缩转储上运行fixgz

fixgz.exe bad.gz fixed.gz
长答覆: 因此,如果在使用pg_dump时使用--compresss或-Z,而不指定自定义格式选项(-Fc),那么实际得到的是ASCII模式下的压缩文件,而不是二进制模式下的压缩文件

引用

如果您已以ASCII模式传输文件,并且不再具有 访问原版,可以尝试用程序fixgz来删除 传输插入的额外CR(回车)字节。窗户 这里有9x/NT/2000/ME/XP二进制文件。但绝对不能保证 这将实际修复您的文件。结论:永远不要转移 ASCII模式下的二进制文件


大多数情况下,此错误意味着您的还原操作使用了无效格式

从pg_转储的手册(pg_转储-帮助)

这意味着,如果您使用pg_dump创建转储,而不选择--format/-F,则转储将以纯文本格式创建

注意:无法使用pg_restore工具还原纯文本格式。改用psql 示例:

# plain text export/import
pg_dump -Fp -d postgres://<db_user>:<db_password>@<db_host>:<db_port>/<db_name> > dump.sql
psql -d postgres://<target_db_user>:<target_db_password>@<target_db_host>:<target_db_port>/<target_db_name> -f dump.sql

# custom format 
pg_dump -Fc -d postgres://<db_user>:<db_password>@<db_host>:<db_port>/<db_name> > dump.sql.custom
pg_restore -Ft postgres://<target_db_user>:<target_db_password>@<target_db_host>:<target_db_port>/<target_db_name> dump.sql.custom

# tar format 
pg_dump -Ft -d postgres://<db_user>:<db_password>@<db_host>:<db_port>/<db_name> > dump.sql.tar
pg_restore -Ft postgres://<target_db_user>:<target_db_password>@<target_db_host>:<target_db_port>/<target_db_name> dump.sql.tar
#纯文本导出/导入
pg_dump-Fp-d postgres://:@://>dump.sql
psql-d postgres://:@://-f dump.sql
#自定义格式
pg_dump-Fc-d postgres://:@://>dump.sql.custom
pg_restore-Ft postgres://:@:/dump.sql.custom
#tar格式
pg_dump-Ft-d postgres://:@://>dump.sql.tar
pg_restore-Ft postgres://:@:/dump.sql.tar
还原格式与备份不匹配时,也可能出现主题错误。

例如,创建的转储将采用自定义格式,但对于指定的还原tar

我在使用PGAdmin III进行还原时遇到此问题。PGAdmin 4不会出现此问题。

不幸的是,它不是纯SQL。请自己尝试
pg_dump-Z 1…
,如果我只使用
-Z
参数,则手册对我来说不清楚。在纯SQL的情况下,200GB数据库的文件大小将比16GB大得多。这是我一整天都在尝试的。奇怪的是,当使用
pg_dump-Z1 my_new_database>backup创建新转储时,每次备份都会损坏,但在postgres DB上创建的默认DB
pg_dump-Z1 postgres>backup
工作正常。怎么可能?为什么您得出结论,pg_dump-Z1 my_new_database>备份的结果已损坏?到底发生了什么事?我无法以任何方式打开它。一切都返回CRC错误。你可以自己试试。这是测试备份:(0.5kB),这是新备份的纯SQL。我不知道是否有人能做到。不能重复你的错误。对我来说,任何DB都可以正常工作。试着用
gzip
代替
pg_dump-Z1
,就像这样:
pg_dump my_new_database|gzip->backup.gz
使用gzip管道没关系。但我急需旧的后援。你试过我上面的例子吗?如果没有,您可以吗?我在问题的末尾编写了一个编辑解决方案:Windows将新行
\n
替换为
\r\n
。你必须把它换回来。我建议不要在Windows中使用“转发到文件”,而是使用“输出文件”作为
pg_dump
(或您正在使用的任何其他脚本)的参数。@hrtlik我刚刚添加了此答案,作为类似问题的可能解决方案,但这是SO club的另一个根本原因。请你澄清一下你的建议好吗?您是否建议使用PGAdmin 4而不是PGAdmin 3?
fixgz.exe bad.gz fixed.gz
-F, --format=c|d|t|p         output file format (custom, directory, tar,  
                             plain text (default))
# plain text export/import
pg_dump -Fp -d postgres://<db_user>:<db_password>@<db_host>:<db_port>/<db_name> > dump.sql
psql -d postgres://<target_db_user>:<target_db_password>@<target_db_host>:<target_db_port>/<target_db_name> -f dump.sql

# custom format 
pg_dump -Fc -d postgres://<db_user>:<db_password>@<db_host>:<db_port>/<db_name> > dump.sql.custom
pg_restore -Ft postgres://<target_db_user>:<target_db_password>@<target_db_host>:<target_db_port>/<target_db_name> dump.sql.custom

# tar format 
pg_dump -Ft -d postgres://<db_user>:<db_password>@<db_host>:<db_port>/<db_name> > dump.sql.tar
pg_restore -Ft postgres://<target_db_user>:<target_db_password>@<target_db_host>:<target_db_port>/<target_db_name> dump.sql.tar