Postgresql

pg_restore:archiver(db)一種rCH一世v和r(db)archiver (db)無法執行查詢:錯誤:架構“公共”已存在

  • June 17, 2021

我正在使用 pg_dump / pg_restore 備份和恢復 PostgreSQL 數據庫,但我從 pg_restore 收到一些錯誤消息(和非零退出狀態)。我嘗試了一個超級簡單的基本案例(如下所述),但仍然出現這些錯誤:

pg_restore: [archiver (db)] 處理目錄時出錯:
pg_restore: [archiver (db)] 來自 TOC 條目 5 的錯誤;2615 2200 SCHEMA 公共 postgres
pg_restore: [archiver (db)] 無法執行查詢:錯誤:模式“公共”已經存在
命令是:CREATE SCHEMA public;

重現步驟:

  1. 安裝一個全新的香草 Ubuntu 14.04 發行版(我在這個 Vagrant box 中使用 Vagrant )。
  2. 安裝 PostgreSQL 9.3,配置為允許來自任何 Linux 使用者的 PostgreSQL 使用者“postgres”的本地連接。
  3. 創建一個測試數據庫。我只是在做:
vagrant@vagrant-ubuntu-trusty-64:~$ psql --username=postgres postgres
psql (9.3.5)
鍵入“幫助”以獲得幫助。

postgres=# 創建數據庫 mydb;
創建數據庫
postgres=#\q
vagrant@vagrant-ubuntu-trusty-64:~$ psql --username=postgres mydb
psql (9.3.5)
鍵入“幫助”以獲得幫助。

mydb=# 創建表數據(entry bigint);
創建表
mydb=# 插入數據值(1);
插入 0 1
mydb=# 插入數據值(2);
插入 0 1
mydb=# 插入數據值(3);
插入 0 1
我的數據庫=# \q
  1. 像這樣創建數據庫的備份:
PGPASSWORD="postgres" pg_dump --dbname=mydb --username=postgres --format=custom > pg_backup.dump
  1. 從 mydb 的數據表中刪除一些行,以便我們能夠判斷我們是否成功恢復了數據。
  2. 使用以下命令恢復數據庫:
PGPASSWORD="postgres" pg_restore --clean --create --dbname=postgres --username=postgres pg_backup.dump

數據已恢復,但步驟 6 中的 pg_restore 命令以狀態退出1並顯示以下輸出:

pg_restore: [archiver (db)] 處理目錄時出錯:
pg_restore: [archiver (db)] 來自 TOC 條目 5 的錯誤;2615 2200 SCHEMA 公共 postgres
pg_restore: [archiver (db)] 無法執行查詢:錯誤:模式“公共”已經存在
命令是:CREATE SCHEMA public;



警告:還原時忽略錯誤:1

我不能忽略這一點,因為我正在以程式方式執行此命令,並且需要使用退出狀態來確定還原是否失敗。最初,我想知道這個問題是否是因為我將我的數據庫公開(預設模式)。我推斷,在恢復數據之前,由於 pg_restore 的選項會創建 public --create(可以想像,這也可以嘗試創建該模式,因為那是我的表所在的位置),但是當我用我的表嘗試上述步驟時在不同的架構中,結果相同,錯誤消息相同。

難道我做錯了什麼?為什麼我看到這個錯誤?

該錯誤是無害的,但要擺脫它,我認為您需要將此還原分為兩個命令,如下所示:

dropdb -U postgres mydb && \
pg_restore --create --dbname=postgres --username=postgres pg_backup.dump

pg_restore 中的--clean選項看起來並不多,但實際上引發了不平凡的問題。

對於最高 9.1 的版本

--createpg_restore 選項中的和的組合--clean曾經是舊 PG 版本(最高 9.1)中的錯誤。(引用 9.1 聯機幫助頁)之間確實存在一些矛盾:

–clean 在重新創建它們之前清理(刪除)數據庫對象

–create 在還原到數據庫之前創建數據庫。

因為在全新的數據庫中進行清理有什麼意義?

從 9.2 版開始

該組合現在已被接受,文件說明了這一點(引用 9.3 聯機幫助頁):

–clean 在重新創建它們之前清理(刪除)數據庫對象。(如果目標數據庫中不存在任何對象,這可能會生成一些無害的錯誤消息。)

–create 在還原到數據庫之前創建數據庫。如果還指定了 –clean,則在連接到它之前刪除並重新創建目標數據庫。

現在將兩者放在一起會在還原期間導致這種序列:

DROP DATABASE mydb;
...
CREATE DATABASE mydb WITH TEMPLATE = template0... [other options]
...
CREATE SCHEMA public;
...
CREATE TABLE...

DROP每個單獨的對像都沒有,只有DROP DATABASE開頭的 a。如果不使用--create這將是相反的。

無論如何,這個序列會引發public模式已經存在的錯誤,因為創建mydbfromtemplate0已經導入了它(這很正常,這是模板數據庫的重點)。

我不知道為什麼這種情況不是由pg_restore. template0當管理員決定自定義和/或更改 的用途時,這可能會導致不良的副作用public,即使我們不應該這樣做。

引用自:https://dba.stackexchange.com/questions/90258