So lösen Sie Berechtigungsprobleme beim Wiederherstellen der PostgreSQL-Datenbank

104

Ich habe mit dem Befehl eine saubere Sicherung ohne Eigentümer für die Postgres-Datenbank gespeichert

pg_dump sample_database -O -c -U

Später, wenn ich die Datenbank mit wiederherstelle

psql -d sample_database -U app_name

Es sind jedoch mehrere Fehler aufgetreten, die mich daran hindern, die Daten wiederherzustellen:

ERROR:  must be owner of extension plpgsql
ERROR:  must be owner of schema public
ERROR:  schema "public" already exists
ERROR:  must be owner of schema public
CREATE EXTENSION
ERROR:  must be owner of extension plpgsql

Ich habe mich mit dem Klartext befasst, den SQL pg_dumpgeneriert, und festgestellt, dass er SQL enthält

CREATE SCHEMA public;
COMMENT ON SCHEMA public IS 'standard public schema';
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';

Ich denke, die Ursachen sind, dass der Benutzer app_namenicht die Berechtigungen hat, das publicSchema und zu ändern plpgsql.

Wie könnte ich dieses Problem lösen?

steveyang
quelle
5
Wenn Sie nicht brauchen plpgsql, dann DROP EXTENSION plpgsqlvor Ihnen pg_dump. Dies ist sicherer, als Ihre App zu einem Superuser zu machen, und es ist bequemer, als Fehler zu ignorieren (welche Bomben, wenn Sie --single-transactionoder verwenden -v ON_ERROR_STOP=1). Dies ist ein bekanntes Problem, das von den Postgres-Entwicklern ausführlich erörtert wurde postgresql.org/message-id/… aber nicht behoben ab 9.3.
Mark E. Haase

Antworten:

63

Um das Problem zu lösen, müssen Sie die entsprechenden Eigentumsrechte zuweisen. Versuchen Sie Folgendes, um alle Probleme im Zusammenhang mit Berechtigungen für bestimmte Benutzer zu beheben. Wie in den Kommentaren angegeben, sollte dies jedoch nicht in der Produktion verwendet werden:

root@server:/var/log/postgresql# sudo -u postgres psql
psql (8.4.4)
Type "help" for help.

postgres=# \du
               List of roles
    Role name    | Attributes  | Member of
-----------------+-------------+-----------
 <user-name>    | Superuser   | {}
                 : Create DB
 postgres       | Superuser   | {}
                 : Create role
                 : Create DB

postgres=# alter role <user-name> superuser;
ALTER ROLE
postgres=#

Stellen Sie also unter einem Superuser-Konto sudo -u postgres psqleine Verbindung zur Datenbank her und führen Sie eine ALTER ROLE <user-name> Superuser;Anweisung aus.

Beachten Sie, dass dies nicht die beste Lösung für Hosting-Server mit mehreren Standorten ist. Sehen Sie sich stattdessen die Zuweisung einzelner Rollen an: https://www.postgresql.org/docs/current/static/sql-set-role.html und https : //www.postgresql.org/docs/current/static/sql-alterrole.html .

Daniel Sokolowski
quelle
27
Gibt es eine Möglichkeit, dies zu tun, ohne ein Superuser zu sein?
Travis Webb
17
"muss die richtigen Eigentumsrechte zuweisen" und "Rolle ändern <Benutzername> Superuser" sind nicht kongruent. Proper Eigentum würde bedeuten , dass app_userist nicht ein Super - User.
Mark E. Haase
@mehaase Bitte aktualisieren Sie den Wortlaut der Antwort im Gegensatz zu Abstimmungen.
Daniel Sokolowski
5
IMHO ist dies keine Lösung, sondern eine Problemumgehung, die in der Produktion vermieden werden sollte.
Dmytriy Voloshyn
6
Es ist ein schlechter Vorschlag, einen normalen Benutzer zu machensuperuser
Evren Yurtesen
55

AWS RDS-Benutzer, wenn Sie dies erhalten, liegt es daran, dass Sie kein Superuser sind und laut aws-Dokumentation keiner sein können. Ich habe festgestellt, dass ich diese Fehler ignorieren muss.

