Как восстановить резервную копию postgres - ОШИБКА: невозможно удалить текущую открытую базу данных

Я пытаюсь восстановить резервную копию postgres из системы, которая больше не подготовлена, и получаю ряд ошибок, в зависимости от того, что я пытаюсь сделать.

  • У меня есть только резервные копии, нет исходных серверов, на которые можно было бы сослаться.
  • Я успешно восстанавливался из этих производственных резервных копий в прошлом, но с момента последнего успеха испортил свою локальную среду (например, переустановил postgres через Homebrew)
  • Я считаю, что бывший коллега (уже недоступен) успешно восстановил эту конкретную резервную копию
  • I've encountered the same error when:
    • trying the backup using [email protected]
    • пробуем предыдущую исправную версию базы данных (используя postgres 11)

(Я прочитал связанные/предлагаемые вопросы, и они не кажутся актуальными)

Резервная копия была создана с помощью следующей команды (в сценарии bash):

pg_dump --schema=public -Fc

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

dropdb ${PGDATABASE}
createdb ${PGDATABASE}
time pg_restore \
    -j4 \
    -d ${PGDATABASE} \
    --create \
    --no-privileges \
    --no-owner \
    --clean \
    --if-exists \
    --exit-on-error \
    "${dirname}/${filename}"

Когда я запускаю команду восстановления локально, я получаю следующее:

time pg_restore -j4 -d ${PGDATABASE} --create --no-privileges --no-owner --clean --if-exists --exit-on-error ../backups/backup__2019-09-03_16-00-19.pg_dump
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 4954; 1262 962277 DATABASE mydb mydb
pg_restore: [archiver (db)] could not execute query: ERROR:  cannot drop the currently open database
    Command was: DROP DATABASE IF EXISTS mydb;

real    0m0.049s
user    0m0.019s
sys    0m0.012s

Раньше у меня случались ошибки «недостаточно места на диске» только через несколько минут работы, но, как вы можете видеть из вывода time, эта ошибка возникает почти сразу!

Резервная копия создается со сжатием -Fc , и я могу распаковать резервную копию в открытый текст, используя pg_restore backup.pg_dump > backup.sql, но я не могу найти там никаких команд, связанных с DROP DATABASE :/

-- Dumped from database version 9.6.11
-- Dumped by pg_dump version 11.3 (Ubuntu 11.3-1.pgdg14.04+1)

Я вижу, что БД изначально была сброшена с 9.6.11, но я достаточно уверен, что ранее успешно восстанавливал с PG 10...

Я пробовал разные вещи, например:

time pg_restore -d ${PGDATABASE} --no-privileges --no-owner --exit-on-error ../backups/backup__2019-09-03_16-00-19.pg_dump
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 7; 2615 1033373 SCHEMA public mydb
pg_restore: [archiver (db)] could not execute query: ERROR:  schema "public" already exists
    Command was: CREATE SCHEMA public;

ptim:dropdb mydb; createdb mydb
ptim:gizmag ptim$ dropdb mydb

ptim:gizmag ptim$ time pg_restore -d ${PGDATABASE} --create --no-privileges --no-owner --exit-on-error ../backups/backup__2019-09-03_16-00-19.pg_dump
pg_restore: [archiver (db)] connection to database "mydb" failed: FATAL:  database "mydb" does not exist

# guess I misunderstood the create flag!

ptim:gizmag ptim$ dropdb mydb; createdb mydb
dropdb: database removal failed: ERROR:  database "mydb" does not exist

ptim:gizmag ptim$ time pg_restore -d ${PGDATABASE} --create --no-privileges --no-owner --exit-on-error ../backups/backup__2019-09-03_16-00-19.pg_dump
pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 4954; 1262 962277 DATABASE mydb mydb
pg_restore: [archiver (db)] could not execute query: ERROR:  database "mydb" already exists
    Command was: CREATE DATABASE mydb WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8';

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

psql -U ptim -d mydb -1 -f ../backups/backup__2019-09-03_16-00-19.sql

SET
SET
SET
SET
SET
 set_config
------------

(1 row)

SET
SET
SET
SET
psql:../backups/backup__2019-09-03_16-00-19.sql:23: ERROR:  schema "public" already exists
psql:../backups/backup__2019-09-03_16-00-19.sql:26: ERROR:  current transaction is aborted, commands ignored until end of transaction block

# snip... repeated, and varied errors follow

Какие-либо предложения?!


person ptim    schedule 21.11.2019    source источник
comment
Если вы используете --create, вам необходимо подключиться к другой базе данных, например. postgres или template1 pg_restore -j4 -d postgres ...   -  person a_horse_with_no_name    schedule 21.11.2019
comment
Это фантастика, спасибо @a_horse_with_no_name! Решено! (TLDR; я отказался от опции --create) Ваш комментарий привел меня к следующему объяснению --create: почему-pg-restore-ignores-create... - еще раз спасибо! Хотите добавить ответ или мне?   -  person ptim    schedule 22.11.2019


Ответы (1)


Благодаря совету @a_horse_with_no_name я узнал:

-C, --create Создайте базу данных перед восстановлением в нее. Если также указано --clean, удалите и заново создайте целевую базу данных перед подключением к ней.

При использовании этой опции база данных с именем -d используется только для выполнения начальных команд DROP DATABASE и CREATE DATABASE. Все данные восстанавливаются в имя базы данных, которое появляется в архиве.

(Дополнительно объясняется в dba.stackexchange: почему pg_restore игнорирует --create. Обратите внимание, что --create имеет дополнительные, несвязанные эффекты в новых версиях pg_restore)

Мое решение состояло в том, чтобы удалить параметр --create:

dropdb ${PGDATABASE}
createdb ${PGDATABASE}
time pg_restore \
    -j4 \
    -d ${PGDATABASE} \
    --no-privileges \
    --no-owner \
    --clean \
    --if-exists \
    --exit-on-error \
    backup.pg_dump
person ptim    schedule 28.11.2019
comment
Я пытаюсь сделать то же самое и следую официальному документу, чтобы использовать --create, что дает мне много ошибок и беспокоит меня. Удалив --create и используя только --clean, это кажется нормальным. - person cwhsu; 06.10.2020