Fix PostgreSQL backup restore (#1628)

* Export PG* envs when backing up postgres

* Export PG* envs when restoring postgres from backup

* Prevent postgres connection from dropping all at ones

* Alter postgres backups docs  

Include another crucial prerequisite.

* "feel free switching" -> "feel free to switch"

* Address the feedback
This commit is contained in:
Nikita Shupeyko 2018-05-05 12:27:27 +03:00 committed by GitHub
parent 8203cfe4fc
commit b4d0416530
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 45 deletions

View File

@ -1,13 +1,14 @@
PostgreSQL Backups with Docker
==============================
Prerequisites:
.. note:: For brevity it is assumed that you will be running the below commands against local environment, however, this is by no means mandatory so feel free to switch to ``production.yml`` when needed.
#. the project was generated with ``use_docker`` set to ``y``.
For brevity it is assumed that will be running the below commands against local environment, however, this is by no means mandatory so feel free switching to ``production.yml`` when needed.
Prerequisites
-------------
Note that the application stack should not necessarily be running when applying any of the instructions below, unless explicitly stated otherwise. For instance, suppose the stack has been down for quite some time or have never even been up yet -- rather than starting it beforehand use a single ``$ docker-compose -f local.yml run --rm <command>`` with the desired command. By contrast, should you already have your application up and running do not bother waiting for ``run`` instruction to finish (they usually take a bit longer due to bootstrapping phase), just use ``$ docker-compose -f local.yml exec <command>`` instead; note that any ``exec`` command fails unless all of the required containers are running. From now on, we will be using ``run``-style examples for general-case compatibility.
#. the project was generated with ``use_docker`` set to ``y``;
#. the stack is up and running: ``docker-compose -f local.yml up -d postgres``.
Creating a Backup
@ -15,7 +16,7 @@ Creating a Backup
To create a backup, run::
$ docker-compose -f local.yml run --rm postgres backup
$ docker-compose -f local.yml exec postgres backup
Assuming your project's database is named ``my_project`` here is what you will see: ::
@ -30,7 +31,7 @@ Viewing the Existing Backups
To list existing backups, ::
$ docker-compose -f local.yml run --rm postgres backups
$ docker-compose -f local.yml exec postgres backups
These are the sample contents of ``/backups``: ::
@ -62,16 +63,11 @@ Restoring from the Existing Backup
To restore from one of the backups you have already got (take the ``backup_2018_03_13T09_05_07.sql.gz`` for example), ::
$ docker-compose -f local.yml run --rm postgres restore backup_2018_03_13T09_05_07.sql.gz
$ docker-compose -f local.yml exec postgres restore backup_2018_03_13T09_05_07.sql.gz
You will see something like ::
Restoring the 'my_project' database from the '/backups/backup_2018_03_13T09_05_07.sql.gz' backup...
INFO: Dropping all connections to the database...
pg_terminate_backend
----------------------
(0 rows)
INFO: Dropping the database...
INFO: Creating a new database...
INFO: Applying the backup to the new database...

View File

@ -25,14 +25,13 @@ if [[ "${POSTGRES_USER}" == "postgres" ]]; then
exit 1
fi
export PGHOST="postgres"
export PGUSER="${POSTGRES_USER}"
export PGPASSWORD="${POSTGRES_PASSWORD}"
export PGDATABASE="${POSTGRES_DB}"
backup_filename="${BACKUP_FILE_PREFIX}_$(date +'%Y_%m_%dT%H_%M_%S').sql.gz"
pg_dump \
--host=postgres \
--dbname="${POSTGRES_DB}" \
--username="${POSTGRES_USER}" \
| gzip > "${BACKUP_DIR_PATH}/${backup_filename}"
pg_dump | gzip > "${BACKUP_DIR_PATH}/${backup_filename}"
message_success "'${POSTGRES_DB}' database backup '${backup_filename}' has been created and placed in '${BACKUP_DIR_PATH}'."

View File

@ -37,40 +37,18 @@ if [[ "${POSTGRES_USER}" == "postgres" ]]; then
exit 1
fi
export PGHOST="postgres"
export PGUSER="${POSTGRES_USER}"
export PGPASSWORD="${POSTGRES_PASSWORD}"
message_info "Dropping all connections to the database..."
# Source: http://dba.stackexchange.com/a/11895
drop_postgres_connections_sql='UPDATE pg_database'
drop_postgres_connections_sql+=" SET datallowconn = 'false'"
drop_postgres_connections_sql+=" WHERE datname = '${POSTGRES_DB}';"
drop_postgres_connections_sql+='SELECT pg_terminate_backend(pid)'
drop_postgres_connections_sql+=' FROM pg_stat_activity'
drop_postgres_connections_sql+=" WHERE datname = '${POSTGRES_DB}';"
psql \
--host=localhost \
--username=postgres \
--dbname=postgres \
--command="${drop_postgres_connections_sql}"
export PGDATABASE="${POSTGRES_DB}"
message_info "Dropping the database..."
dropdb \
--host=postgres \
--username="${POSTGRES_USER}" \
"${POSTGRES_DB}"
dropdb "${PGDATABASE}"
message_info "Creating a new database..."
createdb \
--host=postgres \
--username="${POSTGRES_USER}" \
--owner="${POSTGRES_USER}" \
"${POSTGRES_DB}"
createdb --owner="${POSTGRES_USER}"
message_info "Applying the backup to the new database..."
gunzip -c "${backup_filename}" \
| psql \
--host=postgres \
--username="${POSTGRES_USER}" \
"${POSTGRES_DB}"
gunzip -c "${backup_filename}" | psql "${POSTGRES_DB}"
message_success "The '${POSTGRES_DB}' database has been restored from the '${backup_filename}' backup."