Estou usando pg_dump / pg_restore para fazer backup e restaurar um banco de dados PostgreSQL, mas estou recebendo algumas mensagens de erro (e um status de saída diferente de zero) do pg_restore. Eu tentei um caso base super simples (descrito abaixo), mas ainda recebi esses erros:
pg_restore: [archiver (db)] Erro ao PROCESSAR TOC: pg_restore: [archiver (db)] Erro da entrada 5 do TOC; 2615 2200 SCHEMA postgres público pg_restore: [archiver (db)] não pôde executar a consulta: ERRO: o esquema "público" já existe O comando era: CREATE SCHEMA public;
Passos para reproduzir:
- Instale uma nova distribuição do Ubuntu 14.04 (estou usando o Vagrant com esta caixa do Vagrant ).
- Instale o PostgreSQL 9.3, configure para permitir conexões locais como usuário PostgreSQL "postgres" de qualquer usuário Linux.
Crie um banco de dados de teste. Estou apenas fazendo:
vagrant@vagrant-ubuntu-trusty-64:~$ psql --username=postgres postgres psql (9.3.5) Digite "ajuda" para obter ajuda. postgres=# cria banco de dados mydb; CRIAR BANCO DE DADOS postgres=# \q vagrant@vagrant-ubuntu-trusty-64:~$ psql --username=postgres mydb psql (9.3.5) Digite "ajuda" para obter ajuda. mydb=# cria dados da tabela(entry bigint); CRIAR A TABELA mydb=# inserir em valores de dados(1); INSERIR 0 1 mydb=# inserir em valores de dados(2); INSERIR 0 1 mydb=# inserir em valores de dados(3); INSERIR 0 1 meudb=# \q
Crie um backup do banco de dados assim:
PGPASSWORD="postgres" pg_dump --dbname=mydb --username=postgres --format=custom > pg_backup.dump
Exclua algumas linhas da tabela de dados em mydb para que possamos saber se restauramos os dados com sucesso.
Restaure o banco de dados com:
PGPASSWORD="postgres" pg_restore --clean --create --dbname=postgres --username=postgres pg_backup.dump
Os dados são restaurados, mas o comando pg_restore na etapa 6 sai com status 1
e mostra a seguinte saída:
pg_restore: [archiver (db)] Erro ao PROCESSAR TOC: pg_restore: [archiver (db)] Erro da entrada 5 do TOC; 2615 2200 SCHEMA postgres público pg_restore: [archiver (db)] não pôde executar a consulta: ERRO: o esquema "público" já existe O comando era: CREATE SCHEMA public; AVISO: erros ignorados na restauração: 1
Não posso simplesmente ignorar isso porque estou executando esse comando programaticamente e preciso usar o status de saída para determinar se a restauração falhou ou não. Inicialmente, me perguntei se esse problema era porque coloquei meu banco de dados em público (o esquema padrão). Eu raciocinei que public seria criado como resultado da --create
opção por pg_restore antes que os dados fossem restaurados (o que poderia tentar criar esse esquema também, já que é onde está minha tabela), mas quando tentei as etapas acima com minha tabela em um esquema diferente, os resultados foram os mesmos e as mensagens de erro foram idênticas.
Estou fazendo algo errado? Por que estou vendo esse erro?
O erro é inofensivo, mas para se livrar dele, acho que você precisa dividir essa restauração em dois comandos, como em:
A
--clean
opção em pg_restore não parece muito, mas na verdade levanta problemas não triviais.Para versões até 9.1
A combinação de
--create
e--clean
nas opções do pg_restore costumava ser um erro nas versões mais antigas do PG (até 9.1). Há de fato alguma contradição entre (citando a página de manual 9.1):e
Porque qual é o sentido de limpar dentro de um banco de dados novinho em folha?
A partir da versão 9.2
A combinação agora é aceita e o documento diz isso (citando a página de manual 9.3):
Agora, ter os dois juntos leva a esse tipo de sequência durante a restauração:
Não há
DROP
para cada objeto individual, apenas umDROP DATABASE
no início. Se não usar--create
isso seria o oposto.De qualquer forma essa sequência gera o erro de
public
esquema já existente porque criarmydb
detemplate0
já importou (o que é normal, é o ponto de um banco de dados de templates).Não sei por que esse caso não é tratado automaticamente pelo
pg_restore
. Talvez isso causaria efeitos colaterais indesejáveis quando um administrador decide personalizartemplate0
e/ou alterar a finalidade depublic
, mesmo que não devêssemos fazer isso.No meu caso, o motivo foi que eu estava usando
pg_restore
postgresql-contrib versão 11.2 para restaurar um dump feito pelopg_dump
9.6 para um cluster PostgreSQL 9.6.Depois que fiz o downgrade
pg_restore
para 9.6, esseschema "public" already exists
erro desapareceu e o processo de restauração funcionou como antes.A restauração inclui o esquema público e também cria o banco de dados. Portanto, remova o esquema após criar o banco de dados para que a restauração possa criá-lo sem erros.
Nota: A seguir, assume -se que
-h -U -p
é padrão ePGPASSWORD
ou.pgpass
está definidoNo meu caso, consegui resolver esse problema primeiro executando
CREATE DATABASE target_db;
e depois executandopg_restore
com o--schema=public -d target_db
. Isso pressupõe que você queira apenas o esquema público, mas acho que esse é um cenário bastante comum.Eu resolvi com:
no
db.sql
arquivoentão
E depois
Minha versão do pg_restore é 11.6
Recebi os mesmos erros ao usar o pgsql-pg_restore da versão 12 para restaurar um despejo feito pelo pg_dump 9.6. Alterado para usar pg_restore versão 9, problema resolvido.