私はライブサーバーと開発ボックスを持っています。それぞれpostgresqlを実行しているliveおよびdevと呼びます。私はpgadmin4で両方を表示して両方を問題なく管理でき、開発ボックスでデバッグモードでWebサイトで実行すると、どちらもライブWebサイトとして動作し、もう一方は完全に機能します。かなり普通の設定。
何年もの間、私が書いたのと同じbashスクリプトを実行していて、ライブデータベースをダンプし、それを開発ボックスで復元しているので、最新のライブスナップショットを操作できます。
今日、これは私にタイトルの付いたメッセージで失敗します:
pg_restore: [archiver] unsupported version (1.14) in file header
私はこれを診断しようとし、オンラインで広範囲に検索しましたが、困惑して失敗しました。そこで、ここで専門知識を求めています。
次の情報を共有します。
$ 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
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
私はそれらが同じバージョンであるだけでなく、同じラッパースクリプトによって実行されていることを確認できます(これはたまたま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)
ライブボックスにわずかに古いバージョンのpg_dumpがあることがわかります(私の開発ボックスのpg_dumpがライブボックスへのRPCを使用して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
空のログファイルが示すように、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)
穏やかな魚ですが、明らかに原因や関連性はありません。
これがラブボックスのクラスターで、ポート5432を介してlive.lanで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
私は現在これに深く当惑し、身もだえしています。前進する手がかりを深く感謝します。暗闇の中で釣り回らざるを得ない場合は、おそらくpostgres 11と12を再度アンインストールして、それが役立つかどうかを確認します。それ以外の場合は、/usr/share/postgresql-common/pg_wrapper
をトレースして、pg_dumpとpg_restoreの2つのパスを確認する必要があります。互換性のないバージョンパスを分岐します。
更新:
私が発見したさらなる手掛かりは、私に回避策を許可しますが、謎を単に深めることです:
$ 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 test.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)
それは信じられないほど困惑しています。考えられる唯一の説明:
2つ目はもっともらしく、診断するためにpg_wrapperをインストルメント化する必要があります。
更新2:
そして、後でpg_wrapperの1つのインストルメンテーション。 pg_dumpは/usr/lib/postgresql/12/bin/pg_dump
を実行するpg_wrapperを実行しますが、/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で作成されたファイルを読み取ることができません)。
では、なぜこれがバグなのでしょうか?私はuse configを持っているので、リモートホストと話しているかどうかに関係なくそれを尊重したいのです。もっと重要なことは、ホストを指定した場合、ローカル構成を無視して最新のローカルバージョンを使用することを期待しないことです。 (リモートホストが指定されていない場合のように)ローカル構成を尊重するか、rmeoteホストのバージョンを一致させることを期待しています。インストールされている最新バージョンに恣意的に依存することは、私見に深く疑わしいものです。
しかし、うまくいく回避策があることがわかりました。基本的に次の代わりに:
Sudo -u postgres pg_restore -l test.backup
これは機能します:
Sudo -u postgres pg_restore --Host=localhost -l test.backup
皮肉なことにホストを指定することで、ローカル構成を無視し、PG 10クラスターに正常に復元できるように見える最新バージョンのpg_restoreを使用するように強制します。
ここでは別の工夫がありますが、これはWindowsのケースであることに注意してください。それがLinuxだけの場合は、これ以上読み進めないでください。ここで与えられたすべてのアドバイスは私を助けませんでした、最終的に原因IMCはより単純で、pgAdminの使用と関係がありました。新しいバージョンではnagが繰り返されるため、私の習慣はpgAdminを個別にインストールすることです(stackbuilderは使用しません)。 (少なくとも)その場合、pgAdminにはユーティリティプログラムの独自のキャッシュがあり、別様に指示しない限りこれらを使用します。私のpgインスタンスはまだバージョン11(.6)ですが、最新のpgAdminにはおそらくV12ユーティリティが含まれています。これは、バージョンの不一致を引き起こす可能性があります。これは、メインマシンからラップトップへの転送に成功した後、忍び寄ってきました。したがって、pgAdminで(メニュー)ファイル->設定->パスを実行し、postgresインストールに対応するバイナリパスを設定します(IMC C:\ Program Files\PostgreSQL\11\bin)。それは仕事をしました。