pg_restore: [archiver] 文件头中不支持的版本 (1.14)

Ber*_*ner 45 postgresql ubuntu pg-dump pg-restore

我有一个实时服务器和开发盒,分别称它们为 live 和 dev,它们都运行 postgresql。我可以使用 pgadmin4 轻松查看和管理两者,并且当我在开发箱上以调试模式通过网站运行时,两者都功能齐全,一个是实时网站,另一个是。很普通的设定。

多年来,我一直在运行我编写的相同 bash 脚本,该脚本转储实时数据库,然后在开发箱上恢复它,因此我拥有最新的实时快照。

今天,这让我失望了标题消息:

pg_restore: [archiver] unsupported version (1.14) in file header
Run Code Online (Sandbox Code Playgroud)

我试图诊断这个问题,并在网上进行了广泛的搜索,但我很困惑并且失败了,所以在这里我掌握了专业知识。

为了帮助我将分享以下内容:

$ pg_dump --version
pg_dump (PostgreSQL) 10.11 (Ubuntu 10.11-1.pgdg18.04+1)
$ pg_restore --version
pg_restore (PostgreSQL) 10.11 (Ubuntu 10.11-1.pgdg18.04+1)
$ pg_dump --host=live.lan --port=5432 --dbname=mydb --username=myuser --format=custom > test.backup
$ ls -l test.backup 
-rw-r--r-- 1 bernd bernd 2398358 Dec 23 23:40 test.backup
$ file test.backup 
test.backup: PostgreSQL custom database dump - v1.14-0
$ pg_restore --dbname=mydb test.backup 
pg_restore: [archiver] unsupported version (1.14) in file header
Run Code Online (Sandbox Code Playgroud)

鉴于 pg_dump 和 pg_restore 是相同的版本,并且:

$ which pg_dump
/usr/bin/pg_dump
$ which pg_restore
/usr/bin/pg_restore
$ ls -l /usr/bin/pg_dump /usr/bin/pg_restore
lrwxrwxrwx 1 root root 37 Nov 14 23:23 /usr/bin/pg_dump -> ../share/postgresql-common/pg_wrapper
lrwxrwxrwx 1 root root 37 Nov 14 23:23 /usr/bin/pg_restore -> ../share/postgresql-common/pg_wrapper
Run Code Online (Sandbox Code Playgroud)

我可以看到它们不仅仅是相同的版本,而是由相同的包装脚本运行(恰好是一个 perl 脚本 - 现在这是一种你不再看到的语言,我曾经广泛地编码)

所以我完全困惑了。认为直播机可能存在版本问题:

$ ssh live.lan
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-72-generic x86_64)
$ which pg_dump
/usr/bin/pg_dump
$ which pg_restore
/usr/bin/pg_restore
$ pg_dump --version
pg_dump (PostgreSQL) 10.10 (Ubuntu 10.10-0ubuntu0.18.04.1)
$ pg_restore --version
pg_restore (PostgreSQL) 10.10 (Ubuntu 10.10-0ubuntu0.18.04.1)
Run Code Online (Sandbox Code Playgroud)

我可以看到 live box 确实有稍旧版本的 pg_dump(只有在我的 dev box 上的 pg_dump 以某种方式使用 RPC 到 live box 来运行它的 pg_dump 时才重要)。

现在可能有一个小线索,我的开发箱已经看到了一些 postgresql 升级,例如:

$ pg_lsclusters
Ver Cluster Port Status Owner    Data directory              Log file
10  main    5432 online postgres /var/lib/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
11  main    5433 online postgres /var/lib/postgresql/11/main /var/log/postgresql/postgresql-11-main.log
12  main    5434 online postgres /var/lib/postgresql/12/main /var/log/postgresql/postgresql-12-main.log
Run Code Online (Sandbox Code Playgroud)

空日志文件证明 11 和 12 集群仍未使用。我正在使用 10。但我确实注意到:

$ psql --version
psql (PostgreSQL) 12.1 (Ubuntu 12.1-1.pgdg18.04+1)
$ ssh live.lan
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-72-generic x86_64)
$ psql --version
psql (PostgreSQL) 10.10 (Ubuntu 10.10-0ubuntu0.18.04.1)
Run Code Online (Sandbox Code Playgroud)