Jim Zucker
quelle
5
Dieser Fehler verhindert, dass die Wiederherstellung für mich abgeschlossen wird (AWS RDS pg_restore). Irgendwelche Tipps zum Ignorieren dieser Fehler?
Avjaarsveld
PS Ich habe -e oder --exit-on-error nicht für pg_restore
avjaarsveld
6
Ich habe festgestellt , dass auf RDS, das Problem ist COMMENT ON EXTENSION, nicht CREATE EXTENSION. Entfernen Sie die Kommentare und es sollte Ihnen gut gehen.
pkoch
@pkoch gleich mit Google Cloud Storage. Kommentar zur Erweiterung war das Problem und nicht erforderlich
Jaybeecave
25

Für Benutzer von Google Cloud Platform wird der Importvorgang durch jeden Fehler gestoppt. Persönlich sind je nach dem von mir ausgegebenen Befehl pg_dump zwei verschiedene Fehler aufgetreten:

1- The input is a PostgreSQL custom-format dump. Use the pg_restore command-line client to restore this dump to a database.

Tritt auf, wenn Sie versucht haben, Ihre Datenbank in einem nicht einfachen Textformat zu sichern. Dh wenn dem Befehl der Parameter -Fp oder --format = plain fehlt. Wenn Sie es jedoch zu Ihrem Befehl hinzufügen, kann der folgende Fehler auftreten:

2- SET SET SET SET SET SET CREATE EXTENSION ERROR: must be owner of extension plpgsql

Dies ist ein Berechtigungsproblem, das ich mit dem Befehl in den GCP-Dokumenten , den Tipps aus diesem aktuellen Thread oder den Ratschlägen des Google Postgres-Teams hier nicht beheben konnte . Welche empfahl, den folgenden Befehl auszugeben:

pg_dump -Fp --no-acl --no-owner -U myusername myDBName > mydump.sql

Das einzige, was in meinem Fall den Trick gemacht hat, war das manuelle Bearbeiten der Dump-Datei und das Auskommentieren aller Befehle in Bezug auf plpgsql.

Ich hoffe, das hilft GCP-abhängigen Seelen.

Update:

Es ist einfacher, die Datei zu sichern, indem Erweiterungen auskommentiert werden, zumal einige Speicherauszüge sehr groß sein können: pg_dump ... | grep -v -E '(CREATE\ EXTENSION|COMMENT\ ON)' > mydump.sql

Was auf plpgsql eingegrenzt werden kann: pg_dump ... | grep -v -E '(CREATE\ EXTENSION\ IF\ NOT\ EXISTS\ plpgsql|COMMENT\ ON\ EXTENSION\ plpgsql)' > mydump.sql

Stanislasdrg Monica wieder einsetzen
quelle
1
GCP hat jetzt den genauen pg_dumpBefehl, den sie in ihren Dokumenten verwenden können :pg_dump -U [USERNAME] --format=plain --no-owner --no-acl [DATABASE_NAME] \ | sed -E 's/(DROP|CREATE|COMMENT ON) EXTENSION/-- \1 EXTENSION/g' > [SQL_FILE].sql
Rush
14

In diesem Fall können Sie die Fehlermeldungen wahrscheinlich ignorieren. Wenn Sie dem öffentlichen Schema keinen Kommentar hinzufügen und plpgsql installieren (das bereits installiert sein sollte), treten keine wirklichen Probleme auf.

Wenn Sie jedoch eine vollständige Neuinstallation durchführen möchten, benötigen Sie einen Benutzer mit den entsprechenden Berechtigungen. Das sollte natürlich nicht der Benutzer sein, den Ihre Anwendung routinemäßig ausführt.

Richard Huxton
quelle
12

Kürzere Antwort: Ignorieren Sie es.

Dieses Modul ist der Teil von Postgres, der die SQL-Sprache verarbeitet. Der Fehler tritt häufig beim Kopieren einer entfernten Datenbank auf, z. B. bei einem 'heroku pg: pull'. Es überschreibt Ihren SQL-Prozessor nicht und warnt Sie davor.

Charles Merriam
quelle
9

Versuchen Sie, das -LFlag mit pg_restore zu verwenden, indem Sie die Datei angeben, aus der entnommen wurdepg_dump -Fc

-L Listendatei --use-list = Listendatei

Stellen Sie nur die Archivelemente wieder her, die in der Listendatei aufgeführt sind, und stellen Sie sie in der Reihenfolge wieder her, in der sie in der Datei angezeigt werden. Beachten Sie, dass Filterschalter wie -n oder -t, die mit -L verwendet werden, die wiederhergestellten Elemente weiter einschränken.

Die Listendatei wird normalerweise durch Bearbeiten der Ausgabe einer vorherigen -l-Operation erstellt. Zeilen können verschoben oder entfernt sowie durch Platzieren eines Semikolons (;) am Zeilenanfang auskommentiert werden. Beispiele finden Sie unten.

