Comment résoudre les problèmes de privilèges lors de la restauration de la base de données PostgreSQL

105

J'ai vidé une sauvegarde propre, pas de propriétaire pour la base de données Postgres avec la commande

pg_dump sample_database -O -c -U

Plus tard, lorsque je restaure la base de données avec

psql -d sample_database -U app_name

Cependant, j'ai rencontré plusieurs erreurs qui m'empêchent de restaurer les données:

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

J'ai fouillé dans le texte brut pg_dumpgénéré par SQL et j'ai trouvé qu'il contient du SQL

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';

Je pense que les causes sont que l'utilisateur app_namen'a pas les privilèges pour modifier le publicschéma et plpgsql.

Comment pourrais-je résoudre ce problème?

steveyang
la source
5
Si vous n'en avez pas besoin plpgsql, alors DROP EXTENSION plpgsqlavant vous pg_dump. C'est plus sûr que de faire de votre application un super utilisateur, et c'est plus pratique que d'ignorer les erreurs (quelles bombes si vous utilisez --single-transactionou -v ON_ERROR_STOP=1). C'est un problème connu, [discuté en détail par les développeurs de Postgres | postgresql.org/message-id/... mais non corrigé à partir de la version 9.3.
Mark E. Haase

Réponses:

63

Pour résoudre le problème, vous devez attribuer les autorisations de propriété appropriées. Essayez ce qui suit qui devrait résoudre tous les problèmes liés aux autorisations pour des utilisateurs spécifiques, mais comme indiqué dans les commentaires, cela ne doit pas être utilisé en production:

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=#

Alors connectez-vous à la base de données sous un compte superutilisateur sudo -u postgres psqlet exécutez une ALTER ROLE <user-name> Superuser;déclaration.

Gardez à l'esprit que ce n'est pas la meilleure solution sur un serveur d'hébergement multi-site, alors jetez plutôt un œil à l'attribution de rôles individuels: https://www.postgresql.org/docs/current/static/sql-set-role.html et https : //www.postgresql.org/docs/current/static/sql-alterrole.html .

Daniel Sokolowski
la source
28
y a-t-il un moyen de faire cela sans être un superutilisateur?
Travis Webb
17
«doit attribuer les droits de propriété appropriés» et «modifier le rôle <nom d'utilisateur> superutilisateur» ne sont pas cohérents. Une bonne propriété signifierait que ce app_usern'est pas un super utilisateur.
Mark E. Haase
@mehaase veuillez mettre à jour le libellé de la réponse par opposition au vote négatif.
Daniel Sokolowski
5
À mon humble avis, ce n'est pas une solution mais une solution de contournement qui devrait être évitée en production.
Dmytriy Voloshyn
6
C'est une mauvaise suggestion de faire un utilisateur normalsuperuser
Evren Yurtesen
55

Utilisateurs AWS RDS si vous obtenez cela, c'est parce que vous n'êtes pas un super-utilisateur et, selon la documentation aws, vous ne pouvez pas en être un. J'ai constaté que je devais ignorer ces erreurs.

Jim Zucker
la source
5
Cette erreur empêche la restauration de se terminer pour moi (AWS RDS pg_restore). Des conseils pour ignorer ces erreurs?
avjaarsveld
PS je n'ai pas utilisé -e ou --exit-on-error pour pg_restore
avjaarsveld
7
J'ai trouvé que, sur RDS, le problème est que COMMENT ON EXTENSIONnon CREATE EXTENSION. Supprimez les commentaires et ça devrait aller.
pkoch
@pkoch idem avec Google Cloud Storage. COMMENTAIRE SUR L'EXTENSION était le problème et n'était pas nécessaire
Jaybeecave
25

Pour les utilisateurs de Google Cloud Platform, toute erreur arrêtera le processus d'importation. Personnellement, j'ai rencontré deux erreurs différentes en fonction de la commande pg_dump que j'ai émise:

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

Se produit lorsque vous avez essayé de vider votre base de données dans un format de texte non brut. C'est-à-dire lorsque la commande n'a pas le paramètre -Fp ou --format = plain. Cependant, si vous l'ajoutez à votre commande, vous pouvez alors rencontrer l'erreur suivante:

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

Il s'agit d'un problème d'autorisation que je n'ai pas pu résoudre à l'aide de la commande fournie dans la documentation GCP , des conseils de ce fil de discussion actuel ou des conseils de l'équipe Google Postgres ici . Qui a recommandé d'émettre la commande suivante:

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

La seule chose qui a fait l'affaire dans mon cas était d'éditer manuellement le fichier de vidage et de commenter toutes les commandes relatives à plpgsql.

J'espère que cela aidera les âmes dépendantes de GCP.

Mettre à jour :

Il est plus facile de vider le fichier en commentant les extensions, d'autant plus que certains vidages peuvent être énormes: pg_dump ... | grep -v -E '(CREATE\ EXTENSION|COMMENT\ ON)' > mydump.sql