这有点可疑,但又不是明显的原因或相关:

  1. 我使用的是 pg_dump 而不是 psql
  2. 我只使用开发盒 pg 工具而不是实时盒(它们应该无关紧要,理论上整个数据传输通过实时盒上的端口 5432 传输数据转储到我的开发盒上的 pg_dump。

这是 love box 上的集群,它位于 live.lan 上的端口 5432 上,我正在运行 pg_dump!

$ pg_lsclusters 
Ver Cluster Port Status Owner    Data directory           Log file
10  main    5432 online postgres /data/postgresql/10/main /var/log/postgresql/postgresql-10-main.log
Run Code Online (Sandbox Code Playgroud)

我目前对此深感困惑和束手无策。将深深地欣赏向前移动的线索。如果我被迫在黑暗中钓鱼,我可能会再次卸载 postgres 11 和 12,看看是否有帮助,否则我最终将不得不跟踪/usr/share/postgresql-common/pg_wrapper以查看 pg_dump 和 pg_restore 的两条路径如何以及在哪里分叉到不兼容的版本路径.

更新:

我发现的另一条线索允许我解决问题,但只是加深了谜团如下:

$ sudo -u postgres pg_dump --host=live.lan --port=5432 --dbname=mydb --username=myuser --format=custom > test.backup
$ sudo -u postgres /usr/lib/postgresql/10/bin/pg_dump --host=live.lan --port=5432 --dbname=mydb --username=myuser --format=custom > test2.backup
$ sudo -u postgres pg_restore -l test.backup
pg_restore: [archiver] unsupported version (1.14) in file header
$ sudo -u postgres pg_restore -l test2.backup
... produces listing of contents ...
$ sudo -u postgres pg_dump --version
pg_dump (PostgreSQL) 10.11 (Ubuntu 10.11-1.pgdg18.04+1)
$ sudo -u postgres /usr/lib/postgresql/10/bin/pg_dump --version
pg_dump (PostgreSQL) 10.11 (Ubuntu 10.11-1.pgdg18.04+1)
Run Code Online (Sandbox Code Playgroud)

这是令人难以置信的令人困惑。唯一可能的解释:

  1. 尽管报告的版本号相同,但两个 pg_dump 是不同的。我会认为这是难以置信的。
  2. pg_dump 运行 pg_wrapper,它运行 /usr/lib/postgresql/10/bin/pg_dump 并带有一些破坏它的神秘参数!

第二个是合理的,需要我使用 pg_wrapper 进行诊断。

更新 2:

稍后对 pg_wrapper 进行一种检测。它最终导致 pg_dump 运行 pg_wrapper 运行/usr/lib/postgresql/12/bin/pg_dump但它运行/usr/lib/postgresql/10/bin/pg_restore......去图!开始认为这是一个 postgresql 版本的互操作性错误!

更新 3:

深入研究pg_wrapper,确定原因,是的,我认为这是一种 pg_wrapper 错误,尽管它可能有争议,但恕我直言。这是它的作用:

如果--host提供,则它使用安装的最新版本的 postgresql(在我的情况下为 12,这是用于 pg_dump,因此 pg_dump 12 创建转储)

如果--host未提供,则它会咨询用户配置(在我的情况下为 10,这是针对 pg_restore,因此运行 pg_restore 10 并且它无法读取由 pg_dump 12 创建的文件)。

那么为什么这是一个错误呢?因为我有一个使用配置,而且无论我是否在与远程主机交谈,我都希望它受到尊重。更重要的是,如果我指定一个主机,我当然不希望使用最新的本地版本而忽略本地配置。我希望要么尊重本地配置(就像没有指定远程主机的情况一样),要么尝试匹配 rmeote 主机版本。任意依赖最新安装的版本恕我直言,深表怀疑。

但事实证明,有一种可行的解决方法。基本上代替:

sudo -u postgres pg_restore -l test.backup
Run Code Online (Sandbox Code Playgroud)

这有效:

sudo -u postgres pg_restore --host=localhost -l test.backup
Run Code Online (Sandbox Code Playgroud)

通过讽刺地指定主机,我们强制它忽略本地配置并使用最新版本的 pg_restore,它似乎可以很好地恢复到 PG 10 集群。

asi*_*niy 11

ubuntu 伙计们:很可能你的pg_restore已经过时了。只需使用 postgres doc并安装最新版本的 postgres:

  1. 创建文件/etc/apt/sources.list.d/pgdg.list并为存储库添加一行:deb http://apt.postgresql.org/pub/repos/apt/ YOUR_UBUNTU_VERSION_HERE-pgdg main其中 ubuntu 版本是:

    • 20.04 - 焦点
    • 18.04 - 仿生
    • 16.04 - xenial
  2. 添加密钥: wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -

  3. sudo apt-get update && sudo apt-get upgrade

它对我有用!


Eld*_*mir 9

所以我在这里的经历和OP有些相似,但又不完全一样。

我安装了 9.4、9.5、11 和 12 版本,所有 pg_* 工具都指向 9.4 版本。我尝试在另一台主机上 pg_restore 版本 12 创建的转储,但没有成功,因为该主机使用不兼容的 9.4 工具(与 OP 发布的错误相同)。

所以,这是我的调试流程:

  • which pg_restore
    • /usr/bin/pg_restore
  • ls -l /usr/bin/pg_restore
    • /usr/bin/pg_restore -> ../share/postgresql-common/pg_wrapper
  • vim /usr/share/postgresql-common/pg_wrapper
    • 了解它如何确定版本。只需阅读前 20 行左右即可

显然,有一个--cluster选项有助于解决版本问题。所以我只是添加--cluster 12/main到我的pg_restore通话中,一切都再次按预期进行


Jan*_*Jan 5

这是另一个变化,但请首先注意这是一个 Windows 案例。如果您只需要 Linux,请不要继续阅读。这里给出的所有建议都没有帮助我,最终原因是 IMC 更简单并且与 pgAdmin 的使用有关。由于新版本的重复性问题,我的习惯是单独安装pgAdmin(不使用stackbuilder)。(至少)在这种情况下,pgAdmin 有自己的实用程序缓存,并且将使用它们,除非您以不同的方式告诉它。我的 pg 实例仍然是版本 11(.6),但最新的 pgAdmin 可能会有 V12 实用程序。这很可能会导致版本差异。在从我的主机到笔记本电脑成功进行多次传输后,我突然意识到了这一点。因此,在 pgAdmin 中执行(菜单)文件->首选项->路径并设置与您的 postgres 安装相对应的二进制路径,IMC C:\Program Files\PostgreSQL\11\bin。这就完成了工作。