Как решить проблемы с привилегиями при восстановлении базы данных PostgreSQL

105

Я сбросил чистую резервную копию базы данных Postgres без владельца с помощью команды

pg_dump sample_database -O -c -U

Позже, когда я восстановлю базу данных с помощью

psql -d sample_database -U app_name

Однако я обнаружил несколько ошибок, которые не позволяют мне восстановить данные:

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

Я покопался в простом тексте, который pg_dumpгенерирует SQL, и обнаружил, что он содержит 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';

Я думаю, что причина в том, что у пользователя app_nameнет прав на изменение publicсхемы и plpgsql.

Как я мог решить эту проблему?

Steveyang
источник
5
Если не надо plpgsql, то DROP EXTENSION plpgsqlперед вами pg_dump. Это безопаснее, чем превращение вашего приложения в суперпользователя, и удобнее, чем игнорирование ошибок (которые становятся бомбой, если вы используете --single-transactionили -v ON_ERROR_STOP=1). Это известная проблема [подробно обсуждается разработчиками Postgres | postgresql.org/message-id/…, но не исправлено в версии 9.3.
Марк Э. Хаасе

Ответы:

63

Чтобы решить эту проблему, вы должны назначить соответствующие права собственности. Попробуйте следующее, которое должно решить все проблемы, связанные с разрешениями для конкретных пользователей, но, как указано в комментариях, это не должно использоваться в производстве:

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

Итак, подключитесь к базе данных под учетной записью суперпользователя sudo -u postgres psqlи выполните ALTER ROLE <user-name> Superuser;инструкцию.

Имейте в виду, что это не лучшее решение для многосайтового хостинг-сервера, поэтому вместо этого обратите внимание на назначение отдельных ролей: https://www.postgresql.org/docs/current/static/sql-set-role.html и https : //www.postgresql.org/docs/current/static/sql-alterrole.html .

Даниэль Соколовски
источник
28
есть ли способ сделать это, не будучи суперпользователем?
Трэвис Уэбб
17
"должен назначить надлежащие права владения" и "изменить роль <имя-пользователя> суперпользователь" несовместимы. Правильное владение означало бы, что app_userвы не суперпользователь.
Марк Э. Хаас
@mehaase, пожалуйста, обновите формулировку ответа, а не голосование против.
Daniel Sokolowski
5
ИМХО, это не решение, а обходной путь, которого следует избегать в производстве.
Дмитрий Волошин
6
- Плохое предложение делать обычного пользователяsuperuser
Эврен Юртесен
56

Пользователи AWS RDS, если вы получаете это, потому что вы не являетесь суперпользователем и, согласно документации AWS, вы не можете им быть. Я обнаружил, что должен игнорировать эти ошибки.

Джим Цукер
источник
5
Эта ошибка не позволяет мне завершить восстановление (AWS RDS pg_restore). Какие-нибудь советы по игнорированию этих ошибок?
avjaarsveld 01
PS Я не использовал -e или --exit-on-error для pg_restore
avjaarsveld 01
7
Я обнаружил, что проблема COMMENT ON EXTENSIONне в RDS CREATE EXTENSION. Удалите комментарии, и все будет в порядке.
pkoch
@pkoch то же самое с Google Cloud Storage. КОММЕНТАРИЙ К РАСШИРЕНИЮ был проблемой и не нужен
Jaybeecave
25

Для людей, использующих Google Cloud Platform, любая ошибка остановит процесс импорта. Лично я столкнулся с двумя разными ошибками в зависимости от введенной мной команды 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.

Возникает, когда вы пытаетесь выгрузить свою БД в формате, отличном от обычного текста. Т.е. когда в команде отсутствует параметр -Fp или --format = plain. Однако, если вы добавите его в свою команду, вы можете столкнуться со следующей ошибкой:

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

Это проблема с разрешением, которую я не смог исправить с помощью команды, представленной в документации GCP , советов из этого текущего потока или следуя советам команды Google Postgres здесь . Которая рекомендовала выполнить следующую команду:

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

Единственное, что помогло в моем случае, - это вручную отредактировать файл дампа и закомментировать все команды, относящиеся к plpgsql.

Я надеюсь, что это поможет душам, зависящим от GCP.

Обновить :

Легче выгрузить файл, закомментировав расширения, тем более, что некоторые дампы могут быть огромными: pg_dump ... | grep -v -E '(CREATE\ EXTENSION|COMMENT\ ON)' > mydump.sql

Что можно сузить до plpgsql: pg_dump ... | grep -v -E '(CREATE\ EXTENSION\ IF\ NOT\ EXISTS\ plpgsql|COMMENT\ ON\ EXTENSION\ plpgsql)' > mydump.sql

Stanislasdrg Reinstate Monica
источник
1
Теперь у GCP есть точная pg_dumpкоманда для использования в своих документах :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

В этом случае, вероятно, можно спокойно игнорировать сообщения об ошибках. Отсутствие комментария к общедоступной схеме и установка plpgsql (который уже должен быть установлен) не вызовут реальных проблем.

Однако, если вы хотите выполнить полную переустановку, вам понадобится пользователь с соответствующими разрешениями. Конечно, это не должен быть пользователь, которым ваше приложение обычно запускается.

Ричард Хакстон
источник
12

Короче ответ: игнорируйте это.

Этот модуль является частью Postgres, обрабатывающей язык SQL. Ошибка часто возникает при копировании удаленной базы данных, например, с помощью «heroku pg: pull». Он не перезаписывает ваш SQL-процессор и предупреждает вас об этом.

Чарльз Мерриам
источник
11

Попробуйте использовать -Lфлаг с pg_restore, указав файл, взятый изpg_dump -Fc

-L файл-списка --use-list = файл-список

Восстановите только те элементы архива, которые перечислены в list-file, и восстановите их в том порядке, в котором они появляются в файле. Обратите внимание, что если параметры фильтрации, такие как -n или -t, используются с -L, они дополнительно ограничивают восстанавливаемые элементы.

list-file обычно создается путем редактирования вывода предыдущей операции -l. Строки можно перемещать или удалять, а также можно закомментировать, поставив точку с запятой (;) в начале строки. См. Примеры ниже.

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

Здесь вы можете увидеть обратное верно, если вывести только комментарий:

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
--
Лигемер
источник
Я думаю, что вышеизложенное верно, исключение комментариев для плагинов не повлияет на функциональность вашего приложения
Андреас,
Это определенно лучший ответ, я не уверен, почему ниже двух ответов говорится, что нужно просто игнорировать его ...
Дилан
3

Для людей, использующих AWS , COMMENT ON EXTENSIONэто возможно только в качестве суперпользователя , и, как мы знаем из документации, инстансы RDS управляются Amazon. Таким образом, чтобы вы не нарушали такие вещи, как репликация, ваши пользователи - даже пользователь root, который вы настроили при создании экземпляра, - не будут иметь полных привилегий суперпользователя:

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

Когда вы создаете экземпляр БД, созданной вами системной учетной записи главного пользователя назначается роль rds_superuser. Роль rds_superuser - это предварительно определенная роль Amazon RDS, аналогичная роли суперпользователя PostgreSQL (обычно называемой postgres в локальных экземплярах), но с некоторыми ограничениями. Как и в случае с ролью суперпользователя PostgreSQL, роль rds_superuser имеет наибольшее количество привилегий в вашем экземпляре БД, и вы не должны назначать эту роль пользователям, если они не нуждаются в наибольшем доступе к экземпляру БД.

Чтобы исправить эту ошибку, просто --закомментируйте строки SQL, содержащиеCOMMENT ON EXTENSION

Петар Ников
источник
2
Или Опустить комментарии , когда демпинг: pg_dump --no-comments.
Дмитрий I.
2

Используйте пользователя postgres (admin), чтобы выгрузить схему, воссоздать ее и предоставить привилегии для использования, прежде чем выполнять восстановление. В одной команде:

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
источник
1

Для меня я настраивал базу данных с помощью pgAdmin, и мне показалось, что установки владельца во время создания базы данных было недостаточно. Мне пришлось перейти к «общедоступной» схеме и установить там владельца (изначально «postgres»).

Питер Л
источник
0

Для людей, которые сузили проблему до COMMENT ONутверждений (согласно различным ответам ниже) и имеют доступ суперпользователя к исходной базе данных, из которой создается файл дампа, самым простым решением может быть предотвращение включения комментариев в дамп файл в первую очередь, удалив их из сбрасываемой исходной базы данных ...

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

Будущие дампы не будут включать эти COMMENT ONутверждения.

Марк Шнайдер
источник
1
Эти решения, разрабатываемые локально в Rails (который автоматически создает новый файл дампа при запуске миграции схемы), позволяют мне просто работать rails db:resetс экземпляром AWS RDS postgresql без необходимости удалять строки COMMENT ON из файла дампа каждый раз, когда я запускаю схему. миграция.
Марк Шнайдер