46

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:

  1. Install a fresh, vanilla Ubuntu 14.04 distro (I'm using Vagrant with this Vagrant box).
  2. Install PostgreSQL 9.3, configure to allow local connections as PostgreSQL user "postgres" from any Linux user.
  3. 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
    
  4. Create a backup of the database like so:

    PGPASSWORD="postgres" pg_dump --dbname=mydb --username=postgres --format=custom > pg_backup.dump
  5. Delete some rows out of the data table in mydb so we will be able to tell if we restored the data successfully.

  6. 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
    Command was: CREATE SCHEMA public;



WARNING: errors ignored on restore: 1

I cannot just ignore this because I am running this command programmatically and need to use the exit status to determine if the restore failed or not. Initially, I wondered if this problem was because I put my database in public (the default schema). I reasoned that public would be created as a result of the --create option by pg_restore before the data was restored (which could conceivably try to create that schema as well since that is where my table is), but when I tried the above steps with my table in a different schema, the results were the same and the error messages were identical.

Am I doing something wrong? Why am I seeing this error?

6 Answers 6

31

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.

1
  • 2
    I'm using 9.6, and specifying --create without clean does not fix the issue.
    – Cerin
    Nov 29, 2018 at 19:47
14

In my case, the reason was that I was using pg_restore from postgresql-contrib version 11.2 to restore a dump made by pg_dump 9.6 to a PostgreSQL cluster 9.6.

After I downgraded my pg_restore back to 9.6, this schema "public" already exists error was gone, and the restoring process worked as before.

1
  • I had a similar issue but rather than try downgrading just pg_restore in my postgres docker image, blindly adding --schema=public worked.
    – jozxyqk
    May 27 at 21:58
6

In my case I was able to solve this problem by first running CREATE DATABASE target_db; then running pg_restore with --schema=public -d target_db. This assumes you only want the public schema, but I reckon that's quite a common scenario.

2
  • This was the only solution which worked for me when migrating from 9.5 to 14. Accepted solution with --create failed as the dump included some extensions. Creating a blank db, adding in the extensions then running the following with the --schema=public option instead did the trick: pg_restore --dbname=existingdb --username=postgres --schema=public filename.backup Jul 30, 2022 at 19:00
  • This also worked for me, restoring a 10.2 dump into a 15.4 DB. I'm still not sure though, why --schema=public is enough and other schemas present in my DB like information_schema, pg_catalog and pg_toast can be omitted...
    – dokaspar
    Sep 14 at 9:50
4

The restore includes the public schema and so does create database. So remove the schema after creating the database so that the restore can create it without error.

Note: Following assumes -h -U -p are default and PGPASSWORD or .pgpass is set

    psql << XENDX
    drop database if exists DB_NAME;
    create database DB_NAME;
    \c DB_NAME;
    drop schema if exists public;
    create schema public;
    XENDX
    
    pg_restore -d DB_NAME FILE_CREATED_WITH_pg_dump
1

I solved it with:

in the db.sql file

drop database if exists DB_name;
create database DB_name;
drop schema if exists public;
create schema public;
\q

then

PGPASSWOD=DB_pass psql -U DB_user -h 127.0.0.1 < db.sql

And then

PGPASSWOD=DB_pass pg_restore -h 127.0.0.1 \ 
    -U DB_user -d DB_name --create --no-acl --no-owner DB_dump_FILE

My pg_restore version is 11.6

0

I got the same errors when using pgsql-pg_restore from version 12 to restore a dump made by pg_dump 9.6. Changed it to use pg_restore version 9, problem solved.

1
  • this contributes nothing new to the question, as this was already mentioned in an answer.
    – nbk
    Jun 17, 2021 at 8:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.