pg_restore:错误:无法执行查询:错误:无法识别选项“区域设置”

Emr*_*inç 5 postgresql pg-dump pg-restore

当我尝试将转储文件恢复到另一个(本地)PostgreSQL 服务器(在 Debian GNU/Linux 10.10 上运行)时,出现以下错误:

\n
pg_restore: error: could not execute query: ERROR:  option "locale" not recognized\n
Run Code Online (Sandbox Code Playgroud)\n

因为它确实有以下行:

\n
CREATE DATABASE "REMOTE_DB" WITH TEMPLATE = template0 ENCODING = \'UTF8\' LOCALE = \'en_GB.UTF-8\';\n
Run Code Online (Sandbox Code Playgroud)\n

是的,我知道PostgreSQL 12 CREATE DATABASE命令没有选项LOCALE

\n

我不明白的是:

\n
    \n
  • 我在本地服务器上使用的 PostgreSQL 本身版本报告为 12.7
  • \n
  • pg_dump我在本地服务器上使用的版本报告为 12.7
  • \n
  • pg_restore我在本地服务器上使用的版本报告为 12.7
  • \n
  • 我使用其转储创建的远程 PostgreSQL 数据库pg_dump是版本 12.7,而不是 13
  • \n
\n

让我一一验证一下:

\n

我的本地服务器:

\n
$ sudo -u postgres psql -c \'select version();\'\n                                                     version\n------------------------------------------------------------------------------------------------------------------\n PostgreSQL 12.7 (Debian 12.7-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit\n
Run Code Online (Sandbox Code Playgroud)\n

我的本地pg_dump版本:

\n
$ pg_dump --version\npg_dump (PostgreSQL) 12.7 (Debian 12.7-1.pgdg100+1)\n
Run Code Online (Sandbox Code Playgroud)\n

我的本地pg_restore版本:

\n
$ pg_restore --version\npg_restore (PostgreSQL) 12.7 (Debian 12.7-1.pgdg100+1)\n
Run Code Online (Sandbox Code Playgroud)\n

让我们检查一下REMOTE数据库的 PostgreSQL 版本:

\n
$ psql --host=REMOTE_HOST_IP_ADDRESS --dbname=REMOTE_DB --username=DB_USER -c \'select version();\'\nPassword for user DB_USER:\n                                                             version\n----------------------------------------------------------------------------------------------------------------------------------\n PostgreSQL 12.7 (Debian 12.7-1.pgdg90+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18+deb9u1) 6.3.0 20170516, 64-bit\n(1 row)\n
Run Code Online (Sandbox Code Playgroud)\n

这就是我创建转储文件的方式:

\n
$ pg_dump --verbose \\\n  --create \\\n  --clean \\\n  --if-exists \\\n  --format=custom \\\n  --compress=5 \\\n  --host=REMOTE_HOST_IP_ADDRESS --dbname=REMOTE_DB --username=DB_USER \\\n  --schema=public --table=TABLE_NAME\\\n  > db.dump\n
Run Code Online (Sandbox Code Playgroud)\n

这就是我尝试在运行 PostgreSQL 12 的本地服务器上恢复它的方法:

\n
$ sudo -u postgres \\\npg_restore --verbose \\\n  --create \\\n  --clean \\\n  --jobs=8 \\\n  --format=custom \\\n  --dbname=postgres \\\n  db.dump\n
Run Code Online (Sandbox Code Playgroud)\n

PostgreSQL 13已安装,但未在此本地服务器上运行:

\n
$ systemctl status postgresql@13-main.service\n\xe2\x97\x8f postgresql@13-main.service - PostgreSQL Cluster 13-main\n   Loaded: loaded (/lib/systemd/system/postgresql@.service; enabled-runtime; vendor preset: enabled)\n   Active: failed (Result: protocol) since Thu 2021-06-24 07:59:24 UTC; 1 day 5h ago\n  Process: 562 ExecStart=/usr/bin/pg_ctlcluster --skip-systemctl-redirect 13-main start (code=exited, status=1/FAILURE)\n
Run Code Online (Sandbox Code Playgroud)\n

PostgreSQL 12正在运行:

\n
$ systemctl status postgresql@12-main.service\n\xe2\x97\x8f postgresql@12-main.service - PostgreSQL Cluster 12-main\n   Loaded: loaded (/lib/systemd/system/postgresql@.service; enabled-runtime; vendor preset: enabled)\n   Active: active (running) since Thu 2021-06-24 07:59:26 UTC; 1 day 5h ago\n  Process: 556 ExecStart=/usr/bin/pg_ctlcluster --skip-systemctl-redirect 12-main start (code=exited, status=0/SUCCESS)\n Main PID: 595 (postgres)\n    Tasks: 9 (limit: 36863)\n   Memory: 235.7M\n   CGroup: /system.slice/system-postgresql.slice/postgresql@12-main.service\n           \xe2\x94\x9c\xe2\x94\x80595 /usr/lib/postgresql/12/bin/postgres -D /var/lib/postgresql/12/main -c config_file=/etc/postgresql/12/main/postgresql.conf\n           \xe2\x94\x9c\xe2\x94\x80678 postgres: 12/main: checkpointer\n           \xe2\x94\x9c\xe2\x94\x80679 postgres: 12/main: background writer\n           \xe2\x94\x9c\xe2\x94\x80680 postgres: 12/main: walwriter\n           \xe2\x94\x9c\xe2\x94\x80681 postgres: 12/main: autovacuum launcher\n           \xe2\x94\x9c\xe2\x94\x80682 postgres: 12/main: stats collector\n           \xe2\x94\x9c\xe2\x94\x80683 postgres: 12/main: TimescaleDB Background Worker Launcher\n           \xe2\x94\x9c\xe2\x94\x80684 postgres: 12/main: logical replication launcher\n           \xe2\x94\x94\xe2\x94\x80685 postgres: 12/main: TimescaleDB Background Worker Scheduler\n
Run Code Online (Sandbox Code Playgroud)\n

长话短说,我的问题是:

\n
    \n
  • 为什么我LOCALE在 生成的转储文件中得到这个不受支持的选项pg_dump,而 REMOTE PostgreSQL 版本以及本地pg_dump版本报告为12.7不是 13
  • \n
\n

我还应该检查什么?

\n

Dan*_*ité 5

我在本地服务器上使用的 PostgreSQL 本身版本报告为 12.7

但仍然是 pg_dump 13.x 使用 的LOCALE参数创建了转储CREATE DATABASE

/usr/bin/pg_dump由 Debian/Ubuntu 软件包安装的是一个包装器,它尝试确定它应该与哪个版本的 PostgreSQL 通信,然后执行/usr/lib/postgresql/$VERSION/bin/. 这是为了支持同一主机上的 PostgreSQL 的多个安装和版本,即使您的情况下只运行一个。

$ ls -l /usr/bin/pg_dump
lrwxrwxrwx 1 root root 2020 年 8 月 14 日 37 日 /usr/bin/pg_dump -> ../share/postgresql-common/pg_wrapper

请参阅pg_wrapper 的联机帮助页。

合理的解释

执行时pg_dump --version,它会以某种方式获取活动集群的版本 (12) 并启动相应的 pg_dump。

执行时pg_dump --host ...,它不知道远程主机正在运行哪个版本的 PostgreSQL,并且以某种方式默认选择版本 13。

解决方案

作为解决方法,您可以直接调用/usr/lib/postgresql/12/bin/pg_dump而不是pg_dump