Como resolver problemas de privilégios ao restaurar o banco de dados PostgreSQL

105

Despejei um backup limpo e sem proprietário do banco de dados Postgres com o comando

pg_dump sample_database -O -c -U

Mais tarde, quando restauro o banco de dados com

psql -d sample_database -U app_name

No entanto, encontrei vários erros que me impedem de restaurar os dados:

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

Pesquisei no SQL de texto simples pg_dumpgerado e descobri que contém 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';

Acho que as causas são que o usuário app_namenão tem privilégios para alterar o publicesquema e plpgsql.

Como posso resolver esse problema?

Steveyang
fonte
5
Se você não precisa plpgsql, DROP EXTENSION plpgsqlantes de você pg_dump. Isso é mais seguro do que tornar seu aplicativo um superusuário e é mais conveniente do que ignorar erros (que detonam se você usar --single-transactionou -v ON_ERROR_STOP=1). Este é um problema conhecido, [discutido longamente pelos desenvolvedores do Postgres | postgresql.org/message-id/… mas não corrigido a partir de 9.3.
Mark E. Haase

Respostas:

63

Para resolver o problema, você deve atribuir as permissões de propriedade adequadas. Tente o procedimento abaixo, que deve resolver todos os problemas relacionados à permissão para usuários específicos, mas conforme declarado nos comentários, isso não deve ser usado na produção:

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

Portanto, conecte-se ao banco de dados com uma conta de superusuário sudo -u postgres psqle execute uma ALTER ROLE <user-name> Superuser;instrução.

Lembre-se de que esta não é a melhor solução em um servidor de hospedagem de vários sites, então dê uma olhada na atribuição de funções individuais: https://www.postgresql.org/docs/current/static/sql-set-role.html e https : //www.postgresql.org/docs/current/static/sql-alterrole.html .

Daniel Sokolowski
fonte
28
existe uma maneira de fazer isso sem ser um superusuário?
Travis Webb
17
"deve atribuir as permissões de propriedade adequadas" e "alterar função <nome do usuário> superusuário" não são congruentes. A propriedade adequada significaria que nãoapp_user é um superusuário.
Mark E. Haase
@mehaase atualize o texto da resposta em vez de votar contra.
Daniel Sokolowski
5
IMHO, isso não é solução, mas solução alternativa que deve ser evitada na produção.
Dmytriy Voloshyn
6
É uma má sugestão fazer um usuário normalsuperuser
Evren Yurtesen
55

Usuários do AWS RDS, se você está entendendo isso, é porque não é um superusuário e, de acordo com a documentação do aws, não pode ser. Descobri que devo ignorar esses erros.

Jim Zucker
fonte
5
Este erro está impedindo que a restauração seja concluída para mim (AWS RDS pg_restore). Alguma dica para ignorar esses erros?
avjaarsveld
PS Eu não usei -e ou --exit-on-error para pg_restore
avjaarsveld
7
Descobri que, no RDS, o problema é COMMENT ON EXTENSIONnão CREATE EXTENSION. Remova os comentários e você ficará bem.
pkoch
@pkoch mesmo com o Google Cloud Storage. COMENTÁRIO SOBRE A EXTENSÃO era o problema e não era necessário
Jaybeecave
25

Para quem usa o Google Cloud Platform, qualquer erro interromperá o processo de importação. Pessoalmente, encontrei dois erros diferentes, dependendo do comando pg_dump que emiti:

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

Ocorre quando você tenta despejar seu banco de dados em um formato de texto não simples. Ou seja, quando o comando não tem o parâmetro -Fp ou --format = plain. No entanto, se você adicioná-lo ao seu comando, poderá encontrar o seguinte erro:

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

Este é um problema de permissão que não consegui corrigir usando o comando fornecido nos documentos do GCP , as dicas deste tópico atual ou seguindo os conselhos da equipe do Google Postgres aqui . Qual recomendado para emitir o seguinte comando:

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

A única coisa que funcionou no meu caso foi editar manualmente o arquivo de despejo e comentar todos os comandos relacionados ao plpgsql.

Espero que isso ajude as almas que dependem do GCP.

Atualização:

É mais fácil despejar o arquivo comentando as extensões, especialmente porque alguns despejos podem ser enormes: pg_dump ... | grep -v -E '(CREATE\ EXTENSION|COMMENT\ ON)' > mydump.sql

Que pode ser reduzido a plpgsql: pg_dump ... | grep -v -E '(CREATE\ EXTENSION\ IF\ NOT\ EXISTS\ plpgsql|COMMENT\ ON\ EXTENSION\ plpgsql)' > mydump.sql

Stanislasdrg Reintegrar Monica
fonte
1
O GCP agora tem o pg_dumpcomando exato para usar em seus documentos :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

Você provavelmente pode ignorar com segurança as mensagens de erro nesse caso. Deixar de adicionar um comentário ao esquema público e instalar o plpgsql (que já deve estar instalado) não causará problemas reais.

No entanto, se quiser fazer uma reinstalação completa, você precisará de um usuário com as permissões apropriadas. Esse não deve ser o usuário que seu aplicativo executa rotineiramente.

Richard Huxton
fonte
12

Resposta mais curta: ignore.

Este módulo é a parte do Postgres que processa a linguagem SQL. O erro frequentemente aparecerá como parte da cópia de um banco de dados remoto, como com um 'heroku pg: pull'. Ele não sobrescreve o processador SQL e avisa sobre isso.

Charles Merriam
fonte
10

Tente usar a -Lsinalização com pg_restore especificando o arquivo obtido depg_dump -Fc

-L list-file --use-list = list-file

Restaure apenas os elementos do arquivo que estão listados no arquivo de lista e restaure-os na ordem em que aparecem no arquivo. Observe que, se chaves de filtragem como -n ou -t forem usadas com -L, elas restringirão ainda mais os itens restaurados.

O arquivo-lista é normalmente criado editando a saída de uma operação -l anterior. As linhas podem ser movidas ou removidas e também podem ser comentadas colocando um ponto e vírgula (;) no início da linha. Veja abaixo exemplos.

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

Aqui você pode ver que o inverso é verdadeiro, gerando apenas o comentário:

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
fonte
Acho que o acima está correto, excluir comentários para plug-ins não afetará a funcionalidade de seu aplicativo
Andreas
3

Para pessoas que usam AWS , o COMMENT ON EXTENSIONé possível apenas como superusuário e, como sabemos pelos documentos, as instâncias RDS são gerenciadas pela Amazon. Dessa forma, para evitar que você interrompa itens como a replicação, seus usuários - mesmo o usuário root que você configurou ao criar a instância - não terão privilégios totais de superusuário:

http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Apêndice.PostgreSQL.CommonDBATasks.html

Ao criar uma instância de banco de dados, a conta do sistema do usuário mestre que você cria é atribuída à função rds_superuser. A função rds_superuser é uma função pré-definida do Amazon RDS semelhante à função de superusuário do PostgreSQL (normalmente chamada de postgres em instâncias locais), mas com algumas restrições. Como com a função de superusuário do PostgreSQL, a função rds_superuser tem mais privilégios em sua instância de banco de dados e você não deve atribuir esta função a usuários, a menos que eles precisem de mais acesso à instância de banco de dados.

Para corrigir este erro, use --para comentar as linhas de SQL que contémCOMMENT ON EXTENSION

Petar Nikov
fonte
2
Ou comentários omitir durante o despejo: pg_dump --no-comments.
Dmitrii I.
2

Use o usuário postgres (admin) para descartar o esquema, recriá-lo e conceder privilégios para uso antes de fazer a restauração. Em um comando:

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
fonte
1

Para mim, estava configurando um banco de dados com pgAdmin e parece que definir o proprietário durante a criação do banco de dados não foi suficiente. Eu tive que navegar até o esquema 'público' e definir o proprietário lá também (originalmente era 'postgres').

Peter L
fonte
0

Para pessoas que limitaram o problema às COMMENT ONdeclarações (conforme várias respostas abaixo) e que têm acesso de superusuário ao banco de dados de origem a partir do qual o arquivo de despejo é criado, a solução mais simples pode ser impedir que os comentários sejam incluídos no despejo em primeiro lugar, removendo-os do banco de dados de origem que está sendo despejado ...

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

Os despejos futuros não incluirão as COMMENT ONinstruções.

Mark Schneider
fonte
1
Desenvolvendo localmente em Rails (que cria um novo arquivo de despejo automaticamente sempre que uma migração de esquema é executada), esta solução me permite simplesmente executar rails db:resetem uma instância postgresql do AWS RDS sem ter que remover as linhas COMMENT ON do arquivo de despejo sempre que executo um esquema migração.
Mark Schneider