HiveBrain v1.2.0
Get Started
← Back to all entries
debugsqlMajor

pg_restore: [archiver (db)] could not execute query: ERROR: schema "public" already exists

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
errorarchiverpublicquerycouldschemaalreadyexistsnotpg_restore

Problem

I am using pg_dump / pg_restore to backup and restore a PostgreSQL database, but am getting some error messages (and a non-zero exit status) from pg_restore. I tried a super simple base case (outlined below) but still got these errors:

pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 5; 2615 2200 SCHEMA public postgres
pg_restore: [archiver (db)] could not execute query: ERROR: schema "public" already exists
Command was: CREATE SCHEMA public;

Steps to reproduce:

  • Install a fresh, vanilla Ubuntu 14.04 distro (I'm using Vagrant with this Vagrant box).



  • Install PostgreSQL 9.3, configure to allow local connections as PostgreSQL user "postgres" from any Linux user.



-
Create a test database. I'm just doing:

vagrant@vagrant-ubuntu-trusty-64:~$ psql --username=postgres postgres
psql (9.3.5)
Type "help" for help.

postgres=# create database mydb;
CREATE DATABASE
postgres=# \q
vagrant@vagrant-ubuntu-trusty-64:~$ psql --username=postgres mydb
psql (9.3.5)
Type "help" for help.

mydb=# create table data(entry bigint);
CREATE TABLE
mydb=# insert into data values(1);
INSERT 0 1
mydb=# insert into data values(2);
INSERT 0 1
mydb=# insert into data values(3);
INSERT 0 1
mydb=# \q

-
Create a backup of the database like so:

PGPASSWORD="postgres" pg_dump --dbname=mydb --username=postgres --format=custom > pg_backup.dump

-
Delete some rows out of the data table in mydb so we will be able to tell if we restored the data successfully.

-
Restore the database with:

PGPASSWORD="postgres" pg_restore --clean --create --dbname=postgres --username=postgres pg_backup.dump

The data is restored, but the pg_restore command in step 6 exits with status 1 and shows the following output:

pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 5; 2615 2200 SCHEMA public postgres
pg_restore: [archiver (db)] could not execute query: ERROR: schema "public" already exists
C

Solution

The error is harmless but to get rid of it, I think you need to break this restore into two commands, as in:

dropdb -U postgres mydb && \
 pg_restore --create --dbname=postgres --username=postgres pg_backup.dump


The --clean option in pg_restore doesn't look like much but actually raises non-trivial problems.

For versions up to 9.1

The combination of --create and --clean in pg_restore options used to be an error in older PG versions (up to 9.1). There is indeed some contradiction between (quoting the 9.1 manpage):


--clean
Clean (drop) database objects before recreating them

and


--create
Create the database before restoring into it.

Because what's the point of cleaning inside a brand-new database?

Starting from version 9.2

The combination is now accepted and the doc says this (quoting the 9.3 manpage):


--clean
Clean (drop) database objects before recreating them. (This might generate some harmless error messages, if any objects were not present in the destination database.)


--create
Create the database before restoring into it. If --clean is also specified, drop and recreate the target database before connecting to it.

Now having both together leads to this kind of sequence during your restore:

DROP DATABASE mydb;
...
CREATE DATABASE mydb WITH TEMPLATE = template0... [other options]
...
CREATE SCHEMA public;
...
CREATE TABLE...


There is no DROP for each individual object, only a DROP DATABASE at the beginning. If not using --create this would be the opposite.

Anyway this sequence raises the error of public schema already existing because creating mydb from template0 has imported it already (which is normal, it's the point of a template database).

I'm not sure why this case is not handled automatically by pg_restore. Maybe this would cause undesirable side-effects when an admin decides to customize template0 and/or change the purpose of public, even if we're not supposed to do that.

Code Snippets

dropdb -U postgres mydb && \
 pg_restore --create --dbname=postgres --username=postgres pg_backup.dump
DROP DATABASE mydb;
...
CREATE DATABASE mydb WITH TEMPLATE = template0... [other options]
...
CREATE SCHEMA public;
...
CREATE TABLE...

Context

StackExchange Database Administrators Q#90258, answer score: 31

Revisions (0)

No revisions yet.