pg_restore:archiver(db)一種rCH一世v和r(db)archiver (db)無法執行查詢:錯誤:架構“公共”已存在
我正在使用 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;
重現步驟:
- 安裝一個全新的香草 Ubuntu 14.04 發行版(我在這個 Vagrant box 中使用 Vagrant )。
- 安裝 PostgreSQL 9.3,配置為允許來自任何 Linux 使用者的 PostgreSQL 使用者“postgres”的本地連接。
- 創建一個測試數據庫。我只是在做:
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
- 像這樣創建數據庫的備份:
PGPASSWORD="postgres" pg_dump --dbname=mydb --username=postgres --format=custom > pg_backup.dump
- 從 mydb 的數據表中刪除一些行,以便我們能夠判斷我們是否成功恢復了數據。
- 使用以下命令恢復數據庫:
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 的版本
--create
pg_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
模式已經存在的錯誤,因為創建mydb
fromtemplate0
已經導入了它(這很正常,這是模板數據庫的重點)。我不知道為什麼這種情況不是由
pg_restore
.template0
當管理員決定自定義和/或更改 的用途時,這可能會導致不良的副作用public
,即使我們不應該這樣做。