Jak rozwiązać problemy z uprawnieniami podczas przywracania bazy danych PostgreSQL

105

Zrzuciłem czystą kopię zapasową bazy danych Postgres bez właściciela za pomocą polecenia

pg_dump sample_database -O -c -U

Później, kiedy przywracam bazę danych za pomocą

psql -d sample_database -U app_name

Jednak napotkałem kilka błędów, które uniemożliwiają mi przywrócenie danych:

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

Zagłębiłem się w pg_dumpgenerowane przez zwykły tekst SQL i stwierdziłem, że zawiera 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';

Myślę, że przyczyną jest to, że użytkownik app_namenie ma uprawnień do zmiany publicschematu i plpgsql.

Jak mogę rozwiązać ten problem?

steveyang
źródło
5
Jeśli nie potrzebujesz plpgsql, to DROP EXTENSION plpgsqlprzed tobą pg_dump. Jest to bezpieczniejsze niż uczynienie aplikacji superużytkownikiem i jest wygodniejsze niż ignorowanie błędów (które bombardują, jeśli używasz --single-transactionlub -v ON_ERROR_STOP=1). Jest to znany problem, [szczegółowo omówiony przez programistów Postgres | postgresql.org/message-id/ ... ale nie naprawiono od 9.3.
Mark E. Haase

Odpowiedzi:

63

Aby rozwiązać ten problem, musisz przypisać odpowiednie uprawnienia własności. Wypróbuj poniższe rozwiązania, które powinny rozwiązać wszystkie problemy związane z uprawnieniami dla określonych użytkowników, ale jak stwierdzono w komentarzach, nie należy tego używać w produkcji:

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

Połącz się więc z bazą danych na koncie Superuser sudo -u postgres psqli wykonaj ALTER ROLE <user-name> Superuser;instrukcję.

Pamiętaj, że nie jest to najlepsze rozwiązanie na serwerze obsługującym wiele witryn, więc zamiast tego przyjrzyj się przypisywaniu poszczególnych ról: https://www.postgresql.org/docs/current/static/sql-set-role.html i https : //www.postgresql.org/docs/current/static/sql-alterrole.html .

Daniela Sokołowskiego
źródło
28
czy istnieje sposób na zrobienie tego bez bycia superużytkownikiem?
Travis Webb
17
„musi przypisać odpowiednie uprawnienia własności” i „zmień rolę <nazwa użytkownika> superużytkownik” nie są zgodne. Właściwa własności oznaczałoby, że app_userto nie super użytkownika.
Mark E. Haase
@mehaase, zaktualizuj sformułowanie odpowiedzi zamiast głosowania w dół.
Daniel Sokolowski
5
IMHO to nie jest rozwiązanie, ale obejście, którego należy unikać w produkcji.
Dmytriy Voloshyn
6
To zła sugestia, aby zrobić zwykłego użytkownikasuperuser
Evren Yurtesen
55

Użytkownicy AWS RDS, jeśli otrzymujesz to, to dlatego, że nie jesteś superużytkownikiem i zgodnie z dokumentacją aws nie możesz nim być. Odkryłem, że muszę zignorować te błędy.

Jim Zucker
źródło
5
Ten błąd uniemożliwia zakończenie przywracania za mnie (AWS RDS pg_restore). Jakieś wskazówki dotyczące ignorowania tych błędów?
avjaarsveld
PS Nie użyłem -e lub --exit-on-error dla pg_restore
avjaarsveld
7
Odkryłem, że w RDS problem COMMENT ON EXTENSIONnie jest CREATE EXTENSION. Usuń komentarze i powinno być dobrze.
pkoch
@pkoch to samo z Google Cloud Storage. KOMENTARZ DO ROZSZERZENIA był problemem i nie był potrzebny
Jaybeecave
25

W przypadku osób korzystających z Google Cloud Platform każdy błąd zatrzyma proces importowania. Osobiście napotkałem dwa różne błędy w zależności od wydanego przeze mnie polecenia pg_dump:

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

Występuje, gdy próbujesz zrzucić bazę danych w formacie innym niż zwykły tekst. To znaczy, gdy polecenie nie ma parametru -Fp lub --format = plain. Jeśli jednak dodasz go do polecenia, możesz napotkać następujący błąd:

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

Jest to problem z uprawnieniami, którego nie udało mi się naprawić za pomocą polecenia podanego w dokumentacji GCP , porad z tego bieżącego wątku lub zgodnie z poradami zespołu Google Postgres tutaj . Który zalecił wydanie następującego polecenia:

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

Jedyną rzeczą, która załatwiła sprawę w moim przypadku, była ręczna edycja pliku zrzutu i skomentowanie wszystkich poleceń związanych z plpgsql.

Mam nadzieję, że pomoże to duszom zależnym od GCP.

Aktualizacja :

Łatwiej jest zrzucić plik, komentując rozszerzenia, zwłaszcza, że ​​niektóre zrzuty mogą być ogromne: pg_dump ... | grep -v -E '(CREATE\ EXTENSION|COMMENT\ ON)' > mydump.sql

Które można zawęzić do plpgsql: pg_dump ... | grep -v -E '(CREATE\ EXTENSION\ IF\ NOT\ EXISTS\ plpgsql|COMMENT\ ON\ EXTENSION\ plpgsql)' > mydump.sql

Stanislasdrg Przywróć Monikę
źródło
1
GCP ma teraz dokładne pg_dumppolecenie do użycia w swoich dokumentach :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

W takim przypadku prawdopodobnie możesz bezpiecznie zignorować komunikaty o błędach. Brak komentarza do schematu publicznego i instalacja plpgsql (który powinien być już zainstalowany) nie spowoduje żadnych poważnych problemów.

Jeśli jednak chcesz przeprowadzić pełną ponowną instalację, będziesz potrzebować użytkownika z odpowiednimi uprawnieniami. Oczywiście nie powinien to być użytkownik, który Twoja aplikacja uruchamia rutynowo.

Richarda Huxtona
źródło
12

Krótsza odpowiedź: zignoruj ​​to.

Ten moduł jest częścią Postgres, która przetwarza język SQL. Błąd często pojawia się podczas kopiowania zdalnej bazy danych, na przykład w przypadku „heroku pg: pull”. Nie zastępuje procesora SQL i ostrzega o tym.

Charles Merriam
źródło
11

Spróbuj użyć -Lflagi z pg_restore, określając plik wzięty zpg_dump -Fc

-L plik-listy --use-list = plik-listy

Przywróć tylko te elementy archiwum, które są wymienione w pliku listy i przywróć je w kolejności, w jakiej pojawiają się w pliku. Zwróć uwagę, że jeśli używane są przełączniki filtrujące, takie jak -n lub -t z -L, dodatkowo ograniczą one przywracane elementy.

plik-listy jest zwykle tworzony przez edycję danych wyjściowych poprzedniej operacji -l. Wiersze można przenosić lub usuwać, a także komentować, umieszczając średnik (;) na początku wiersza. Poniżej znajdują się przykłady.

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

Tutaj możesz zobaczyć, że odwrotność jest prawdą, wyświetlając tylko komentarz:

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
źródło
Myślę, że powyższe jest poprawne, wykluczenie komentarzy do wtyczek nie wpłynie na funkcjonalność Twojej aplikacji
Andreas
To zdecydowanie najlepsza odpowiedź, nie jestem pewien, dlaczego poniżej dwie odpowiedzi mówią, aby po prostu ją zignorować ...
Dylan
3

Dla osób korzystających z AWS , COMMENT ON EXTENSIONjest możliwe tylko jako administrator , a jak wiemy przez docs, RDS przypadki są zarządzane przez Amazon. W związku z tym, aby zapobiec zepsuciu rzeczy, takich jak replikacja, Twoi użytkownicy - nawet użytkownik root skonfigurowany podczas tworzenia instancji - nie będą mieli pełnych uprawnień superużytkownika:

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

Podczas tworzenia instancji bazy danych główne konto systemowe użytkownika, które tworzysz, jest przypisywane do roli rds_superuser. Rola rds_superuser to predefiniowana rola Amazon RDS podobna do roli superużytkownika PostgreSQL (zwykle nazywana postgres w lokalnych instancjach), ale z pewnymi ograniczeniami. Podobnie jak w przypadku roli superużytkownika PostgreSQL, rola rds_superuser ma najwięcej uprawnień do instancji bazy danych i nie należy przypisywać tej roli użytkownikom, chyba że potrzebują oni największego dostępu do instancji bazy danych.

Aby naprawić ten błąd, po prostu użyj --do zakomentowania wierszy kodu SQL, które zawierająCOMMENT ON EXTENSION

Petar Nikov
źródło
2
Lub pominąć podczas dumping komentarze: pg_dump --no-comments.
Dmitrii I.
2

Użyj użytkownika postgres (admin), aby zrzucić schemat, ponownie go utworzyć i przyznać uprawnienia do użycia przed wykonaniem przywracania. Jednym poleceniem:

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
źródło
1

Dla mnie konfigurowałem bazę danych za pomocą pgAdmin i wydaje się, że ustawienie właściciela podczas tworzenia bazy danych nie wystarczyło. Musiałem przejść w dół do schematu „publicznego” i ustawić tam również właściciela (pierwotnie był to „postgres”).

Peter L.
źródło
0

Dla osób, które zawęziły problem do COMMENT ONstwierdzeń (zgodnie z różnymi odpowiedziami poniżej) i które mają dostęp superużytkownika do źródłowej bazy danych, z której tworzony jest plik zrzutu, najprostszym rozwiązaniem może być zapobieganie dołączaniu komentarzy do zrzutu plik w pierwszej kolejności, usuwając je z zrzucanej źródłowej bazy danych ...

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

Przyszłe zrzuty nie będą wtedy zawierać COMMENT ONinstrukcji.

Mark Schneider
źródło
1
Rozwijając lokalnie w Railsach (który tworzy nowy plik zrzutu automatycznie za każdym razem, gdy uruchamiana jest migracja schematu), rozwiązanie to pozwala mi po prostu działać rails db:resetna wystąpieniu postgresql AWS RDS bez konieczności usuwania linii COMMENT ON z pliku zrzutu za każdym razem, gdy uruchamiam schemat migracja.
Mark Schneider