https://www.postgresql.org/docs/9.5/app-pgrestore.html

pg_dump -Fc -f pg.dump db_name
pg_restore -l pg.dump | grep -v 'COMMENT - EXTENSION' > pg_restore.list
pg_restore -L pg_restore.list pg.dump

Hier können Sie sehen, dass die Umkehrung wahr ist, indem Sie nur den Kommentar ausgeben:

pg_dump -Fc -f pg.dump db_name
pg_restore -l pg.dump | grep 'COMMENT - EXTENSION' > pg_restore_inverse.list
pg_restore -L pg_restore_inverse.list pg.dump
--
-- PostgreSQL database dump
--

-- Dumped from database version 9.4.15
-- Dumped by pg_dump version 9.5.14

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;

--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
--

COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';


--
-- PostgreSQL database dump complete
--
Ligemer
quelle
Ich denke, das oben
Andreas
3

Für Menschen mit AWS , das COMMENT ON EXTENSIONist nur möglich , als Super - User , und wie wir durch die docs wissen, werden die RDS - Instanzen von Amazon verwaltet. Um zu verhindern, dass Sie beispielsweise die Replikation beschädigen, verfügen Ihre Benutzer - selbst der Root-Benutzer, den Sie beim Erstellen der Instanz eingerichtet haben - nicht über die vollständigen Superuser-Berechtigungen:

http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html

Wenn Sie eine DB-Instanz erstellen, wird das von Ihnen erstellte Hauptbenutzersystemkonto der Rolle rds_superuser zugewiesen. Die rds_superuser-Rolle ist eine vordefinierte Amazon RDS-Rolle, die der PostgreSQL-Superuser-Rolle ähnelt (in lokalen Instanzen üblicherweise als postgres bezeichnet), jedoch mit einigen Einschränkungen. Wie bei der PostgreSQL-Superuser-Rolle verfügt die rds_superuser-Rolle über die meisten Berechtigungen für Ihre DB-Instanz, und Sie sollten diese Rolle nicht Benutzern zuweisen, es sei denn, sie benötigen den meisten Zugriff auf die DB-Instanz.

Um diesen Fehler zu beheben --, kommentieren Sie einfach die enthaltenen SQL-Zeilen ausCOMMENT ON EXTENSION

Petar Nikov
quelle
1
Oder lassen Sie beim Dumping Kommentare weg : pg_dump --no-comments.
Dmitrii I.
2

Verwenden Sie den Benutzer postgres (admin), um das Schema zu sichern, neu zu erstellen und Berechtigungen zur Verwendung zu erteilen, bevor Sie die Wiederherstellung durchführen. In einem Befehl:

sudo -u postgres psql -c "DROP SCHEMA public CASCADE;
create SCHEMA public;
grant usage on schema public to public;
grant create on schema public to public;" myDBName
Pascal_dher
quelle
1

Für mich habe ich eine Datenbank mit pgAdmin eingerichtet und es scheint nicht genug zu sein, den Eigentümer während der Datenbankerstellung festzulegen . Ich musste zum 'öffentlichen' Schema hinunter navigieren und dort auch den Besitzer festlegen (war ursprünglich 'postgres').

Peter L.
quelle
0

Für Personen, die das Problem auf die COMMENT ONAnweisungen eingegrenzt haben (siehe verschiedene Antworten unten) und Superuser-Zugriff auf die Quelldatenbank haben, aus der die Dump-Datei erstellt wird, besteht die einfachste Lösung möglicherweise darin, zu verhindern, dass die Kommentare in den Dump aufgenommen werden Datei in erster Linie, indem Sie sie aus der Quelldatenbank entfernen, die gesichert wird ...

COMMENT ON EXTENSION postgis IS NULL;
COMMENT ON EXTENSION plpgsql IS NULL;
COMMENT ON SCHEMA public IS NULL;

Zukünftige Dumps enthalten dann keine COMMENT ONAnweisungen.

Mark Schneider
quelle
1
Diese Lösung wird lokal in Rails entwickelt (wodurch bei rails db:resetjeder Ausführung einer Schemamigration automatisch eine neue Speicherauszugsdatei erstellt wird). Mit dieser Lösung kann ich einfach eine Postgresql-Instanz von AWS RDS ausführen, ohne jedes Mal, wenn ich ein Schema ausführe, COMMENT ON-Zeilen aus der Speicherauszugsdatei entfernen zu müssen Migration.
Mark Schneider