In this gist we are going to use the pg_dump tool to back up a remote postgres database and pg_restore to restore the dump in a local database.
-
If postgres is not installed directly in your machine because you are usign it via docker containers, first you should install the
postgresql clientutility in your host machine, this client includespsqlandpg_dumptools.$ sudo apt install postgresql-client -
To avoid put the password every time we execute the command we will going to use a postgres password file (
.pgpass), create it in the home folder executing the following command.$ cd ~ $ touch .pgpass -
In the
.pgpassfile write the remote db information (to be backed up) following the format presented below.server:port:database:username:passwordNote that this file accepts multiple entries in the form:
hostname1:port:database1:username1:password1 hostname2:port:database2:username2:password2 -
As stated in the postgres docs you should give the rigth permission to the file executing the command below.
"On Unix systems, the permissions on a password file must disallow any access to world or group; achieve this by a command such as chmod 0600 ~/.pgpass. If the permissions are less strict than this, the file will be ignored."
$ chmod 0600 ~/.pgpass -
To make the dump execute the following command replacing the database name, user and host, note that the command should not ask for password If it ask see Troubleshooting section.
$ pg_dump database_name -Fc --clean --create --no-owner --no-acl -h remote.db.host -U remote_db_user -p 5432 > my_db_file.dumpCommand Explication
-Fc: custom format (to save as.dump)--clean: Output commands to clean (drop) database objects prior to outputting the commands for creating them.--create: Begin the output with a command to create the database itself and reconnect to the created database.--no-owner: Do not output commands to set ownership of objects to match the original database.--no-acl: Prevent dumping of access privileges (grant/revoke commands).-h: Database host-U: Database User-p: Database port
After command completion the created file "my_db_file.dump" is already to be restored in other database.
To restore the database we will use the pg_restore tool.
First of all lets create the database and a role in the localhost:
-
Create the local database
-
Using a local insatallation of postgresql
-
Open terminal and execute to use postgres user:
$ sudo -i -u postgres
Note that the terminal now is ->
postgres@user:~$-
Create a database executing the command
$ createdb my_database_name -
Create an user executing the command. This is going to ask a password.
$ createuser user -P -
Assign
postgresrole to the local db user executing the following command inpsqlconsole:$ psql $ grant postgres to user
-
-
Using a postgres docker container
-
Run the postgres container
docker run --rm --name pg-docker -d -p 5432:5432 -v $HOME/dev/docker/volumes/postgres/:/var/lib/postgresql/data postgresOptions:
--rm: used to remove the container when it stops--name: give a name to the container.-d: Run in detached mode, it means in background.-p: Map the host port 5432 to the container's port 5432.-v: Setup a volume between host and container file system.
-
Create a database executing the command:
$ docker exec pg-docker psql -U postgres -c "create database my_database_name" -
Create an user executing the command:
$ docker exec pg-docker psql -U postgres -c "create user my_user superuser password 'my_password'" -
Grant permissions on the database to the created user:
$ docker exec pg-docker psql -U postgres -c "grant all privileges on database my_database_name to my_user"
-
-
-
Execute the database restore
In the following example we are going to restore the dump in a local postgres instance.
$ pg_restore -h localhost -p 5432 -d my_database_name -U my_user my_db_file.dumpIf errors appear in the process due to permissions on data that others users owns in the dump, and the data that is being restored is all in the public schema, put the
-n publicargument to thepg_restorecommand to only restore information from this schema. (https://stackoverflow.com/a/11776053/2860519)$ pg_restore -h localhost -p 5432 -n public -d my_database_name -U my_user my_db_file.dumpAlso, there is a chance to get errors due to ownership because the dump has other user, to avoid this problems in the restore use the flags
--no-owner --role= your_new_owner$ pg_restore -h localhost -p 5432 -n public -d my_database_name --no-owner --role= my_user -U my_user my_db_file.dumpFor docker use the following commands:
- First of all, copy the dump to the conainer volume:
$ docker cp my_dump.dump pg-docker:/var/lib/postgresql/data- Once copied execute the following command to restore the database.
To delete the database before restore use:
docker exec -it <container-id> psql -U <username> -d postgres -c "DROP DATABASE <dbname>;"To create the database use:
docker exec -it <container-id> psql -U <username> -d postgres -c "CREATE DATABASE <dbname>;"$ docker exec pg-docker pg_restore -h localhost -p 5432 -d my_database_name -U my_user --no-owner --role=my_role /var/lib/postgresql/data/my_dump_file.dump
If the pg_dump command is still asking the password after create the pgpass file, try the following steps:
-
Verify the file permisions as stated in point 4 of Dump section.
-
Set the file owner as the same user which is logged in:
$ sudo chown login_username:login_username ~/.pgpass -
Verify
PGPASSFILEenvironment variable.To see it execute:
$ echo $PGPASSFILETo set it execute the following command, replacing the correct user:
$ export PGPASSFILE='/home/user/.pgpass'If you want to unset the variable execute:
$ unset PGPASSFILE