PostgreSQL Backup and Restore Using pg_dumpall and psql
Table of Contents
Backup:
1. Backup All Databases
2. Backup Users/Roles Definition
3. Backup Tablespaces Definition
4. Backup Schema Only (No Data)
5. Backup Data Only (No Schema)
6. Backup Data as INSERT Commands
7. Backup Global Objects Only (No Databases)
Restore:
9. Restore to Another Host (Different Tablespace Paths)
- A. Copy Backup File
- B. Extract Tablespace/Database Info
- C. Create Tablespace Directories on Target
- D. Create Tablespaces in PostgreSQL
- E. Optional: Backup on Target Host
- F. Restore on Target Host
- G. Final Verification
Click to expand pg_dumpall –help
[postgres@lxtrdpgdsgv01 ~]$ pg_dumpall --help
pg_dumpall extracts a PostgreSQL database cluster into an SQL script file.
Usage:
pg_dumpall [OPTION]...
General options:
-f, --file=FILENAME output file name
-v, --verbose verbose mode
-V, --version output version information, then exit
--lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock
-?, --help show this help, then exit
Options controlling the output content:
-a, --data-only dump only the data, not the schema
-c, --clean clean (drop) databases before recreating
-E, --encoding=ENCODING dump the data in encoding ENCODING
-g, --globals-only dump only global objects, no databases
-O, --no-owner skip restoration of object ownership
-r, --roles-only dump only roles, no databases or tablespaces
-s, --schema-only dump only the schema, no data
-S, --superuser=NAME superuser user name to use in the dump
-t, --tablespaces-only dump only tablespaces, no databases or roles
-x, --no-privileges do not dump privileges (grant/revoke)
--binary-upgrade for use by upgrade utilities only
--column-inserts dump data as INSERT commands with column names
--disable-dollar-quoting disable dollar quoting, use SQL standard quoting
--disable-triggers disable triggers during data-only restore
--exclude-database=PATTERN exclude databases whose name matches PATTERN
--extra-float-digits=NUM override default setting for extra_float_digits
--if-exists use IF EXISTS when dropping objects
--inserts dump data as INSERT commands, rather than COPY
--load-via-partition-root load partitions via the root table
--no-comments do not dump comments
--no-publications do not dump publications
--no-role-passwords do not dump passwords for roles
--no-security-labels do not dump security label assignments
--no-subscriptions do not dump subscriptions
--no-sync do not wait for changes to be written safely to disk
--no-table-access-method do not dump table access methods
--no-tablespaces do not dump tablespace assignments
--no-toast-compression do not dump TOAST compression methods
--no-unlogged-table-data do not dump unlogged table data
--on-conflict-do-nothing add ON CONFLICT DO NOTHING to INSERT commands
--quote-all-identifiers quote all identifiers, even if not key words
--restrict-key=RESTRICT_KEY use provided string as psql \restrict key
--rows-per-insert=NROWS number of rows per INSERT; implies --inserts
--use-set-session-authorization
use SET SESSION AUTHORIZATION commands instead of
ALTER OWNER commands to set ownership
Connection options:
-d, --dbname=CONNSTR connect using connection string
-h, --host=HOSTNAME database server host or socket directory
-l, --database=DBNAME alternative default database
-p, --port=PORT database server port number
-U, --username=NAME connect as specified database user
-w, --no-password never prompt for password
-W, --password force password prompt (should happen automatically)
--role=ROLENAME do SET ROLE before dump
If -f/--file is not used, then the SQL script will be written to the standard
output.
Report bugs to <pgsql-bugs@lists.postgresql.org>.
PostgreSQL home page: <https://www.postgresql.org/>
[postgres@lxtrdpgdsgv01 ~]$
Note: pg_dumpall does not support custom format backups. The pg_dumpall utility is used to back up an entire PostgreSQL environment, including: * Roles and users * Tablespaces * All databases (schemas and data) It is especially useful for: * Full cluster migrations * Disaster recovery * Environment replication across dev, QA, and prod When restoring to a different host, you'll need to: * Update tablespace paths (using tools like sed) * Pre-create required tablespace directories This ensures compatibility and successful restoration across different environments.
Backup
[postgres@lxtrdpgdsgv01 ~]$ nohup pg_dumpall -U postgres -v -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql > /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.log 2>&1 & [1] 5610 [postgres@lxtrdpgdsgv01 ~]$ [postgres@lxtrdpgdsgv01 ~]$ cat /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.log | grep -i /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql pg_dumpall: running ""/usr/pgsql-15/bin/pg_dump" -v -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql -Fa 'user=postgres dbname=template1'" pg_dumpall: running ""/usr/pgsql-15/bin/pg_dump" -v -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql --create -Fa 'user=postgres dbname=edpua'" pg_dumpall: running ""/usr/pgsql-15/bin/pg_dump" -v -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql --create -Fa 'user=postgres dbname=gebua'" pg_dumpall: running ""/usr/pgsql-15/bin/pg_dump" -v -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql --create -Fa 'user=postgres dbname=orcl'" pg_dumpall: running ""/usr/pgsql-15/bin/pg_dump" -v -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql -Fa 'user=postgres dbname=postgres'" [postgres@lxtrdpgdsgv01 ~]$ [postgres@lxtrdpgdsgv01 ~]$ psql psql (15.14) Type "help" for help. postgres=# \c orcl You are now connected to database "orcl" as user "postgres". orcl=# SELECT orcl-# schemaname || '.' || relname AS table_name, orcl-# pg_size_pretty(pg_total_relation_size(relid)) AS total_size, orcl-# pg_size_pretty(pg_relation_size(relid)) AS table_size, orcl-# pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_size orcl-# FROM orcl-# pg_catalog.pg_statio_user_tables orcl-# ORDER BY orcl-# pg_total_relation_size(relid) DESC; table_name | total_size | table_size | index_size ------------------+------------+------------+------------ trd.metrics_high | 799 MB | 498 MB | 301 MB trd.metrics_mid | 638 MB | 398 MB | 240 MB trd.employees | 493 MB | 322 MB | 172 MB trd.sales_2023 | 399 MB | 249 MB | 150 MB trd.sales_2024 | 399 MB | 249 MB | 150 MB trd.sales_2022 | 399 MB | 249 MB | 150 MB trd.sales_2021 | 398 MB | 248 MB | 150 MB trd.metrics_low | 159 MB | 99 MB | 60 MB trd.test_data | 71 MB | 50 MB | 21 MB trd.emp_summary | 24 kB | 8192 bytes | 16 kB trd.metrics_rest | 8192 bytes | 0 bytes | 8192 bytes (11 rows) orcl=#
2. Backup users/roles definition
[postgres@lxtrdpgdsgv01 ~]$ nohup pg_dumpall -U postgres --roles-only -v -f /pgBackup/pgsql15/backup/roles.sql > /pgBackup/pgsql15/backup/roles.log 2>&1 &
[1] 5205
[postgres@lxtrdpgdsgv01 ~]$
3. Backup tablespaces definition
[postgres@lxtrdpgdsgv01 ~]$ nohup pg_dumpall -U postgres --tablespaces-only -v -f /pgBackup/pgsql15/backup/tablespaces.sql > /pgBackup/pgsql15/backup/tablespaces.log 2>&1 &
[1] 5183
[postgres@lxtrdpgdsgv01 ~]$
4. Backup dump only the schema, no data
[postgres@lxtrdpgdsgv01 ~]$ nohup pg_dumpall -U postgres --schema-only -v -f /pgBackup/pgsql15/backup/schemas.sql > /pgBackup/pgsql15/backup/schemas.log 2>&1 &
[1] 4890
[postgres@lxtrdpgdsgv01 ~]$
5. Backup dump only the data, not the schema
[postgres@lxtrdpgdsgv01 ~]$ nohup pg_dumpall -U postgres --data-only -v -f /pgBackup/pgsql15/backup/dataonly.sql > /pgBackup/pgsql15/backup/dataonly.log 2>&1 &
[1] 5233
[postgres@lxtrdpgdsgv01 ~]$
6. Backup dump data as INSERT commands, rather than COPY
[postgres@lxtrdpgdsgv01 ~]$ nohup pg_dumpall -U postgres --inserts -v -f /pgBackup/pgsql15/backup/inserts.sql > /pgBackup/pgsql15/backup/inserts.log 2>&1 &
[1] 5274
[postgres@lxtrdpgdsgv01 ~]$
7. Backup dump only global objects, no databases
[postgres@lxtrdpgdsgv01 ~]$ nohup pg_dumpall -U postgres --globals-only -v -f /pgBackup/pgsql15/backup/globals.sql > /pgBackup/pgsql15/backup/globals.log 2>&1 &
[1] 5331
[postgres@lxtrdpgdsgv01 ~]$
Restore
A. Drop Existing Databases (Optional)
[postgres@lxtrdpgdsgv01 ~]$ psql psql (15.14) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+----------+----------+-------------+-------------+------------+-----------------+----------------------- edpua | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | gebua | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | orcl | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | postgres=CTc/postgres+ | | | | | | | =c/postgres (6 rows) postgres=# drop database edpua; DROP DATABASE postgres=# drop database gebua; DROP DATABASE postgres=# drop database orcl; DROP DATABASE postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+----------+----------+-------------+-------------+------------+-----------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | postgres=CTc/postgres+ | | | | | | | =c/postgres (3 rows) postgres=# postgres=# \db List of tablespaces Name | Owner | Location ------------+----------+--------------------- edpua_ix | postgres | /pgIx/pgsql15/edpua edpua_tb | postgres | /pgTb/pgsql15/edpua gebua_ix | postgres | /pgIx/pgsql15/gebua gebua_tb | postgres | /pgTb/pgsql15/gebua orcl_ix | postgres | /pgIx/pgsql15/orcl orcl_tb | postgres | /pgTb/pgsql15/orcl pg_default | postgres | pg_global | postgres | (8 rows) postgres=#
[postgres@lxtrdpgdsgv01 ~]$ nohup psql -U postgres -X -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql -d postgres > /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025_restore.log [1] 4132 [postgres@lxtrdpgdsgv01 ~]$ -- OR -- nohup psql -U postgres -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql > /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025_restore.log 2>&1 & -- Log: backup_all_databases_10OCT2025_restore.log
[postgres@lxtrdpgdsgv01 ~]$ psql
psql (15.14)
Type "help" for help.
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
edpua | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
gebua | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
orcl | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres +
| | | | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | postgres=CTc/postgres+
| | | | | | | =c/postgres
(6 rows)
postgres=#
9. Restore to Another Host (Different Tablespace Paths)
A. Copy Backup File
[postgres@lxtrdpgdsgv01 backup]$ scp backup_all_databases_10OCT2025.sql 192.168.2.31:/pgBackup/pgsql15/backup/ postgres@192.168.2.31's password: backup_all_databases_10OCT2025.sql 100% 3556MB 51.5MB/s 01:09 [postgres@lxtrdpgdsgv01 backup]$ [postgres@pg17 backup]$ ls -ltr backup_all_databases_10OCT2025.sql -rw-r--r--. 1 postgres postgres 3729147646 Oct 6 06:17 backup_all_databases_10OCT2025.sql [postgres@pg17 backup]$
B. Extract Tablespace/Database Info
[postgres@lxtrdpgdsgv01 backup]$ grep -i "CREATE TABLESPACE" /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql CREATE TABLESPACE orcl_tb OWNER postgres LOCATION '/pgTb/pgsql15/orcl'; CREATE TABLESPACE orcl_ix OWNER postgres LOCATION '/pgIx/pgsql15/orcl'; CREATE TABLESPACE gebua_tb OWNER postgres LOCATION '/pgTb/pgsql15/gebua'; CREATE TABLESPACE gebua_ix OWNER postgres LOCATION '/pgIx/pgsql15/gebua'; CREATE TABLESPACE edpua_tb OWNER postgres LOCATION '/pgTb/pgsql15/edpua'; CREATE TABLESPACE edpua_ix OWNER postgres LOCATION '/pgIx/pgsql15/edpua'; [postgres@lxtrdpgdsgv01 backup]$ [postgres@lxtrdpgdsgv01 backup]$ grep -i "CREATE DATABASE" /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql CREATE DATABASE edpua WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE_PROVIDER = libc LOCALE = 'en_US.UTF-8' TABLESPACE = edpua_tb; CREATE DATABASE gebua WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE_PROVIDER = libc LOCALE = 'en_US.UTF-8' TABLESPACE = gebua_tb; CREATE DATABASE orcl WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE_PROVIDER = libc LOCALE = 'en_US.UTF-8' TABLESPACE = orcl_tb; [postgres@lxtrdpgdsgv01 backup]$
C. Create Tablespace Directories on Target
[postgres@pg17 ~]$ psql psql (15.13) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+----------+----------+-------------+-------------+------------+-----------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | postgres=CTc/postgres+ | | | | | | | =c/postgres (3 rows) postgres=# postgres=# \db List of tablespaces Name | Owner | Location ------------+----------+---------- pg_default | postgres | pg_global | postgres | (2 rows) postgres=# # Create Directory [postgres@pg17 ~]$ mkdir -p /pgData/pgsql15/orcl_tb [postgres@pg17 ~]$ mkdir -p /pgData/pgsql15/orcl_ix [postgres@pg17 ~]$ mkdir -p /pgData/pgsql15/gebua_tb [postgres@pg17 ~]$ mkdir -p /pgData/pgsql15/gebua_ix [postgres@pg17 ~]$ mkdir -p /pgData/pgsql15/edpua_tb [postgres@pg17 ~]$ mkdir -p /pgData/pgsql15/edpua_ix
D. Create Tablespaces in PostgreSQL
postgres=# CREATE TABLESPACE orcl_tb OWNER postgres LOCATION '/pgData/pgsql15/orcl_tb'; CREATE TABLESPACE postgres=# CREATE TABLESPACE orcl_ix OWNER postgres LOCATION '/pgData/pgsql15/orcl_ix'; CREATE TABLESPACE postgres=# CREATE TABLESPACE gebua_tb OWNER postgres LOCATION '/pgData/pgsql15/gebua_tb'; CREATE TABLESPACE postgres=# CREATE TABLESPACE gebua_ix OWNER postgres LOCATION '/pgData/pgsql15/gebua_ix'; CREATE TABLESPACE postgres=# CREATE TABLESPACE edpua_tb OWNER postgres LOCATION '/pgData/pgsql15/edpua_tb'; CREATE TABLESPACE postgres=# CREATE TABLESPACE edpua_ix OWNER postgres LOCATION '/pgData/pgsql15/edpua_ix'; CREATE TABLESPACE postgres=# -- OR --- You can modify the tablespace paths directly in the backup file; however, this approach is not recommended for large backup files due to reliability concerns. cd /pgBackup/pgsql15/backup/ # Replace ORCL paths sed -i 's|/pgTb/pgsql15/orcl|/pgData/pgsql15/orcl_tb|g' backup_all_databases_10OCT2025.sql sed -i 's|/pgIx/pgsql15/orcl|/pgData/pgsql15/orcl_ix|g' backup_all_databases_10OCT2025.sql # Replace GEBUA paths sed -i 's|/pgTb/pgsql15/gebua|/pgData/pgsql15/gebua_tb|g' backup_all_databases_10OCT2025.sql sed -i 's|/pgIx/pgsql15/gebua|/pgData/pgsql15/gebua_ix|g' backup_all_databases_10OCT2025.sql # Replace EDPUA paths sed -i 's|/pgTb/pgsql15/edpua|/pgData/pgsql15/edpua_tb|g' backup_all_databases_10OCT2025.sql sed -i 's|/pgIx/pgsql15/edpua|/pgData/pgsql15/edpua_ix|g' backup_all_databases_10OCT2025.sql [postgres@pg17 ~]$ psql psql (15.13) Type "help" for help. postgres=# \db List of tablespaces Name | Owner | Location ------------+----------+-------------------------- edpua_ix | postgres | /pgData/pgsql15/edpua_ix edpua_tb | postgres | /pgData/pgsql15/edpua_tb gebua_ix | postgres | /pgData/pgsql15/gebua_ix gebua_tb | postgres | /pgData/pgsql15/gebua_tb orcl_ix | postgres | /pgData/pgsql15/orcl_ix orcl_tb | postgres | /pgData/pgsql15/orcl_tb pg_default | postgres | pg_global | postgres | (8 rows) postgres=#
E. Optional: Backup on Target Host
[postgres@pg17 ~]$ nohup pg_dumpall -U postgres -v -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025_pg17.sql > /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025_pg17.log 2>&1 &
[1] 4246
[postgres@pg17 ~]$
[postgres@pg17 ~]$ nohup psql -U postgres -X -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql -d postgres > /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025_restore_pg17.log 2>&1 &
[1] 5213
[postgres@pg17 ~]$
-- OR --
nohup psql -U postgres -f /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025.sql > /pgBackup/pgsql15/backup/backup_all_databases_10OCT2025_restore_pg17.log 2>&1 &
-- Log: backup_all_databases_10OCT2025_restore_pg17.log
[postgres@pg17 ~]$ psql psql (15.13) Type "help" for help. postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | ICU Locale | Locale Provider | Access privileges -----------+----------+----------+-------------+-------------+------------+-----------------+----------------------- edpua | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | gebua | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | orcl | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | =c/postgres + | | | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | | libc | postgres=CTc/postgres+ | | | | | | | =c/postgres (6 rows) postgres=# [postgres@pg17 ~]$ psql psql (15.13) Type "help" for help. postgres=# \c orcl You are now connected to database "orcl" as user "postgres". orcl=# SELECT orcl-# schemaname || '.' || relname AS table_name, orcl-# pg_size_pretty(pg_total_relation_size(relid)) AS total_size, orcl-# pg_size_pretty(pg_relation_size(relid)) AS table_size, orcl-# pg_size_pretty(pg_total_relation_size(relid) - pg_relation_size(relid)) AS index_size orcl-# FROM orcl-# pg_catalog.pg_statio_user_tables orcl-# ORDER BY orcl-# pg_total_relation_size(relid) DESC; table_name | total_size | table_size | index_size ------------------+------------+------------+------------ trd.metrics_high | 799 MB | 498 MB | 301 MB trd.metrics_mid | 638 MB | 398 MB | 240 MB trd.employees | 493 MB | 322 MB | 172 MB trd.sales_2023 | 399 MB | 249 MB | 150 MB trd.sales_2024 | 399 MB | 249 MB | 150 MB trd.sales_2022 | 399 MB | 249 MB | 150 MB trd.sales_2021 | 398 MB | 248 MB | 150 MB trd.metrics_low | 159 MB | 99 MB | 60 MB trd.test_data | 71 MB | 50 MB | 21 MB trd.emp_summary | 24 kB | 8192 bytes | 16 kB trd.metrics_rest | 8192 bytes | 0 bytes | 8192 bytes (11 rows) orcl=#
Caution: Your use of any information or materials on this website is entirely at your own risk. It is provided for educational purposes only. It has been tested internally, however, we do not guarantee that it will work for you. Ensure that you run it in your test environment before using.
Thank you,
Rajasekhar Amudala
Email: br8dba@gmail.com
Linkedin: https://www.linkedin.com/in/rajasekhar-amudala/