Назад | Перейти на главную страницу

Резервное копирование и восстановление Postgres с помощью pg_dumpall, split & gzip & --set ON_ERROR_STOP = on

У меня есть база данных PostgreSQL 9.4, работающая на CentOS 7.3. База данных довольно ванильная и устанавливается через https://yum.postgresql.org/ .

Я пытаюсь создать резервную копию этой базы данных и протестировать восстановление на другом хосте. Если я попытаюсь восстановить с помощью --set ON_ERROR_STOP=on, восстановление не удается. Почему это?

Моя процедура резервного копирования основана на рекомендациях на https://www.postgresql.org/docs/9.4/static/backup-dump.html . Я использую следующую команду после новой новой установки Postgres, которая включает в себя initdb.

pg_dumpall --clean | gzip | split --suffix-length=4 --numeric-suffixes --additional-suffix=.split.gz --bytes 1G - postgres.pg_dumpall.

Это создает серию таких файлов:

[postgres@db1 backups]$ ls
postgres.pg_dumpall.0000.split.gz
postgres.pg_dumpall.0001.split.gz
...
postgres.pg_dumpall.0040.split.gz
[postgres@db1 backups]$

Чтобы восстановить, я думал, что могу использовать cat, gunzip и psql --set ON_ERROR_STOP=on. Однако это не работает:

[postgres@db2 ~]$ cat postgres.pg_dumpall.*.split.gz | gunzip | psql --set ON_ERROR_STOP=on postgres
SET
SET
SET
ERROR:  database "foo" does not exist
[postgres@db2 ~]$

Команда завершится, если я удалю --set ON_ERROR_STOP=on, но тогда мне непонятно, действителен ли резервный архив или нет.

В --clean вариант для pg_dumpall добавляет команды для удаления каждой базы данных, а затем воссоздает их. Если база данных не существует, то DROP DATABASE foo команда завершится с ошибкой, которая остановит ваш скрипт с ON_ERROR_STOP включен.

Использовать --clean --if-exists в pg_dumpall для создания команд, которые сначала проверят, существует ли база данных, прежде чем удалять ее. Эти команды будут выдавать уведомления вместо ошибок, если база данных не существует.

Для удаления других команд, вызывающих проблему, вы можете использовать sed после gunzip чтобы удалить эту команду из сценария. Вы должны понимать, что делает команда, прежде чем удалять ее (в данном случае это попытка удалить суперпользователя). Несколько команд sed будут разделены ; внутри строки в кавычках, данной sed. Эта команда должна dвыберите строки, в которых сценарий будет пытаться отбросить, и воссоздать postgres учетная запись суперпользователя.

cat postgres.pg_dumpall.*.split.gz | gunzip | sed '/^DROP ROLE.*postgres/d;/^CREATE ROLE.*postgres/d' | psql --set ON_ERROR_STOP=on postgres