Ce qui peut être réduit à plpgsql: pg_dump ... | grep -v -E '(CREATE\ EXTENSION\ IF\ NOT\ EXISTS\ plpgsql|COMMENT\ ON\ EXTENSION\ plpgsql)' > mydump.sql

Stanislasdrg réintègre Monica
la source
1
GCP a maintenant la pg_dumpcommande exacte à utiliser dans ses documents :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

Vous pouvez probablement ignorer les messages d'erreur en toute sécurité dans ce cas. Ne pas ajouter de commentaire au schéma public et installer plpgsql (qui devrait déjà être installé) ne causera pas de vrais problèmes.

Cependant, si vous souhaitez effectuer une réinstallation complète, vous aurez besoin d'un utilisateur disposant des autorisations appropriées. Cela ne devrait pas être l'utilisateur que votre application exécute régulièrement, bien sûr.

Richard Huxton
la source
12

Réponse plus courte: ignorez-la.

Ce module fait partie de Postgres qui traite le langage SQL. L'erreur apparaîtra souvent dans le cadre de la copie d'une base de données distante, comme avec un «heroku pg: pull». Il n'écrase pas votre processeur SQL et vous en avertit.

Charles Merriam
la source
11

Essayez d'utiliser l' -Lindicateur avec pg_restore en spécifiant le fichier extrait depg_dump -Fc

-L fichier-liste --use-list = fichier-liste

Restaurez uniquement les éléments d'archive répertoriés dans le fichier-liste et restaurez-les dans l'ordre dans lequel ils apparaissent dans le fichier. Notez que si des commutateurs de filtrage tels que -n ou -t sont utilisés avec -L, ils restreindront davantage les éléments restaurés.

list-file est normalement créé en éditant la sortie d'une opération -l précédente. Les lignes peuvent être déplacées ou supprimées, et peuvent également être commentées en plaçant un point-virgule (;) au début de la ligne. Voir ci-dessous pour des exemples.

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

Ici, vous pouvez voir que l' inverse est vrai en ne produisant que le commentaire:

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
la source
Je pense que ce qui précède est correct, l'exclusion des commentaires pour les plugins n'affectera pas la fonctionnalité de votre application
Andreas
C'est certainement la meilleure réponse, je ne sais pas pourquoi c'est en dessous de deux réponses qui disent simplement l'ignorer ...
Dylan
3

Pour les personnes utilisant AWS , le COMMENT ON EXTENSIONn'est possible qu'en tant que super - utilisateur , et comme nous le savons par la documentation, les instances RDS sont gérées par Amazon. En tant que tel, pour vous empêcher de casser des choses comme la réplication, vos utilisateurs - même l'utilisateur root que vous avez configuré lorsque vous créez l'instance - n'auront pas les privilèges de superutilisateur complets:

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

Lorsque vous créez une instance de base de données, le compte système d'utilisateur principal que vous créez est affecté au rôle rds_superuser. Le rôle rds_superuser est un rôle Amazon RDS prédéfini similaire au rôle de superutilisateur PostgreSQL (généralement nommé postgres dans les instances locales), mais avec certaines restrictions. Comme avec le rôle de superutilisateur PostgreSQL, le rôle rds_superuser a le plus de privilèges sur votre instance de base de données et vous ne devez pas attribuer ce rôle aux utilisateurs à moins qu'ils n'aient besoin du plus grand accès à l'instance de base de données.

Afin de corriger cette erreur, utilisez simplement --pour commenter les lignes de SQL qui contiennentCOMMENT ON EXTENSION

Petar Nikov
la source
2
Ou omettez commentaires lorsque le dumping: pg_dump --no-comments.
Dmitrii I.
2

Utilisez l'utilisateur postgres (admin) pour vider le schéma, le recréer et accorder des privilèges à utiliser avant d'effectuer votre restauration. En une seule commande:

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
la source
1

Pour moi, je configurais une base de données avec pgAdmin et il semble que la configuration du propriétaire lors de la création de la base de données n'était pas suffisante. J'ai dû naviguer vers le schéma «public» et y définir le propriétaire (à l'origine, «postgres»).

Peter L
la source
0

Pour les personnes qui ont réduit le problème aux COMMENT ONdéclarations (conformément aux différentes réponses ci-dessous) et qui ont un accès superutilisateur à la base de données source à partir de laquelle le fichier de vidage est créé, la solution la plus simple pourrait être d'empêcher les commentaires d'être inclus dans le vidage. fichier en premier lieu, en les supprimant de la base de données source en cours de vidage ...

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

Les futurs vidages n'incluront donc pas les COMMENT ONdéclarations.

Mark Schneider
la source
1
Développer localement dans Rails (qui crée automatiquement un nouveau fichier de vidage à chaque fois qu'une migration de schéma est exécutée), cette solution me permet de s'exécuter simplement rails db:resetsur une instance postgresql AWS RDS sans avoir à supprimer les lignes COMMENT ON du fichier de vidage chaque fois que j'exécute un schéma migration.
Mark Schneider