it-swarm.com.de

pg_restore: [archiver (db)] konnte Abfrage nicht ausführen: FEHLER: Schema "public" existiert bereits

Ich verwende pg_dump/pg_restore zum Sichern und Wiederherstellen einer PostgreSQL-Datenbank, erhalte jedoch einige Fehlermeldungen (und einen Exit-Status ungleich Null) von pg_restore. Ich habe einen supereinfachen Basisfall ausprobiert (siehe unten), habe aber trotzdem folgende Fehler erhalten:

 pg_restore: [archiver (db)] Fehler beim Verarbeiten des Inhaltsverzeichnisses: 
 Pg_restore: [archiver (db)] Fehler von Inhaltsverzeichniseintrag 5; 2615 2200 SCHEMA public postgres 
 Pg_restore: [archiver (db)] konnte Abfrage nicht ausführen: FEHLER: Schema "public" existiert bereits 
 Befehl war: CREATE SCHEMA public; 

Schritte zum Reproduzieren:

  1. Installieren Sie eine frische Vanilla Ubuntu 14.04-Distribution (ich verwende Vagrant mit diese Vagrant-Box ).
  2. Installieren Sie PostgreSQL 9.3 und konfigurieren Sie es so, dass lokale Verbindungen als PostgreSQL-Benutzer "postgres" von jedem Linux-Benutzer zugelassen werden.
  3. Erstellen Sie eine Testdatenbank. Ich mache nur:

     vagrant @ vagrant-ubuntu-trusty-64: ~ $ psql --username = postgres postgres 
     psql (9.3.5) 
     Geben Sie "help" ein, um Hilfe zu erhalten. 
     
     postgres = # Datenbank mydb erstellen; 
     DATENBANK ERSTELLEN 
     Postgres = #\q 
     vagrant @ vagrant-ubuntu-trusty-64: ~ $ psql - -username = postgres mydb 
     psql (9.3.5) 
     Geben Sie "help" ein, um Hilfe zu erhalten. 
     
     mydb = # Tabellendaten erstellen (Eintrag bigint); 
     CREATE TABLE 
     Mydb = # in Datenwerte einfügen (1); 
     INSERT 0 1 
     Mydb = # in Datenwerte einfügen (2); 
     INSERT 0 1 
     Mydb = # in Datenwerte einfügen (3); 
     INSERT 0 1 
     Mydb = #\q 
    
  4. Erstellen Sie eine Sicherungskopie der Datenbank wie folgt:

    PGPASSWORD = "postgres" pg_dump --dbname = mydb --username = postgres --format = custom> pg_backup.dump
  5. Löschen Sie einige Zeilen aus der Datentabelle in mydb, damit wir feststellen können, ob wir die Daten erfolgreich wiederhergestellt haben.

  6. Stellen Sie die Datenbank wieder her mit:

    PGPASSWORD = "postgres" pg_restore --clean --create --dbname = postgres --username = postgres pg_backup.dump

Die Daten werden wiederhergestellt, aber der Befehl pg_restore in Schritt 6 wird mit dem Status 1 Beendet und zeigt die folgende Ausgabe an:

 pg_restore: [archiver (db)] Fehler beim Verarbeiten des Inhaltsverzeichnisses: 
 Pg_restore: [archiver (db)] Fehler von Inhaltsverzeichniseintrag 5; 2615 2200 SCHEMA public postgres 
 Pg_restore: [archiver (db)] konnte Abfrage nicht ausführen: FEHLER: Schema "public" existiert bereits 
 Befehl war: CREATE SCHEMA public; 
 
 
 
 WARNUNG: Fehler bei der Wiederherstellung ignoriert: 1 

Ich kann dies nicht einfach ignorieren, da ich diesen Befehl programmgesteuert ausführe und den Exit-Status verwenden muss, um festzustellen, ob die Wiederherstellung fehlgeschlagen ist oder nicht. Anfangs habe ich mich gefragt, ob dieses Problem darauf zurückzuführen ist, dass ich meine Datenbank öffentlich gemacht habe (das Standardschema). Ich habe argumentiert, dass public als Ergebnis der Option --create Von pg_restore erstellt wird, bevor die Daten wiederhergestellt wurden (was möglicherweise auch versuchen könnte, dieses Schema zu erstellen, da sich dort meine Tabelle befindet), aber als ich es versuchte Bei den obigen Schritten mit meiner Tabelle in einem anderen Schema waren die Ergebnisse gleich und die Fehlermeldungen identisch.

Mache ich etwas falsch? Warum sehe ich diesen Fehler?

20
KSletmoe

Der Fehler ist harmlos, aber um ihn zu beseitigen, müssen Sie diese Wiederherstellung in zwei Befehle aufteilen, wie in:

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

Die Option --clean In pg_restore sieht nicht nach viel aus, wirft jedoch nicht triviale Probleme auf.

Für Versionen bis 9.1

Die Kombination von --create Und --clean In den Optionen pg_restore war in älteren PG-Versionen (bis 9.1) ein Fehler. Es gibt tatsächlich einen Widerspruch zwischen (unter Berufung auf die 9.1-Manpage):

--clean Bereinigt (löscht) Datenbankobjekte, bevor sie neu erstellt werden

und

--create Erstellen Sie die Datenbank, bevor Sie sie wiederherstellen.

Denn wozu dient die Reinigung in einer brandneuen Datenbank?

Ab Version 9.2

Die Kombination wird jetzt akzeptiert und das Dokument sagt dies (unter Angabe der 9.3-Manpage):

--clean Bereinigt (löscht) Datenbankobjekte, bevor sie neu erstellt werden. (Dies kann zu harmlosen Fehlermeldungen führen, wenn keine Objekte in der Zieldatenbank vorhanden sind.)

--create Erstellen Sie die Datenbank, bevor Sie sie wiederherstellen. Wenn auch --clean angegeben ist, löschen Sie die Zieldatenbank und erstellen Sie sie neu, bevor Sie eine Verbindung herstellen.

Wenn Sie nun beide zusammen haben, führt dies zu dieser Art von Sequenz während Ihrer Wiederherstellung:

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

Es gibt kein DROP für jedes einzelne Objekt, nur ein DROP DATABASE Am Anfang. Wenn Sie nicht --create Verwenden, ist dies das Gegenteil.

Auf jeden Fall löst diese Sequenz den Fehler des bereits vorhandenen Schemas public aus, da das Erstellen von mydb aus template0 Es bereits importiert hat (was normal ist, es ist der Punkt einer Vorlagendatenbank).

Ich bin mir nicht sicher, warum dieser Fall von pg_restore Nicht automatisch behandelt wird. Möglicherweise würde dies unerwünschte Nebenwirkungen verursachen, wenn ein Administrator beschließt, template0 Anzupassen und/oder den Zweck von public zu ändern, selbst wenn wir das nicht tun sollen.

17
Daniel Vérité

In meinem Fall war der Grund, dass ich pg_restore aus postgresql-contrib Version 11.2, um einen von pg_dump 9.6 zu einem PostgreSQL-Cluster 9.6.

Nachdem ich mein pg_restore zurück zu 9.6, dieses schema "public" already exists Fehler war weg und der Wiederherstellungsprozess funktionierte wie zuvor.

7
Lu Liu

Die Wiederherstellung enthält das öffentliche Schema und erstellt auch eine Datenbank. Entfernen Sie daher das Schema nach dem Erstellen der Datenbank, damit die Wiederherstellung es ohne Fehler erstellen kann.

Hinweis: Im Folgenden wird davon ausgegangen, dass -h -U -p Standard ist und PGPASSWORD oder .pgpass festgelegt ist

    psql << XENDX
    drop database if exists DB_NAME;
    create database DB_NAME;
    /c DB_NAME;
    drop schema if exists public;
    create schema public;
    XENX

    pg_restore -d DB_NAME FILE_CREATED_WITH_pg_dump
1
DaJudge

Ich habe es gelöst mit:

in dem db.sql Datei

drop database if exists DB_name;
create database DB_name;
drop schema if exists public;
create schema public;
\q

dann

PGPASSWOD=DB_pass psql -U DB_user -h 127.0.0.1 < db.sql

Und dann

PGPASSWOD=DB_pass pg_restore -h 127.0.0.1 \ 
    -U DB_user -d DB_name --create --no-acl --no-owner DB_dump_FILE

Meine pg_restore-Version ist 11.6

0
user9869932