Category Archives: PostgreSQL

How PostgreSQL Replay Uncommitted Data During Crash Recovery

How PostgreSQL Replay Uncommitted Data During Crash Recovery

  1. When PostgreSQL crashes, shared memory is lost but WAL files, data files, CLOG, and pg_control remains on disk.
  2. On restart, Postmaster reads pg_control, detects state = DB_IN_PRODUCTION (not a clean shutdown), sets state to DB_IN_CRASH_RECOVERY, and forks the Startup Process to handle recovery.
  3. Startup Process (background process) reads pg_control again to find the last checkpoint LSN (the REDO point) and opens the WAL file at exactly that position to begin replay.
  4. The Startup Process reads WAL files one record at a time β€” for each record, it finds the related data page, loads it into memory (Shared Buffers), applies the change to that page in memory, and marks it as dirty (modified but not yet written to disk).
  5. TheΒ Startup Process applies every single WAL record to memory pages β€” it does not care whether the transaction was committed or not. Both committed and uncommitted changes are loaded into Shared Buffers, because WAL replay never checks CLOG at this stage.
  6. Before applying any WAL record to a page, Startup Process checks the page’s pd_lsn β€” if pd_lsn >= WAL record LSN, the page already has that change (BGWriter flushed it before crash) and the record is safely skipped (idempotent replay).
  7. When Startup Process seesΒ XLOG_COMMITΒ orΒ XLOG_ABORTΒ records in the WAL during replay, it updates CLOG accordingly, marking the transaction as COMMITTED or ABORTED.
  8. When theΒ Startup ProcessΒ reaches the end of WAL files (the crash point), any transaction that had noΒ COMMITΒ orΒ ABORT record is considered as never completed. The Startup Process explicitly marks all those transactions asΒ ABORTEDΒ in CLOG right away before allowing any user to connect β€” this is why you always seeΒ ABORTEDΒ and neverΒ IN_PROGRESSΒ after a crash recovery.
  9. After replay finishes, Startup Process performs an end-of-recovery checkpoint (flushes all dirty buffers including with uncommitted data, write them permanently to the actual database files on disk), updates pg_control with the new checkpoint LSN and sets state = DB_IN_PRODUCTION, and then signals Postmaster to accept client connections.
  10. Uncommitted data physically exists in the database files on disk, but no user will ever see it: CLOG says those transactions areΒ ABORTED, so MVCC automatically makes those rows permanently invisible to all queries. Later, VACUUM physically removes the dead tuples from the pages and frees up the space.
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

How ABORT/ROLLBACK Works in PostgreSQL

How ABORT Works in PostgreSQL

 

  • Signal: The database detects an error or receives a ROLLBACK command and marks the transaction as aborted.

  • WAL File Write: An ABORT record is written to the WAL buffer in RAM and flushed into the actual 16MB WAL files on disk to keep a complete history.

  • CLOG Status: The status of the Transaction ID (XID) is instantly switched to “Aborted” in the Commit Log bitmap.

  • MVCC Isolation: The modified data rows are left on the disk but immediately become invisible to all other users.

  • Cleanup: The background Autovacuum process later scans the database, clears out these dead rows, and reclaims the disk space.

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

How a Checkpoint Works in PostgreSQL

How a Checkpoint Works Internally in PostgreSQL

The Checkpointer performs the following steps

The Checkpointer performs the following steps

  1. Marks a Safe Point (Redo LSN): PostgreSQL identifies a position in the WAL called the Redo LSN and writes a CKPT_START record. If a crash happens later, the database knows it only needs to recover data starting from this exact point forward.

  2. Writes “Dirty Pages” Slowly: It identifies all data changed in memory (dirty pages) and writes them to the operating system cache. It does this slowly (Spreading) to prevent the hard drive from freezing up for users.

  3. Forces Data to Be Permanent (fsync): The checkpointer issues an fsync() call to ensure that all modified database pages written from the shared buffer cache to the operating system’s page cache are safely flushed to the database files on persistent storage. Checkpointing does not wake up the BG writer like oracle, the Checkpointer performs the writes dirty buffers to disk.

  4. Writes a Success Receipt: A CKPT_END record is written to the WAL to seal the process. Only after this succeeds is the pg_control file updated with the Redo LSN (from Step 1) to officially confirm to the entire system that the checkpoint finished safely.

  5. Triggers WAL Cleanup (Recycling/Removal Decision)

Now that data is safely on disk, old WAL files are no longer needed forΒ crash recovery. However, Postgres only deletes or reuses them after checking these rules:

PostgreSQL checks:

  • min_wal_size
    • Keep at least this much WAL available.
    • WAL files below this threshold are usually recycled instead of removed.
  • max_wal_size
    • If total WAL exceeds this value, PostgreSQL tries to recycle or remove old WAL files after the checkpoint.
  • archive_mode / archive_command
    • If WAL archiving is enabled, a WAL file cannot be removed or recycled until it has been successfully archived.
    • The corresponding .ready file changes to .done only after successful archiving.
  • wal_keep_size
    • Prevents removal of WAL files that may still be needed by streaming replication standbys.
  • slot_wal_keep_size / Replication Slots
    • WAL required by any replication slot must be retained.
    • If a standby has fallen behind, PostgreSQL keeps the required WAL files until the slot no longer needs them (subject to slot_wal_keep_size if configured).

Crash Recovery During Instance Startup

If the database crashes during Step 2 or Step 3, the pg_control file still points to the previous successful checkpoint. Because pg_control is not updated until the very end of Step 4, Postgres knows on reboot that the current checkpoint failed, ignores it completely, and safely recovers using the older, valid checkpoint instead.

Checkpoint TriggerDescription
Time-basedAutomatically triggered every checkpoint_timeout (default: 5 minutes).
WAL Size LimitTriggered when the total WAL generated exceeds max_wal_size, allowing PostgreSQL to control WAL growth.
Manual CheckpointA DBA manually initiates a checkpoint using: CHECKPOINT;
Smart / Fast ShutdownDuring a normal server shutdown, PostgreSQL performs a checkpoint to ensure that all dirty buffers are written to disk, reducing recovery time during the next startup.
Immediate ShutdownNo checkpoint is performed. The server terminates immediately, requiring crash recovery during the next startup.
pg_basebackupBy default, pg_basebackup requests the primary server to perform a checkpoint before copying data files, ensuring a consistent physical backup.
Checkpoint behavior can be controlled using:
--checkpoint=fast - Completes as quickly as possible
or
--checkpoint=spread (Default) - Spreads writes over checkpoint_completion_target
Crash RecoveryAfter replaying all required WAL records following an unexpected shutdown, PostgreSQL automatically writes a new checkpoint before accepting client connections.
Point-in-Time Recovery (PITR)After recovery reaches the requested recovery target, PostgreSQL performs a checkpoint before opening the database for normal operation.
Standby PromotionWhen a standby server is promoted to become the new primary, PostgreSQL performs a checkpoint to establish a new recovery starting point.
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

WAL Commit Process

PostgreSQL WAL Commit Process

1. The Modification (In-Memory)

When a user executes a data-modifying query (like INSERT, UPDATE, or DELETE):

  • The change is made to the table or index data inside the Shared Buffers (RAM). The page in memory is now marked as “dirty.”

  • Simultaneously, a record of this exact change is constructed and written sequentially into the WAL Buffers (also in RAM).

2. The COMMIT Command Issued

When the client sends the COMMIT command, PostgreSQL must guarantee that this change will survive a sudden power outage or crash before it can tell the user “Success.”

3. Flushing to Disk (XLogFlush)

To ensure durability without the massive overhead of writing entire data pages to disk immediately, Postgres uses the Write-Ahead Logging protocol:

  • The internal function XLogFlush() is called.

  • It identifies the exact position (Log Sequence Number, or LSN) of the commit record in the WAL Buffer.

  • It issues a synchronous write to flush all WAL buffers up to that LSN out of RAM and into the current 16MB WAL segment file on permanent storage.

  • An fsync() system call is issued to ensure the OS cache actually commits the data to physical disk platters or flash memory.

4. Acknowledgment to the Client

Once the operating system confirms that the WAL record is safely written to the physical storage, the transaction status is updated to “committed” in the commit log (CLOG), and PostgreSQL sends a success acknowledgment back to the client application.

Crucial Architectural Concepts

  • Write-Ahead Rule: The core rule of WAL is that changes to data pages must not be written to permanent database files on disk until the log records describing those changes have been flushed to stable storage. If the server crashes, Postgres reads the WAL from the last checkpoint forward and reapplies the changes (“redoes” them).

  • Asynchronous Commit Alternative: If you set the configuration parameter synchronous_commit = off, Postgres will acknowledge the client’s COMMIT before the WAL buffer is flushed to disk (relying on the WAL Writer background process to flush it within roughly 3 times wal_writer_delay). This massively increases write throughput but introduces a risk of losing up to a split-second of recent transactions if the server suddenly loses power.

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

Table Backup and Recovery Using pg_dump in PostgreSQL

Table Backup and Recovery Using pg_dump in PostgreSQL

EnvironmentUAT (Source)SIT (Target)SIT (Table Test)
Databasegebuagebtagebsit
Server/HostGEBUA / 192.168.2.23GEBTA / 192.168.2.21GEBSIT / 192.168.2.22
Schema/Tablesgeb (emp, dept) / trd (orders)geb.emp, geb.dept (refreshed)trd.orders (refreshed)
Backup Location/pgBackup/gebua/backup/pgBackup/gebta/backup/pgBackup/gebsit/backup

Table Backup Flags Reference

FlagDescriptionExample
-t tableInclude specific table onlypg_dump -t geb.emp -d gebua
-t t1 -t t2Include multiple tablespg_dump -t geb.emp -t geb.dept -d gebua
-T tableExclude specific tablepg_dump -T geb.pgbench_accounts -d gebua
-sStructure only (no data)pg_dump -t geb.dept -s -d gebua
-aData only (no structure)pg_dump -t geb.dept -a -d gebua
-FcCustom format (recommended)pg_dump -t geb.emp -Fc -f backup.dmp
-vVerbose outputpg_dump -t geb.emp -v -d gebua
-cRestore: drop object before recreatingpg_restore -t geb.emp -c -d gebta
-lList dump contents (TOC)pg_restore -l backup.dmp

Contents



When pg_restore is used with -t (table), PostgreSQL implicitly performs a data-only restore for that table. It does not restore the table definition (DDL). Therefore:

  • If geb.dept already exists, its data is restored.
  • If geb.dept does not exist, nothing is restored because there is no table to load data into.
  • Separated Schema and Table (-n geb -t dept): Using the explicit schema flag (-n geb) along with the table flag (-t dept) prevents pg_restore from getting confused by the dot-notation (geb.dept) filter logic.

pg_restore -d gebta -t dept -n geb -Fc -v 02_task_gebua_geb_emp_dept_backup_binary.dmp > 02_task_gebua_geb_emp_dept_backup_binary_restore_single_table.log 2>&1 &

0. Sample Data on Source

[postgres@pgdb02 backup]$ psql -d gebua -c "SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL SELECT 'dept', COUNT(*) FROM geb.dept UNION ALL SELECT 'orders', COUNT(*) FROM trd.orders ORDER BY table_name;"
 table_name | row_count
------------+-----------
 dept       |         5
 emp        |         3
 orders     |   1000001
(3 rows)

[postgres@pgdb02 backup]$

1. Backup a Single Table & Restore

Table-level backups are useful when you only need to refresh or recover one table without touching the rest of the schema.

BACKUP on UAT:

[postgres@pgdb02 ~]$ cd /pgBackup/gebua/backup
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -t geb.emp -Fc -v -f 01_task_gebua_geb_emp_backup_binary.dmp > 01_task_gebua_geb_emp_backup_binary.log 2>&1 &
[1] 4101
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 01_task_gebua_geb_emp_backup_binary.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.emp"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

[postgres@pgdb02 backup]$ scp 01_task_gebua_geb_emp_backup_binary.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/
01_task_gebua_geb_emp_backup_binary.dmp 100% 1367 934.7KB/s 00:00
[postgres@pgdb02 backup]$

RESTORE on SIT:

# Make sure schema should exist
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "CREATE SCHEMA GEB;"
CREATE SCHEMA
[postgres@lxceftsgvdb01 backup]$

# Drop if exits
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "DROP TABLE geb.emp;"
DROP TABLE
[postgres@lxceftsgvdb01 backup]$

# Create SCHEMA IF NOT EXIST
[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fc -v 01_task_gebua_geb_emp_backup_binary.dmp > 01_task_gebua_geb_emp_backup_binary_restore.log 2>&1 &
[1] 4218
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 01_task_gebua_geb_emp_backup_binary_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: creating TABLE "geb.emp"
pg_restore: processing data for table "geb.emp"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT COUNT(*) FROM geb.emp;"
 count
-------
     3
(1 row)

[postgres@lxceftsgvdb01 backup]$

2. Backup Multiple Tables

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -t geb.emp -t geb.dept -Fc -v -f 02_task_gebua_geb_emp_dept_backup_binary.dmp > 02_task_gebua_geb_emp_dept_backup_binary.log 2>&1 &
[1] 5210
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 02_task_gebua_geb_emp_dept_backup_binary.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

[postgres@pgdb02 backup]$ scp 02_task_gebua_geb_emp_dept_backup_binary.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/
02_task_gebua_geb_emp_dept_backup_binary.dmp 100% 2324 1.4MB/s 00:00
[postgres@pgdb02 backup]$
[postgres@pgdb02 backup]$ psql -d gebta -c "DROP TABLE geb.emp; DROP TABLE geb.dept;"
DROP TABLE
DROP TABLE
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ nohup pg_restore -d gebta -Fc -v 02_task_gebua_geb_emp_dept_backup_binary.dmp > 02_task_gebua_geb_emp_dept_backup_binary_restore.log 2>&1 &
[1] 5233
[postgres@pgdb02 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 02_task_gebua_geb_emp_dept_backup_binary_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: creating TABLE "geb.dept"
pg_restore: creating TABLE "geb.emp"
pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT 'emp' AS table_name, COUNT(*) FROM geb.emp UNION ALL SELECT 'dept', COUNT(*) FROM geb.dept;"
 table_name | count
------------+-------
 emp        |     3
 dept       |     5
(2 rows)

[postgres@lxceftsgvdb01 backup]$

3. Backup Table Structure Only & Table Data Only

Splitting structure and data into two dumps lets you version/restore DDL independently from the data load β€” restore structure first, then data.

BACKUP on UAT:

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -t geb.dept -Fc -s -v -f 03_task_gebua_geb_dept_backup_structure.dmp > 03_task_gebua_geb_dept_backup_structure.log 2>&1 &
[1] 5301
[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -t geb.dept -Fc -a -v -f 04_task_gebua_geb_dept_backup_data.dmp > 04_task_gebua_geb_dept_backup_data.log 2>&1 &
[2] 5304
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 03_task_gebua_geb_dept_backup_structure.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
[postgres@pgdb02 backup]$
[postgres@pgdb02 backup]$
[postgres@pgdb02 backup]$ cat 04_task_gebua_geb_dept_backup_data.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

[postgres@pgdb02 backup]$ scp 03_task_gebua_geb_dept_backup_structure.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/
03_task_gebua_geb_dept_backup_structure.dmp 100% 1461 1.1MB/s 00:00
[postgres@pgdb02 backup]$ scp 04_task_gebua_geb_dept_backup_data.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/
04_task_gebua_geb_dept_backup_data.dmp 100% 1206 625.9KB/s 00:00
[postgres@pgdb02 backup]$

RESTORE on SIT (structure first, then data):

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "DROP TABLE geb.dept;"
DROP TABLE
[postgres@lxceftsgvdb01 backup]$


[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fc -v 03_task_gebua_geb_dept_backup_structure.dmp > 03_task_gebua_geb_dept_backup_structure_restore.log 2>&1 &
[1] 4302
[postgres@lxceftsgvdb01 backup]$ cat 03_task_gebua_geb_dept_backup_structure_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: creating TABLE "geb.dept"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fc -v 04_task_gebua_geb_dept_backup_data.dmp > 04_task_gebua_geb_dept_backup_data_restore.log 2>&1 &
[1] 4315
[postgres@lxceftsgvdb01 backup]$ cat 04_task_gebua_geb_dept_backup_data_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: implied data-only restore
pg_restore: processing data for table "geb.dept"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT COUNT(*) FROM geb.dept;"
 count
-------
     5
(1 row)

[postgres@lxceftsgvdb01 backup]$

4. Restore Single Table from Multiple Table Backup Dump

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "DROP TABLE geb.dept;"
DROP TABLE
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ pg_restore -d gebta -n geb -t dept -Fc -v 02_task_gebua_geb_emp_dept_backup_binary.dmp > 02_task_gebua_geb_emp_dept_backup_binary_restore_single_table.log 2>&1 &
[1] 4422
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 02_task_gebua_geb_emp_dept_backup_binary_restore_single_table.log
pg_restore: connecting to database for restore
pg_restore: creating TABLE "geb.dept"
pg_restore: processing data for table "geb.dept"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT COUNT(*) FROM geb.dept;"
 count
-------
     5
(1 row)

[postgres@lxceftsgvdb01 backup]$

5. Restore Single Table from Full Database Backup Dump

BACKUP (full database) on UAT:

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -Fc -v -f 05_task_gebua_full_backup_binary.dmp > 05_task_gebua_full_backup_binary.log 2>&1 &
[1] 5410
[postgres@pgdb02 backup]$ cat 05_task_gebua_full_backup_binary.log
nohup: ignoring input pg_dump: last built-in OID is 16383
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "trd.orders"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

[postgres@pgdb02 backup]$ scp 05_task_gebua_full_backup_binary.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/
05_task_gebua_full_backup_binary.dmp 100% 34MB 41.7MB/s 00:00
[postgres@pgdb02 backup]$

RESTORE single table on SIT:

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "\dn"
      List of schemas
  Name  |       Owner
--------+-------------------
 geb    | postgres
 public | pg_database_owner
 trd    | trdadm
(3 rows)

[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "DROP TABLE trd.orders;"
DROP TABLE
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ pg_restore -d gebta -n trd -t orders -Fc -v 05_task_gebua_full_backup_binary.dmp > 05_task_gebua_full_backup_binary_restore_single_table.log 2>&1 &
[1] 4509
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ cat 05_task_gebua_full_backup_binary_restore_single_table.log
pg_restore: connecting to database for restore
pg_restore: creating TABLE "trd.orders"
pg_restore: processing data for table "trd.orders"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT COUNT(*) FROM trd.orders;"
  count
---------
 1000001
(1 row)

[postgres@lxceftsgvdb01 backup]$

6. Drop and Recreate the Table During Restore

[postgres@lxceftsgvdb01 backup]$ pg_restore -d gebta -n trd -t orders -Fc -c -v 05_task_gebua_full_backup_binary.dmp > 05_task_gebua_full_backup_binary_restore_single_table_c.log 2>&1 &
[1] 4525
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ cat 05_task_gebua_full_backup_binary_restore_single_table_c.log
pg_restore: connecting to database for restore
pg_restore: dropping TABLE orders
pg_restore: creating TABLE "trd.orders"
pg_restore: processing data for table "trd.orders"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT COUNT(*) FROM trd.orders;"
  count
---------
 1000001
(1 row)

[postgres@lxceftsgvdb01 backup]$

7. Restore Single table from Single schema dump

BACKUP on UAT:

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -n geb -Fc -v -f 01_task_gebua_geb_backup_binary.dmp > 01_task_gebua_geb_backup_binary.log 2>&1 &
[1] 4349
[postgres@pgdb02 backup]$

TRANSFER to SIT:

[postgres@pgdb02 backup]$
[postgres@pgdb02 backup]$ scp 01_task_gebua_geb_backup_binary.dmp lxceftsgvdb01:/pgBackup/gebta/backup
01_task_gebua_geb_backup_binary.dmp                                                                                                     100%   27MB  52.3MB/s   00:00
[postgres@pgdb02 backup]$

RESTORE on SIT:

# Without -n 
[postgres@lxceftsgvdb01 backup]$ pg_restore -d gebta -t dept -c -Fc -v 01_task_gebua_geb_backup_binary.dmp
pg_restore: connecting to database for restore
pg_restore: dropping TABLE dept
pg_restore: creating TABLE "geb.dept"
pg_restore: processing data for table "geb.dept"
[postgres@lxceftsgvdb01 backup]$

-- OR --

# With -n -t
[postgres@lxceftsgvdb01 backup]$ pg_restore -d gebta -n geb -t dept -c -Fc -v 01_task_gebua_geb_backup_binary.dmp
pg_restore: connecting to database for restore
pg_restore: dropping TABLE dept
pg_restore: creating TABLE "geb.dept"
pg_restore: processing data for table "geb.dept"
[postgres@lxceftsgvdb01 backup]$

8. Restore Single table from Multi schema dump

BACKUP on UAT:

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -n geb -n trd -Fc -v -f 04_task_gebua_geb_sales_backup_multi_schema.dmp > 04_task_gebua_geb_sales_backup_multi_schema.log 2>&1 &
[1] 4328
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 04_task_gebua_geb_sales_backup_multi_schema.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: finding table default expressions
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_tellers"
pg_dump: dumping contents of table "trd.orders"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

[postgres@pgdb02 backup]$
[postgres@pgdb02 backup]$ scp 04_task_gebua_geb_sales_backup_multi_schema.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/
04_task_gebua_geb_sales_backup_multi_schema.dmp                                                                                                100%   34MB  59.9MB/s   00:00
[postgres@pgdb02 backup]$

RESTORE on SIT:

[postgres@lxceftsgvdb01 backup]$ pg_restore -d gebta -n geb -t dept -Fc -c -v 04_task_gebua_geb_sales_backup_multi_schema.dmp
pg_restore: connecting to database for restore
pg_restore: dropping TABLE dept
pg_restore: creating TABLE "geb.dept"
pg_restore: processing data for table "geb.dept"
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT COUNT(*) FROM geb.dept;"
 count
-------
     5
(1 row)

[postgres@lxceftsgvdb01 backup]$

9. View Backup Contents

# List dump contents
pg_restore -l 01_task_gebua_geb_emp_backup_binary.dmp

[postgres@lxceftsgvdb01 backup]$ pg_restore -l 01_task_gebua_geb_emp_backup_binary.dmp
;
; Archive created at 2026-07-16 19:50:13 +08
; dbname: gebua
; TOC Entries: 6
; Compression: gzip
; Dump Version: 1.16-0
; Format: CUSTOM
; Integer: 4 bytes
; Offset: 8 bytes
; Dumped from database version: 17.10
; Dumped by pg_dump version: 17.10
;
;
; Selected TOC Entries:
;
219; 1259 32844 TABLE geb emp gebadm
4354; 0 32844 TABLE DATA geb emp gebadm
[postgres@lxceftsgvdb01 backup]$

# Extract only object definitions (Table Only)
[postgres@lxceftsgvdb01 backup]$ pg_restore -s -f emp_table_metadata.sql 01_task_gebua_geb_emp_backup_binary.dmp
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ cat emp_table_metadata.sql
--
-- PostgreSQL database dump
--

\restrict de2CWMbMHynBifQUiksm12g6tnrI5bb0441VuCUrKEkAOPy97yAFZStx9E95REZ

-- Dumped from database version 17.10
-- Dumped by pg_dump version 17.10

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: emp; Type: TABLE; Schema: geb; Owner: gebadm
--

CREATE TABLE geb.emp (
    name text,
    designation text,
    project text,
    company text
);


ALTER TABLE geb.emp OWNER TO gebadm;

--
-- PostgreSQL database dump complete
--

\unrestrict de2CWMbMHynBifQUiksm12g6tnrI5bb0441VuCUrKEkAOPy97yAFZStx9E95REZ

[postgres@lxceftsgvdb01 backup]$


# Extract the dump into SQL (extract DDL and data)
[postgres@lxceftsgvdb01 backup]$ pg_restore -f emp_table_data_only.sql 01_task_gebua_geb_emp_backup_binary.dmp
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ cat emp_table_data_only.sql
--
-- PostgreSQL database dump
--

\restrict Y08cgQwrYR77M0cDFpfm0kElelenUf9hXTzya2BOG9ZVZ2tK1MrqAYWIJdJMKHN

-- Dumped from database version 17.10
-- Dumped by pg_dump version 17.10

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET transaction_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: emp; Type: TABLE; Schema: geb; Owner: gebadm
--

CREATE TABLE geb.emp (
    name text,
    designation text,
    project text,
    company text
);


ALTER TABLE geb.emp OWNER TO gebadm;

--
-- Data for Name: emp; Type: TABLE DATA; Schema: geb; Owner: gebadm
--

COPY geb.emp (name, designation, project, company) FROM stdin;
Sugi    DBA     Jetstar iGATE
Teja    DBA     RCM     iGATE
RAJ     DBA     RCM     iGATE
\.


--
-- PostgreSQL database dump complete
--

\unrestrict Y08cgQwrYR77M0cDFpfm0kElelenUf9hXTzya2BOG9ZVZ2tK1MrqAYWIJdJMKHN

[postgres@lxceftsgvdb01 backup]$
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

Schema Backup and Restore Using pg_dump in PostgreSQL

PostgreSQL Schema Level Backup & Restore

EnvironmentUAT (Source)SIT (Target)
Databasegebuagebta
Server/HostGEBUA / 192.168.2.23GEBTA / 192.168.2.21
Schema 1geb (tables: emp, dept,hr,pgbench_accounts,pgbench_branches,pgbench_history,pgbench_tellers)geb (to be populated)
Schema 2trd (table: orders)trd (optional)
Backup Location/pgBackup/gebua/backup/pgBackup/gebta/backup

Schema Backup Flags Reference

FlagDescriptionExample
-n schemaInclude specific schema onlypg_dump -n geb -d gebua
-n schema1 -n schema2Include multiple schemaspg_dump -n geb -n sales -d gebua
-N schemaExclude specific schemapg_dump -N pg_catalog -d gebua
-sStructure only (no data)pg_dump -n geb -s -d gebua
-aData only (no structure)pg_dump -n geb -a -d gebua
-FcCustom format (recommended)pg_dump -n geb -Fc -f backup.dmp
-vVerbose outputpg_dump -n geb -v -d gebua
-OSkip object ownershippg_dump -n geb -O -d gebua

Contents



Important: Do not use the -n option during restore unless it is absolutely necessary.

When the -n option is used, PostgreSQL restores only the specified schema. However, if that schema does not already exist in the target database, the restore will fail even if the schema is present in the backup dump file.

If you decide to use the -n option to restore a single schema from either:

  • a multi-schema backup dump, or
  • a full database backup dump,

make sure you create the target schema before starting the restore. Otherwise, the restore will fail because pg_restore -n does not create the schema automatically.


0. Sample Data on Source


SCHEMA 1: GEB

[postgres@pgdb02 backup]$ psql -d gebua -c "SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL SELECT 'dept', COUNT(*) FROM geb.dept UNION ALL SELECT 'pgbench_accounts', COUNT(*) FROM geb.pgbench_accounts UNION ALL SELECT 'pgbench_branches', COUNT(*) FROM geb.pgbench_branches UNION ALL SELECT 'pgbench_history', COUNT(*) FROM geb.pgbench_history UNION ALL SELECT 'pgbench_tellers', COUNT(*) FROM geb.pgbench_tellers ORDER BY table_name;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@pgdb02 backup]$

SCHEMA 2: TRD
[postgres@pgdb02 backup]$ psql -d gebua -c "SELECT COUNT(*) FROM TRD.ORDERS;"
  count
---------
 1000001
(1 row)

[postgres@pgdb02 backup]$

1. Single Schema Backup/Restore

BACKUP on UAT:

[postgres@pgdb02 ~]$ cd /pgBackup/gebua/backup
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -n geb -Fc -v -f 01_task_gebua_geb_backup_binary.dmp > 01_task_gebua_geb_backup_binary.log 2>&1 &
[1] 4312
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 01_task_gebua_geb_backup_binary.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_tellers"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

[postgres@pgdb02 backup]$ scp 01_task_gebua_geb_backup_binary.dmp lxceftsgvdb01:/pgBackup/gebta/backup
01_task_gebua_geb_backup_binary.dmp 100% 54MB 62.4MB/s 00:00
[postgres@pgdb02 backup]$

RESTORE on SIT:

# Without Error

Note: Please don't use the '-n' option during restore. The restore will fail if the specified schema does not already exist in the target database, even if that schema is present in the backup dump file.

psql -d gebta -c "DROP SCHEMA geb CASCADE;"   
nohup pg_restore -d gebta -Fc -v 01_task_gebua_geb_backup_binary.dmp > 01_task_gebua_geb_backup_binary_restore.log 2>&1 &

[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fc -c -v 01_task_gebua_geb_backup_binary.dmp > 01_task_gebua_geb_backup_binary_restore.log 2>&1 &
[postgres@lxceftsgvdb01 backup]$ cat 01_task_gebua_geb_backup_binary_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: dropping CONSTRAINT pgbench_tellers pgbench_tellers_pkey
pg_restore: dropping CONSTRAINT pgbench_branches pgbench_branches_pkey
pg_restore: dropping CONSTRAINT pgbench_accounts pgbench_accounts_pkey
pg_restore: dropping CONSTRAINT dept dept_pkey
pg_restore: dropping TABLE pgbench_tellers
pg_restore: dropping TABLE pgbench_history
pg_restore: dropping TABLE pgbench_branches
pg_restore: dropping TABLE pgbench_accounts
pg_restore: dropping TABLE emp
pg_restore: dropping TABLE dept
pg_restore: dropping SCHEMA geb
pg_restore: creating SCHEMA "geb"
pg_restore: creating TABLE "geb.dept"
pg_restore: creating TABLE "geb.emp"
pg_restore: creating TABLE "geb.pgbench_accounts"
pg_restore: creating TABLE "geb.pgbench_branches"
pg_restore: creating TABLE "geb.pgbench_history"
pg_restore: creating TABLE "geb.pgbench_tellers"
pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: processing data for table "geb.pgbench_accounts"
pg_restore: processing data for table "geb.pgbench_branches"
pg_restore: processing data for table "geb.pgbench_history"
pg_restore: processing data for table "geb.pgbench_tellers"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "\dn;"
      List of schemas
  Name  |       Owner
--------+-------------------
 geb    | gebadm
 public | pg_database_owner
(2 rows)

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL SELECT 'dept', COUNT(*) FROM geb.dept UNION ALL SELECT 'pgbench_accounts', COUNT(*) FROM geb.pgbench_accounts UNION ALL SELECT 'pgbench_branches', COUNT(*) FROM geb.pgbench_branches UNION ALL SELECT 'pgbench_history', COUNT(*) FROM geb.pgbench_history UNION ALL SELECT 'pgbench_tellers', COUNT(*) FROM geb.pgbench_tellers ORDER BY table_name;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@lxceftsgvdb01 backup]$

2. Single Schema Backup/Restore(STRUCTURE ONLY + DATA BACKUP)

BACKUP on UAT:(BOTH STRUCTURE + DATA)

# Backup Structure
[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -n geb -Fc -s -v -f 02_task_gebua_geb_backup_structure.dmp > 02_task_gebua_geb_backup_structure.log 2>&1 &

[postgres@pgdb02 backup]$ cat 02_task_gebua_geb_backup_structure.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
[postgres@pgdb02 backup]$

# Backup Data only 
[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -n geb -Fc -a -v -f 03_task_gebua_geb_backup_data.dmp > 03_task_gebua_geb_backup_data.log 2>&1 &

[postgres@pgdb02 backup]$ cat 03_task_gebua_geb_backup_data.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_tellers"
[postgres@pgdb02 backup]$

TRANSFER to SIT:(BOTH STRUCTURE + DATA)

scp /pgBackup/gebua/backup/02_task_gebua_geb_backup_structure.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/
scp /pgBackup/gebua/backup/03_task_gebua_geb_backup_data.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/

RESTORE on SIT: (BOTH STRUCTURE + DATA)

psql -d gebua -c "DROP SCHEMA geb CASCADE;"

# Restore Structure
[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fc -c -v 02_task_gebua_geb_backup_structure.dmp > 02_task_gebua_geb_backup_structure_restore.log 2>&1 &

[postgres@lxceftsgvdb01 backup]$ cat 02_task_gebua_geb_backup_structure_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: dropping CONSTRAINT pgbench_tellers pgbench_tellers_pkey
pg_restore: dropping CONSTRAINT pgbench_branches pgbench_branches_pkey
pg_restore: dropping CONSTRAINT pgbench_accounts pgbench_accounts_pkey
pg_restore: dropping CONSTRAINT dept dept_pkey
pg_restore: dropping TABLE pgbench_tellers
pg_restore: dropping TABLE pgbench_history
pg_restore: dropping TABLE pgbench_branches
pg_restore: dropping TABLE pgbench_accounts
pg_restore: dropping TABLE emp
pg_restore: dropping TABLE dept
pg_restore: creating TABLE "geb.dept"
pg_restore: creating TABLE "geb.emp"
pg_restore: creating TABLE "geb.pgbench_accounts"
pg_restore: creating TABLE "geb.pgbench_branches"
pg_restore: creating TABLE "geb.pgbench_history"
pg_restore: creating TABLE "geb.pgbench_tellers"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$

# Restore Data
[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fc -a -v 03_task_gebua_geb_backup_data.dmp > 03_task_gebua_geb_backup_data_restore.log 2>&1 &

[postgres@lxceftsgvdb01 backup]$ cat 03_task_gebua_geb_backup_data_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: processing data for table "geb.pgbench_accounts"
pg_restore: processing data for table "geb.pgbench_branches"
pg_restore: processing data for table "geb.pgbench_history"
pg_restore: processing data for table "geb.pgbench_tellers"
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "\dn;"
      List of schemas
  Name  |       Owner
--------+-------------------
 geb    | gebadm
 public | pg_database_owner
(2 rows)

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL SELECT 'dept', COUNT(*) FROM geb.dept UNION ALL SELECT 'pgbench_accounts', COUNT(*) FROM geb.pgbench_accounts UNION ALL SELECT 'pgbench_branches', COUNT(*) FROM geb.pgbench_branches UNION ALL SELECT 'pgbench_history', COUNT(*) FROM geb.pgbench_history UNION ALL SELECT 'pgbench_tellers', COUNT(*) FROM geb.pgbench_tellers ORDER BY table_name;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@lxceftsgvdb01 backup]$

3. Multiple Schemas Backup/Restore

BACKUP on UAT:

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -n geb -n trd -Fc -v -f 04_task_gebua_geb_sales_backup_multi_schema.dmp > 04_task_gebua_geb_sales_backup_multi_schema.log 2>&1 &
[1] 4688
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 04_task_gebua_geb_sales_backup_multi_schema.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: finding table default expressions
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_tellers"
pg_dump: dumping contents of table "trd.orders"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

[postgres@pgdb02 backup]$ scp /pgBackup/gebua/backup/04_task_gebua_geb_sales_backup_multi_schema.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/
04_task_gebua_geb_sales_backup_multi_schema.dmp 100% 27MB 55.1MB/s 00:00
[postgres@pgdb02 backup]$

RESTORE on SIT:

# Without errors -- Manually 
psql -d gebua -c "DROP SCHEMA geb CASCADE; DROP SCHEMA sales CASCADE;"
nohup pg_restore -d gebta -Fc -v 04_task_gebua_geb_sales_backup_multi_schema.dmp > 04_task_gebua_geb_sales_backup_multi_schema_restore.log 2>&1 &

# Drop and recreate
[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fc -c -v 04_task_gebua_geb_sales_backup_multi_schema.dmp > 04_task_gebua_geb_sales_backup_multi_schema_restore.log 2>&1 &
[1] 4305
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 04_task_gebua_geb_sales_backup_multi_schema_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: dropping CONSTRAINT orders orders_pkey
pg_restore: dropping CONSTRAINT pgbench_tellers pgbench_tellers_pkey
pg_restore: dropping CONSTRAINT pgbench_branches pgbench_branches_pkey
pg_restore: dropping CONSTRAINT pgbench_accounts pgbench_accounts_pkey
pg_restore: dropping CONSTRAINT dept dept_pkey
pg_restore: dropping DEFAULT orders order_id
pg_restore: dropping SEQUENCE orders_order_id_seq
pg_restore: dropping TABLE orders
pg_restore: dropping TABLE pgbench_tellers
pg_restore: dropping TABLE pgbench_history
pg_restore: dropping TABLE pgbench_branches
pg_restore: dropping TABLE pgbench_accounts
pg_restore: dropping TABLE emp
pg_restore: dropping TABLE dept
pg_restore: dropping SCHEMA trd
pg_restore: dropping SCHEMA geb
pg_restore: creating SCHEMA "geb"
pg_restore: creating SCHEMA "trd"
pg_restore: creating TABLE "geb.dept"
pg_restore: creating TABLE "geb.emp"
pg_restore: creating TABLE "geb.pgbench_accounts"
pg_restore: creating TABLE "geb.pgbench_branches"
pg_restore: creating TABLE "geb.pgbench_history"
pg_restore: creating TABLE "geb.pgbench_tellers"
pg_restore: creating TABLE "trd.orders"
pg_restore: creating SEQUENCE "trd.orders_order_id_seq"
pg_restore: creating SEQUENCE OWNED BY "trd.orders_order_id_seq"
pg_restore: creating DEFAULT "trd.orders order_id"
pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: processing data for table "geb.pgbench_accounts"
pg_restore: processing data for table "geb.pgbench_branches"
pg_restore: processing data for table "geb.pgbench_history"
pg_restore: processing data for table "geb.pgbench_tellers"
pg_restore: processing data for table "trd.orders"
pg_restore: executing SEQUENCE SET orders_order_id_seq
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
pg_restore: creating CONSTRAINT "trd.orders orders_pkey"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "\dn;"
      List of schemas
  Name  |       Owner
--------+-------------------
 geb    | gebadm
 public | pg_database_owner
 trd    | trdadm
(3 rows)

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL SELECT 'dept', COUNT(*) FROM geb.dept UNION ALL SELECT 'pgbench_accounts', COUNT(*) FROM geb.pgbench_accounts UNION ALL SELECT 'pgbench_branches', COUNT(*) FROM geb.pgbench_branches UNION ALL SELECT 'pgbench_history', COUNT(*) FROM geb.pgbench_history UNION ALL SELECT 'pgbench_tellers', COUNT(*) FROM geb.pgbench_tellers ORDER BY table_name;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT COUNT(*) FROM TRD.ORDERS;"
  count
---------
 1000001
(1 row)

[postgres@lxceftsgvdb01 backup]$

4. Restore Single Schema from Multi-Schema Dump

[postgres@lxceftsgvdb01 ~]$ psql -d gebta
psql (17.10)
Type "help" for help.

gebta=# \dn
      List of schemas
  Name  |       Owner
--------+-------------------
 geb    | gebadm
 public | pg_database_owner
 trd    | trdadm
(3 rows)

gebta=# drop schema geb cascade;
NOTICE:  drop cascades to 6 other objects
DETAIL:  drop cascades to table geb.dept
drop cascades to table geb.emp
drop cascades to table geb.pgbench_accounts
drop cascades to table geb.pgbench_branches
drop cascades to table geb.pgbench_history
drop cascades to table geb.pgbench_tellers
DROP SCHEMA
gebta=#
gebta=# drop schema trd cascade;
NOTICE:  drop cascades to table trd.orders
DROP SCHEMA
gebta=#
gebta=# \dn
      List of schemas
  Name  |       Owner
--------+-------------------
 public | pg_database_owner
(1 row)

gebta=#


[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -n trd -Fc -v 04_task_gebua_geb_sales_backup_multi_schema.dmp > 04_task_gebua_sales_restore_single_from_multi.log 2>&1 &
[1] 3725
[postgres@lxceftsgvdb01 backup]$
[1]+ Exit 1 nohup pg_restore -d gebta -n trd -Fc -v 04_task_gebua_geb_sales_backup_multi_schema.dmp > 04_task_gebua_sales_restore_single_from_multi.log 2>&1
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 04_task_gebua_sales_restore_single_from_multi.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: creating TABLE "trd.orders"
pg_restore: while PROCESSING TOC:
pg_restore: from TOC entry 222; 1259 41085 TABLE orders trdadm
pg_restore: error: could not execute query: ERROR:  schema "trd" does not exist
LINE 1: CREATE TABLE trd.orders (
                     ^
Command was: CREATE TABLE trd.orders (
    order_id integer NOT NULL,
    product character varying(100),
    amount numeric(10,2)
);


pg_restore: error: could not execute query: ERROR:  schema "trd" does not exist
Command was: ALTER TABLE trd.orders OWNER TO trdadm;

pg_restore: creating SEQUENCE "trd.orders_order_id_seq"
pg_restore: from TOC entry 221; 1259 41084 SEQUENCE orders_order_id_seq trdadm
pg_restore: error: could not execute query: ERROR:  schema "trd" does not exist
Command was: CREATE SEQUENCE trd.orders_order_id_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;


pg_restore: error: could not execute query: ERROR:  schema "trd" does not exist
Command was: ALTER SEQUENCE trd.orders_order_id_seq OWNER TO trdadm;

pg_restore: creating SEQUENCE OWNED BY "trd.orders_order_id_seq"
pg_restore: from TOC entry 4386; 0 0 SEQUENCE OWNED BY orders_order_id_seq trdadm
pg_restore: error: could not execute query: ERROR:  schema "trd" does not exist
Command was: ALTER SEQUENCE trd.orders_order_id_seq OWNED BY trd.orders.order_id;


pg_restore: creating DEFAULT "trd.orders order_id"
pg_restore: from TOC entry 4216; 2604 41088 DEFAULT orders order_id trdadm
pg_restore: error: could not execute query: ERROR:  schema "trd" does not exist
Command was: ALTER TABLE ONLY trd.orders ALTER COLUMN order_id SET DEFAULT nextval('trd.orders_order_id_seq'::regclass);


pg_restore: processing data for table "trd.orders"
pg_restore: from TOC entry 4375; 0 41085 TABLE DATA orders trdadm
pg_restore: error: could not execute query: ERROR:  schema "trd" does not exist
Command was: COPY trd.orders (order_id, product, amount) FROM stdin;
pg_restore: executing SEQUENCE SET orders_order_id_seq
pg_restore: from TOC entry 4387; 0 0 SEQUENCE SET orders_order_id_seq trdadm
pg_restore: error: could not execute query: ERROR:  relation "trd.orders_order_id_seq" does not exist
LINE 1: SELECT pg_catalog.setval('trd.orders_order_id_seq', 1000001,...
                                 ^
Command was: SELECT pg_catalog.setval('trd.orders_order_id_seq', 1000001, true);


pg_restore: creating CONSTRAINT "trd.orders orders_pkey"
pg_restore: from TOC entry 4220; 2606 41090 CONSTRAINT orders orders_pkey trdadm
pg_restore: error: could not execute query: ERROR:  schema "trd" does not exist
Command was: ALTER TABLE ONLY trd.orders
    ADD CONSTRAINT orders_pkey PRIMARY KEY (order_id);


pg_restore: warning: errors ignored on restore: 9
[postgres@lxceftsgvdb01 backup]$



Issue : If the target schema does not already exist in your destination database, pg_restore will throw an error because it does not automatically create the schema container when filtering with the -n flag.

Solution: # CREATE SCHEMA FIRST THEN TRIGGER RESTORE

# CREATE SCHEMA 
gebta=# CREATE SCHEMA TRD;
CREATE SCHEMA
gebta=#

gebta=# ALTER SCHEMA TRD OWNER TO TRDADM; 
ALTER SCHEMA 
gebta=# 

# Restore singel schema 'trd' from multi schema dump file

[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -n trd -Fc -v 04_task_gebua_geb_sales_backup_multi_schema.dmp > 04_task_gebua_sales_restore_single_from_multi.log 2>&1 &
[1] 3752
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 04_task_gebua_sales_restore_single_from_multi.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: creating TABLE "trd.orders"
pg_restore: creating SEQUENCE "trd.orders_order_id_seq"
pg_restore: creating SEQUENCE OWNED BY "trd.orders_order_id_seq"
pg_restore: creating DEFAULT "trd.orders order_id"
pg_restore: processing data for table "trd.orders"
pg_restore: executing SEQUENCE SET orders_order_id_seq
pg_restore: creating CONSTRAINT "trd.orders orders_pkey"
[postgres@lxceftsgvdb01 backup]$

Note: ALTER SCHEMA OWNER is optional. If the original schema owner does not exist on the target database, you can use the --no-owner option during restore to skip restoring object ownership. 

5. Restore Single Schema from Full Database Dump

BACKUP on UAT:

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -Fc -v -f 02_task_gebua_full_backup_binary.dmp > 02_task_gebua_full_backup_binary.log 2>&1 &
[1] 4737
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 02_task_gebua_full_backup_binary.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: finding table default expressions
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading large objects
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_tellers"
pg_dump: dumping contents of table "trd.orders"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

scp /pgBackup/gebua/backup/02_task_gebua_full_backup_binary.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/

RESTORE on SIT:Β 

If the target schema does not already exist in your destination database, pg_restore will throw an error because it does not automatically create the schema container when filtering with the -n flag.

# Cleanup

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "DROP SCHEMA trd CASCADE;"
NOTICE: drop cascades to table trd.orders
DROP SCHEMA
[postgres@lxceftsgvdb01 backup]$

# Restore
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "CREATE SCHEMA trd;"
CREATE SCHEMA
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "ALTER SCHEMA TRD OWNER TO TRDADM;"
ALTER SCHEMA
[postgres@lxceftsgvdb01 backup]$

# I will remove '-c' flag
[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -n trd -Fc -v 02_task_gebua_full_backup_binary.dmp > 02_task_gebua_full_backup_binary_restore.log 2>&1 &
[1] 3814
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 02_task_gebua_full_backup_binary_restore.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: creating TABLE "trd.orders"
pg_restore: creating SEQUENCE "trd.orders_order_id_seq"
pg_restore: creating SEQUENCE OWNED BY "trd.orders_order_id_seq"
pg_restore: creating DEFAULT "trd.orders order_id"
pg_restore: processing data for table "trd.orders"
pg_restore: executing SEQUENCE SET orders_order_id_seq
pg_restore: creating CONSTRAINT "trd.orders orders_pkey"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "\dn;"
      List of schemas
  Name  |       Owner
--------+-------------------
 public | pg_database_owner
 trd    | trdadm
(2 rows)

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "select count(*) from trd.orders;"
  count
---------
 1000001  <--------------
(1 row)

[postgres@lxceftsgvdb01 backup]$

6. List Dump Contents

#  List dumps
pg_restore -l 02_task_gebua_full_backup_binary.dmp

[postgres@lxceftsgvdb01 backup]$ pg_restore -l 02_task_gebua_full_backup_binary.dmp
;
; Archive created at 2026-07-15 20:46:43 +08
;     dbname: gebua
;     TOC Entries: 29
;     Compression: gzip
;     Dump Version: 1.16-0
;     Format: CUSTOM
;     Integer: 4 bytes
;     Offset: 8 bytes
;     Dumped from database version: 17.10
;     Dumped by pg_dump version: 17.10
;
;
; Selected TOC Entries:
;
6; 2615 32843 SCHEMA - geb gebadm
7; 2615 41083 SCHEMA - trd trdadm
220; 1259 32849 TABLE geb dept gebadm
219; 1259 32844 TABLE geb emp gebadm
225; 1259 41097 TABLE geb pgbench_accounts gebadm
226; 1259 41100 TABLE geb pgbench_branches gebadm
223; 1259 41091 TABLE geb pgbench_history gebadm
224; 1259 41094 TABLE geb pgbench_tellers gebadm
222; 1259 41085 TABLE trd orders trdadm
221; 1259 41084 SEQUENCE trd orders_order_id_seq trdadm
4386; 0 0 SEQUENCE OWNED BY trd orders_order_id_seq trdadm
4216; 2604 41088 DEFAULT trd orders order_id trdadm
4373; 0 32849 TABLE DATA geb dept gebadm
4372; 0 32844 TABLE DATA geb emp gebadm
4378; 0 41097 TABLE DATA geb pgbench_accounts gebadm
4379; 0 41100 TABLE DATA geb pgbench_branches gebadm
4376; 0 41091 TABLE DATA geb pgbench_history gebadm
4377; 0 41094 TABLE DATA geb pgbench_tellers gebadm
4375; 0 41085 TABLE DATA trd orders trdadm
4387; 0 0 SEQUENCE SET trd orders_order_id_seq trdadm
4218; 2606 32853 CONSTRAINT geb dept dept_pkey gebadm
4224; 2606 41112 CONSTRAINT geb pgbench_accounts pgbench_accounts_pkey gebadm
4226; 2606 41108 CONSTRAINT geb pgbench_branches pgbench_branches_pkey gebadm
4222; 2606 41110 CONSTRAINT geb pgbench_tellers pgbench_tellers_pkey gebadm
4220; 2606 41090 CONSTRAINT trd orders orders_pkey trdadm
[postgres@lxceftsgvdb01 backup]$

# Extract only object definitions (Schema Only)
pg_restore -s -f schema.sql 02_task_gebua_full_backup_binary.dmp

# Extract the dump into SQL (extract DDL and data)
pg_restore -f backup.sql 02_task_gebua_full_backup_binary.dmp

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

pg_dump – Database-Level Backup & Restore

pg_dump – Database Backup & Restore (UAT β†’ SIT Migration)

ItemUAT (Source)SIT (Target)
Database Namegebuagebta
Server/Hostpgdb02 / 192.168.2.23lxceftsgvdb01 / 192.168.2.21
Data Tablespace (default tablespace)ts_data_uatts_data_sit
Backup Path/pgBackup/gebua/backup/pgBackup/gebta/backup
FormatExtension
Plain TextΒ  Β (-Fp).sql
CustomΒ  Β  Β  (-Fc).dmp or .bin
TarΒ  Β  Β  Β  Β  Β  Β  Β (-Ft).tar
DirectoryΒ  Β (-Fd)(folder)Β  Β — Can run in parallel using -j2 (2workers)

Contents



1. UAT Environment Setup (Source)

Set up the source database in UAT (GEBUA – 192.168.2.23).

Create Database & Schema in UAT:

-- Connect as superuser
[postgres@pgdb02 ~]$ psql
psql (17.10)
Type "help" for help.

postgres=# \c
You are now connected to database "postgres" as user "postgres".
postgres=#

-- Create tablespace 

mkdir -p /pgTBS/tsdata/ts_data_uat

postgres=# CREATE TABLESPACE ts_data_uat LOCATION '/pgTBS/tsdata/ts_data_uat';
CREATE TABLESPACE


-- Create user
postgres=# CREATE USER gebadm WITH PASSWORD 'gebadm123';
CREATE ROLE
postgres=#
-- Create database
postgres=# CREATE DATABASE gebua tablespace ts_data_uat;
CREATE DATABASE
postgres=# 

-- Create schema
postgres=# \c gebua
You are now connected to database "gebua" as user "postgres".
gebua=#

gebua=# CREATE SCHEMA geb AUTHORIZATION gebadm;
CREATE SCHEMA
gebua=#

-- Create tables
gebua=# \c gebua gebadm
You are now connected to database "gebua" as user "gebadm".
gebua=>
gebua=> CREATE TABLE geb.emp (name TEXT, designation TEXT, project TEXT, company TEXT);
CREATE TABLE
gebua=> INSERT INTO geb.emp VALUES ('Sugi', 'DBA', 'Jetstar', 'iGATE');
INSERT 0 1
gebua=> INSERT INTO geb.emp VALUES ('Teja', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
gebua=> INSERT INTO geb.emp VALUES ('RAJ', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
gebua=>
gebua=> CREATE TABLE geb.dept ( dept_id INT PRIMARY KEY, dept_name VARCHAR(100) NOT NULL, location VARCHAR(50), manager VARCHAR(100) );
CREATE TABLE
gebua=> INSERT INTO geb.dept VALUES
(1, 'Engineering', 'Vijayawada', 'Ravi'),
(2, 'Sales', 'Visakhapatnam', 'Sai Krishna'),
(3, 'HR', 'Rajahmundry', 'Anusha'),
(4, 'Finance', 'Nellore', 'Archana'),
(5, 'Operations', 'Anantapur', 'Harika');
INSERT 0 5
gebua=>
gebua=> \dt geb.*
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+--------
 geb    | dept | table | gebadm
 geb    | emp  | table | gebadm
(2 rows)

gebua=> SELECT COUNT(*) FROM geb.emp;
 count
-------
     3   <------
(1 row)

gebua=> SELECT COUNT(*) FROM geb.dept;
 count
-------
     5 <------
(1 row)

gebua=>

Setup Backup Directory in UAT:

mkdir -p /pgBackup/gebua/backup
chown postgres:postgres /pgBackup/gebua/backup
chmod 755 /pgBackup/gebua/backup

2. SIT Environment Setup (Target)

Set up the target database infrastructure in SIT (GEBTA – 192.168.2.21).

Create Database & Schema in SIT:

-- Connect as superuser on SIT
[postgres@lxceftsgvdb01 ~]$ psql
psql (17.10)
Type "help" for help.

postgres=#


-- Create tablespaces (ensure directories exist)
mkdir -p /pgTBS/tsdata/ts_data_sit

postgres=# CREATE TABLESPACE ts_data_sit LOCATION '/pgTBS/tsdata/ts_data_sit';
CREATE TABLESPACE
postgres=#

-- Create empty database
CREATE DATABASE gebta tablespace ts_data_sit;

-- Create user
CREATE USER gebadm WITH PASSWORD 'gebadm';

-- Connect as superuser
\c gebta postgres

-- Create schema
CREATE SCHEMA geb AUTHORIZATION gebadm;

-- Verify
\dn geb

Setup Backup Directory in SIT:

mkdir -p /pgBackup/gebta/backup
chown postgres:postgres /pgBackup/gebta/backup
chmod 755 /pgBackup/gebta/backup

3. Sample Data in UAT

Insert sample data in UAT that will be backed up and restored to SIT.

postgres=# ALTER ROLE gebadm SET search_path = geb;
ALTER ROLE
postgres=#

[postgres@pgdb02 ~]$ pgbench -i -s 100 -U gebadm gebua
dropping old tables...
NOTICE: table "pgbench_accounts" does not exist, skipping
NOTICE: table "pgbench_branches" does not exist, skipping
NOTICE: table "pgbench_history" does not exist, skipping
NOTICE: table "pgbench_tellers" does not exist, skipping
creating tables...
generating data (client-side)...
vacuuming...
creating primary keys...
done in 41.90 s (drop tables 0.00 s, create tables 0.02 s, client-side generate 28.47 s, vacuum 1.59 s, primary keys 11.81 s).
[postgres@pgdb02 ~]$

gebua=# \dt+ geb.*
                                          List of relations
 Schema |       Name       | Type  | Owner  | Persistence | Access method |    Size    | Description
--------+------------------+-------+--------+-------------+---------------+------------+-------------
 geb    | dept             | table | gebadm | permanent   | heap          | 8192 bytes |
 geb    | emp              | table | gebadm | permanent   | heap          | 16 kB      |
 geb    | pgbench_accounts | table | gebadm | permanent   | heap          | 1281 MB    |
 geb    | pgbench_branches | table | gebadm | permanent   | heap          | 40 kB      |
 geb    | pgbench_history  | table | gebadm | permanent   | heap          | 0 bytes    |
 geb    | pgbench_tellers  | table | gebadm | permanent   | heap          | 80 kB      |
(6 rows)

gebua=#

[postgres@pgdb02 backup]$ psql -d gebua -c "SELECT 'dept' AS table_name, COUNT(*) AS row_count FROM geb.dept UNION ALL
SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL
SELECT 'pgbench_accounts' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_accounts UNION ALL
SELECT 'pgbench_branches' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_branches UNION ALL
SELECT 'pgbench_history' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_history UNION ALL
SELECT 'pgbench_tellers' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_tellers;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@pgdb02 backup]$ 

4. Backup & Restore (All Formats)

4.1 Plain Text (SQL) Format

BACKUP on UAT:

-- Execute on UAT (192.168.2.23) as postgres user
cd /pgBackup/gebua/backup

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -Fp -v -f 01_task_gebua_full_backup_sql.sql 2>01_task_gebua_full_backup_sql.log &
[1] 3786
[postgres@pgdb02 backup]$
[postgres@pgdb02 backup]$ jobs -l
[1]+ 3786 Done nohup pg_dump -d gebua -Fp -v -f 01_task_gebua_full_backup_sql.sql 2> 01_task_gebua_full_backup_sql.log
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 01_task_gebua_full_backup_sql.log
nohup: ignoring input and appending output to 'nohup.out'
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading large objects
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: creating SCHEMA "geb"
pg_dump: creating TABLE "geb.dept"
pg_dump: creating TABLE "geb.emp"
pg_dump: creating TABLE "geb.pgbench_accounts"
pg_dump: creating TABLE "geb.pgbench_branches"
pg_dump: creating TABLE "geb.pgbench_history"
pg_dump: creating TABLE "geb.pgbench_tellers"
pg_dump: processing data for table "geb.dept"
pg_dump: dumping contents of table "geb.dept"
pg_dump: processing data for table "geb.emp"
pg_dump: dumping contents of table "geb.emp"
pg_dump: processing data for table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: processing data for table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: processing data for table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: processing data for table "geb.pgbench_tellers"
pg_dump: dumping contents of table "geb.pgbench_tellers"
pg_dump: creating CONSTRAINT "geb.dept dept_pkey"
pg_dump: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_dump: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_dump: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

-- Execute on UAT server
scp /pgBackup/gebua/backup/01_task_gebua_full_backup_sql.sql postgres@192.168.2.21:/pgBackup/gebta/backup/

RESTORE on SIT:

-- Execute on SIT (192.168.2.21) as postgres user
cd /pgBackup/gebta/backup

-- 1. Block normal users
SELECT datname, datconnlimit FROM pg_database WHERE datname = 'gebta';
ALTER DATABASE gebta CONNECTION LIMIT 0;

-- 2. Disconnect normal users
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'gebta' AND usename <> 'postgres';

-- 3. Restore from SQL

-- 4. Restore the original connection limit (unlimited) 
ALTER DATABASE gebta CONNECTION LIMIT -1;

postgres=# \c gebta
You are now connected to database "gebta" as user "postgres".
gebta=#
gebta=# drop schema geb cascade;
NOTICE: drop cascades to 7 other objects
DETAIL: drop cascades to table geb.dept
drop cascades to table geb.emp
drop cascades to table geb.hr
drop cascades to table geb.pgbench_accounts
drop cascades to table geb.pgbench_branches
drop cascades to table geb.pgbench_history
drop cascades to table geb.pgbench_tellers
DROP SCHEMA
gebta=#

[postgres@lxceftsgvdb01 backup]$ nohup psql -d gebta -f 01_task_gebua_full_backup_sql.sql > 01_task_gebua_full_restore_sql.log 2>&1 &
[1] 3693
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ jobs -l
[1]+ 3693 Running nohup psql -d gebta -f 01_task_gebua_full_backup_sql.sql > 01_task_gebua_full_restore_sql.log 2>&1 &
[postgres@lxceftsgvdb01 backup]$
[1]+ Done nohup psql -d gebta -f 01_task_gebua_full_backup_sql.sql > 01_task_gebua_full_restore_sql.log 2>&1
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 01_task_gebua_full_restore_sql.log
nohup: ignoring input
SET
SET
SET
SET
SET
SET
 set_config
------------

(1 row)

SET
SET
SET
SET
CREATE SCHEMA
ALTER SCHEMA
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
COPY 5
COPY 3
COPY 10000000
COPY 100
COPY 0
COPY 1000
ALTER TABLE
ALTER TABLE
ALTER TABLE
ALTER TABLE
[postgres@lxceftsgvdb01 backup]$

--- Verify 

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT 'dept' AS table_name, COUNT(*) AS row_count FROM geb.dept UNION ALL
SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL
SELECT 'pgbench_accounts' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_accounts UNION ALL
SELECT 'pgbench_branches' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_branches UNION ALL
SELECT 'pgbench_history' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_history UNION ALL
SELECT 'pgbench_tellers' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_tellers;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@lxceftsgvdb01 backup]$

4.2 Custom (DMP) Format – RECOMMENDED

BACKUP on UAT:

-- Execute on UAT (192.168.2.23) as postgres user
cd /pgBackup/gebua/backup

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -Fc -v -f 02_task_gebua_full_backup_binary.dmp > 02_task_gebua_full_backup_binary.log 2>&1 &
[1] 3866
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 02_task_gebua_full_backup_binary.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading large objects
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_tellers"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

-- Execute on UAT server
scp /pgBackup/gebua/backup/02_task_gebua_full_backup_binary.dmp postgres@192.168.2.21:/pgBackup/gebta/backup/

RESTORE on SIT:

-- Execute on SIT (192.168.2.21) as postgres user
cd /pgBackup/gebta/backup

-- 1. Block normal users
SELECT datname, datconnlimit FROM pg_database WHERE datname = 'gebta';
ALTER DATABASE gebta CONNECTION LIMIT 0;

-- 2. Disconnect normal users
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'gebta' AND usename <> 'postgres';

-- 3. Restore from DMP
nohup pg_restore -d gebta -Fc -c -v 02_task_gebua_full_backup_binary.dmp > 02_task_gebua_full_restore_binary.log 2>&1 &

-- 4. Restore the original connection limit (unlimited) 
ALTER DATABASE gebta CONNECTION LIMIT -1

-- Restore from DMP
[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fc -c -v 02_task_gebua_full_backup_binary.dmp > 02_task_gebua_full_restore_binary.log 2>&1 &
[1] 3768
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 02_task_gebua_full_restore_binary.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: dropping CONSTRAINT pgbench_tellers pgbench_tellers_pkey
pg_restore: dropping CONSTRAINT pgbench_branches pgbench_branches_pkey
pg_restore: dropping CONSTRAINT pgbench_accounts pgbench_accounts_pkey
pg_restore: dropping CONSTRAINT dept dept_pkey
pg_restore: dropping TABLE pgbench_tellers
pg_restore: dropping TABLE pgbench_history
pg_restore: dropping TABLE pgbench_branches
pg_restore: dropping TABLE pgbench_accounts
pg_restore: dropping TABLE emp
pg_restore: dropping TABLE dept
pg_restore: dropping SCHEMA geb
pg_restore: creating SCHEMA "geb"
pg_restore: creating TABLE "geb.dept"
pg_restore: creating TABLE "geb.emp"
pg_restore: creating TABLE "geb.pgbench_accounts"
pg_restore: creating TABLE "geb.pgbench_branches"
pg_restore: creating TABLE "geb.pgbench_history"
pg_restore: creating TABLE "geb.pgbench_tellers"
pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: processing data for table "geb.pgbench_accounts"
pg_restore: processing data for table "geb.pgbench_branches"
pg_restore: processing data for table "geb.pgbench_history"
pg_restore: processing data for table "geb.pgbench_tellers"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
[postgres@lxceftsgvdb01 backup]$

-- Verify
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT 'dept' AS table_name, COUNT(*) AS row_count FROM geb.dept UNION ALL
SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL
SELECT 'pgbench_accounts' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_accounts UNION ALL
SELECT 'pgbench_branches' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_branches UNION ALL
SELECT 'pgbench_history' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_history UNION ALL
SELECT 'pgbench_tellers' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_tellers;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@lxceftsgvdb01 backup]$

4.3 Tar Format

BACKUP on UAT:

-- Execute on SIT (192.168.2.21) as postgres user
cd /pgBackup/gebta/backup

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -Ft -v -f 03_task_gebua_full_backup_binary.tar > 03_task_gebua_full_backup_tar.log 2>&1 &
[1] 3896
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 03_task_gebua_full_backup_tar.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading large objects
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_tellers"
pg_dump: dropping DATABASE PROPERTIES gebua
pg_dump: dropping DATABASE gebua
pg_dump: creating DATABASE "gebua"
pg_dump: connecting to new database "gebua"
pg_dump: creating DATABASE PROPERTIES "gebua"
pg_dump: connecting to new database "gebua"
pg_dump: creating SCHEMA "geb"
pg_dump: creating TABLE "geb.dept"
pg_dump: creating TABLE "geb.emp"
pg_dump: creating TABLE "geb.pgbench_accounts"
pg_dump: creating TABLE "geb.pgbench_branches"
pg_dump: creating TABLE "geb.pgbench_history"
pg_dump: creating TABLE "geb.pgbench_tellers"
pg_dump: processing data for table "geb.dept"
pg_dump: processing data for table "geb.emp"
pg_dump: processing data for table "geb.pgbench_accounts"
pg_dump: processing data for table "geb.pgbench_branches"
pg_dump: processing data for table "geb.pgbench_history"
pg_dump: processing data for table "geb.pgbench_tellers"
pg_dump: creating CONSTRAINT "geb.dept dept_pkey"
pg_dump: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_dump: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_dump: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
[postgres@pgdb02 backup]$

TRANSFER to SIT:

-- Execute on UAT server
scp /pgBackup/gebua/backup/03_task_gebua_full_backup_binary.tar postgres@192.168.2.21:/pgBackup/gebta/backup/

RESTORE on SIT:

-- Execute on SIT (192.168.2.21) as postgres user
cd /pgBackup/gebta/backup

-- 1. Block normal users
SELECT datname, datconnlimit FROM pg_database WHERE datname = 'gebta';
ALTER DATABASE gebta CONNECTION LIMIT 0;

-- 2. Disconnect normal users
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'gebta' AND usename <> 'postgres';

-- 3. Restore from TAR
nohup pg_restore -d gebta -Ft -c -v 03_task_gebua_full_backup_binary.tar > 03_task_gebua_full_restore_tar.log 2>&1 &

-- 4. Restore the original connection limit (unlimited) 
ALTER DATABASE gebta CONNECTION LIMIT -1


[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Ft -c -v 03_task_gebua_full_backup_binary.tar > 03_task_gebua_full_restore_tar.log 2>&1 &
[1] 3811
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ cat 03_task_gebua_full_restore_tar.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: dropping CONSTRAINT pgbench_tellers pgbench_tellers_pkey
pg_restore: dropping CONSTRAINT pgbench_branches pgbench_branches_pkey
pg_restore: dropping CONSTRAINT pgbench_accounts pgbench_accounts_pkey
pg_restore: dropping CONSTRAINT dept dept_pkey
pg_restore: dropping TABLE pgbench_tellers
pg_restore: dropping TABLE pgbench_history
pg_restore: dropping TABLE pgbench_branches
pg_restore: dropping TABLE pgbench_accounts
pg_restore: dropping TABLE emp
pg_restore: dropping TABLE dept
pg_restore: dropping SCHEMA geb
pg_restore: creating SCHEMA "geb"
pg_restore: creating TABLE "geb.dept"
pg_restore: creating TABLE "geb.emp"
pg_restore: creating TABLE "geb.pgbench_accounts"
pg_restore: creating TABLE "geb.pgbench_branches"
pg_restore: creating TABLE "geb.pgbench_history"
pg_restore: creating TABLE "geb.pgbench_tellers"
pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: processing data for table "geb.pgbench_accounts"
pg_restore: processing data for table "geb.pgbench_branches"
pg_restore: processing data for table "geb.pgbench_history"
pg_restore: processing data for table "geb.pgbench_tellers"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
[postgres@lxceftsgvdb01 backup]$

[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT 'dept' AS table_name, COUNT(*) AS row_count FROM geb.dept UNION ALL
SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL
SELECT 'pgbench_accounts' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_accounts UNION ALL
SELECT 'pgbench_branches' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_branches UNION ALL
SELECT 'pgbench_history' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_history UNION ALL
SELECT 'pgbench_tellers' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_tellers;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@lxceftsgvdb01 backup]$

4.4 Directory Format

BACKUP on UAT:

-- Execute on UAT (192.168.2.23) as postgres user
cd /pgBackup/gebua/backup

nohup pg_dump -d gebua -Fd -v -f 04_task_gebua_full_backup_directory > 04_task_gebua_full_backup_directory.log 2>&1 &   <---- Without parallel
nohup pg_dump -d gebua -Fd -v -j2 -f 04_task_gebua_full_backup_directory_01 > 04_task_gebua_full_backup_directory_01.log 2>&1 &  <---- with parallel

**** directory 04_task_gebua_full_backup_directory  will be created automatically by pg_dump -Fd  *********

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -Fd -v -f 04_task_gebua_full_backup_directory > 04_task_gebua_full_backup_directory.log 2>&1 &
[1] 3927
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ ls -l /pgBackup/gebua/backup/04_task_gebua_full_backup_directory
total 27468
-rw-r--r--. 1 postgres postgres 63 Jul 14 14:53 4363.dat.gz
-rw-r--r--. 1 postgres postgres 145 Jul 14 14:53 4364.dat.gz
-rw-r--r--. 1 postgres postgres 25 Jul 14 14:53 4365.dat.gz
-rw-r--r--. 1 postgres postgres 1774 Jul 14 14:53 4366.dat.gz
-rw-r--r--. 1 postgres postgres 28095689 Jul 14 14:53 4367.dat.gz
-rw-r--r--. 1 postgres postgres 208 Jul 14 14:53 4368.dat.gz
-rw-r--r--. 1 postgres postgres 5660 Jul 14 14:53 toc.dat
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ cat 04_task_gebua_full_backup_directory.log
nohup: ignoring input
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading large objects
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "geb.dept"
pg_dump: dumping contents of table "geb.emp"
pg_dump: dumping contents of table "geb.pgbench_accounts"
pg_dump: dumping contents of table "geb.pgbench_branches"
pg_dump: dumping contents of table "geb.pgbench_history"
pg_dump: dumping contents of table "geb.pgbench_tellers"
[postgres@pgdb02 backup]$


with Parallel -j6

[postgres@pgdb02 backup]$ nohup pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01 > 05_task_gebua_full_backup_directory_01.log 2>&1 &
[1] 3851
[postgres@pgdb02 backup]$
[postgres@pgdb02 backup]$ jobs -l
[1]+ 3851 Running nohup pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01 > 05_task_gebua_full_backup_directory_01.log 2>&1 &
[postgres@pgdb02 backup]$
[postgres@pgdb02 backup]$ ps -ef | grep postgres
root 3276 3198 0 14:57 pts/0 00:00:00 su - postgres
postgres 3277 3276 0 14:57 pts/0 00:00:00 -bash
postgres 3341 1 0 14:57 ? 00:00:00 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data
postgres 3342 3341 0 14:57 ? 00:00:00 postgres: logger
postgres 3343 3341 0 14:57 ? 00:00:00 postgres: checkpointer
postgres 3344 3341 0 14:57 ? 00:00:00 postgres: background writer
postgres 3347 3341 0 14:57 ? 00:00:01 postgres: walwriter
postgres 3348 3341 0 14:57 ? 00:00:00 postgres: autovacuum launcher
postgres 3349 3341 0 14:57 ? 00:00:00 postgres: logical replication launcher
postgres 3851 3277 0 17:39 pts/0 00:00:00 pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01
postgres 3852 3341 1 17:39 ? 00:00:00 postgres: postgres gebua [local] idle in transaction
postgres 3853 3851 58 17:39 pts/0 00:00:04 pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01
postgres 3854 3851 0 17:39 pts/0 00:00:00 pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01
postgres 3855 3341 0 17:39 ? 00:00:00 postgres: postgres gebua [local] idle in transaction
postgres 3856 3851 0 17:39 pts/0 00:00:00 pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01
postgres 3857 3851 0 17:39 pts/0 00:00:00 pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01
postgres 3858 3341 32 17:39 ? 00:00:02 postgres: postgres gebua [local] COPY
postgres 3859 3851 0 17:39 pts/0 00:00:00 pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01
postgres 3860 3341 0 17:39 ? 00:00:00 postgres: postgres gebua [local] idle in transaction
postgres 3861 3851 0 17:39 pts/0 00:00:00 pg_dump -d gebua -Fd -v -j6 -f 05_task_gebua_full_backup_directory_01
postgres 3862 3341 0 17:39 ? 00:00:00 postgres: postgres gebua [local] idle in transaction
postgres 3863 3341 0 17:39 ? 00:00:00 postgres: postgres gebua [local] idle in transaction
postgres 3864 3341 0 17:39 ? 00:00:00 postgres: postgres gebua [local] idle in transaction
postgres 3865 3277 0 17:39 pts/0 00:00:00 ps -ef
postgres 3866 3277 0 17:39 pts/0 00:00:00 grep --color=auto postgres
[postgres@pgdb02 backup]$

[postgres@pgdb02 backup]$ pstree -p 3851 
pg_dump(3851)─┬─pg_dump(3853)
              β”œβ”€pg_dump(3854)
              β”œβ”€pg_dump(3856)
              β”œβ”€pg_dump(3857)
              β”œβ”€pg_dump(3859)
              └─pg_dump(3861)
[postgres@pgdb02 backup]$


3851 --- Master , Rest all workers

TRANSFER to SIT:

-- Execute on UAT server
scp -r /pgBackup/gebua/backup/04_task_gebua_full_backup_directory postgres@192.168.2.21:/pgBackup/gebta/backup/

RESTORE on SIT:

-- Execute on SIT (192.168.2.21) as postgres user
cd /pgBackup/gebta/backup

-- 1. Block normal users
SELECT datname, datconnlimit FROM pg_database WHERE datname = 'gebta';
ALTER DATABASE gebta CONNECTION LIMIT 0;

-- 2. Disconnect normal users
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'gebta' AND usename <> 'postgres';

-- 3. Restore from directory
nohup pg_restore -d gebta -Fd -c -v 04_task_gebua_full_backup_directory > 04_task_gebua_full_restore_directory.log 2>&1 &

-- 4. Restore the original connection limit (unlimited) 
ALTER DATABASE gebta CONNECTION LIMIT -1


[postgres@lxceftsgvdb01 backup]$ nohup pg_restore -d gebta -Fd -c -v 04_task_gebua_full_backup_directory > 04_task_gebua_full_restore_directory.log 2>&1 &
[1] 3909
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ cat 04_task_gebua_full_restore_directory.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: dropping CONSTRAINT pgbench_tellers pgbench_tellers_pkey
pg_restore: dropping CONSTRAINT pgbench_branches pgbench_branches_pkey
pg_restore: dropping CONSTRAINT pgbench_accounts pgbench_accounts_pkey
pg_restore: dropping CONSTRAINT dept dept_pkey
pg_restore: dropping TABLE pgbench_tellers
pg_restore: dropping TABLE pgbench_history
pg_restore: dropping TABLE pgbench_branches
pg_restore: dropping TABLE pgbench_accounts
pg_restore: dropping TABLE emp
pg_restore: dropping TABLE dept
pg_restore: dropping SCHEMA geb
pg_restore: creating SCHEMA "geb"
pg_restore: creating TABLE "geb.dept"
pg_restore: creating TABLE "geb.emp"
pg_restore: creating TABLE "geb.pgbench_accounts"
pg_restore: creating TABLE "geb.pgbench_branches"
pg_restore: creating TABLE "geb.pgbench_history"
pg_restore: creating TABLE "geb.pgbench_tellers"
pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: processing data for table "geb.pgbench_accounts"
pg_restore: processing data for table "geb.pgbench_branches"
pg_restore: processing data for table "geb.pgbench_history"
pg_restore: processing data for table "geb.pgbench_tellers"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ psql -d gebta -c "SELECT 'dept' AS table_name, COUNT(*) AS row_count FROM geb.dept UNION ALL
SELECT 'emp' AS table_name, COUNT(*) AS row_count FROM geb.emp UNION ALL
SELECT 'pgbench_accounts' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_accounts UNION ALL
SELECT 'pgbench_branches' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_branches UNION ALL
SELECT 'pgbench_history' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_history UNION ALL
SELECT 'pgbench_tellers' AS table_name, COUNT(*) AS row_count FROM geb.pgbench_tellers;"
    table_name    | row_count
------------------+-----------
 dept             |         5
 emp              |         3
 pgbench_accounts |  10000000
 pgbench_branches |       100
 pgbench_history  |         0
 pgbench_tellers  |      1000
(6 rows)

[postgres@lxceftsgvdb01 backup]$

5. Restore database with –no-owner and –no-tablespaces

You need to restore a PostgreSQL database when:

  • The source database owner does not exist on the target PostgreSQL server.
  • Some tables in the source database are stored in tablespaces other than the database’s default tablespace, and those tablespaces do not exist on the target server.

postgres=# CREATE TABLESPACE ts_data_uat LOCATION ‘/pgTBS/tsdata/ts_data_uat’;
CREATE TABLESPACE
postgres=# CREATE TABLESPACE ts_data_uat2 LOCATION ‘/pgTBS/tsdata/ts_data_uat2’;
CREATE TABLESPACE
postgres=#
postgres=# CREATE DATABASE gebua tablespace ts_data_uat;
CREATE DATABASE
postgres=#

CREATE TABLE geb.hr(emp_id int, emp_name varchar) TABLESPACE ts_data_uat2;Β  <— geb.hr table created in tablespaces other than the database’s default tablespace

For example, the source database contains the GEB schema owned by GEBADM, but the GEBADM role does not exist on the target PostgreSQL instance. In addition, several tables are located in custom tablespaces.

If you perform a normal restore, PostgreSQL report errors because it cannot assign ownership to a role that does not exist or create objects in tablespaces that are unavailable on the target server. However, the database objects and data are still restored successfully. The restored schema is owned by the user performing the restore (for example, postgres), and all objects are created in the target database’s default tablespace.

To avoid these problems, restore the database using the --no-owner and --no-tablespaces options.

  • --no-owner prevents PostgreSQL from restoring the original object ownership. The objects will be owned by the user performing the restore (for example, postgres).
  • --no-tablespaces ignores the original tablespace definitions and restores all objects into the target database’s default tablespace.
-- Restore without --no-owner and --no-tablespaces options.

Backup on source:

[postgres@pgdb02 backup]$ psql -d gebua
psql (17.10)
Type "help" for help.

gebua=# \dn+
                                       List of schemas
  Name  |       Owner       |           Access privileges            |      Description
--------+-------------------+----------------------------------------+------------------------
 geb    | gebadm            |                                        |
 public | pg_database_owner | pg_database_owner=UC/pg_database_owner+| standard public schema
        |                   | =U/pg_database_owner                   |
(2 rows)

gebua=# \dt geb.*
             List of relations
 Schema |       Name       | Type  | Owner
--------+------------------+-------+--------
 geb    | dept             | table | gebadm
 geb    | emp              | table | gebadm
 geb    | hr               | table | gebadm
 geb    | pgbench_accounts | table | gebadm
 geb    | pgbench_branches | table | gebadm
 geb    | pgbench_history  | table | gebadm
 geb    | pgbench_tellers  | table | gebadm
(7 rows)

gebua=# select count(*) from geb.hr;
 count
-------
     3
(1 row)

gebua=#


[postgres@pgdb02 backup]$ pg_dump -d gebua -Fc -v -f 03_task_gebua_full_backup_binary.dmp 2> 03_task_gebua_full_backup_binary.log


scp to target server

[postgres@pgdb02 backup]$ scp 03_task_gebua_full_backup_binary.dmp lxceftsgvdb01:/pgBackup/gebta/backup
03_task_gebua_full_backup_binary.dmp             100%                 27MB            49.5MB/s               00:00
[postgres@pgdb02 backup]$

Cleanup:
[postgres@lxceftsgvdb01 backup]$ psql -d gebta
psql (17.10)
Type "help" for help.

gebta=# drop schema geb cascade;
NOTICE:  drop cascades to 3 other objects
DETAIL:  drop cascades to table geb.dept
drop cascades to table geb.emp
drop cascades to table geb.hr
DROP SCHEMA
gebta=#
gebta=# \dn+
                                       List of schemas
  Name  |       Owner       |           Access privileges            |      Description
--------+-------------------+----------------------------------------+------------------------
 public | pg_database_owner | pg_database_owner=UC/pg_database_owner+| standard public schema
        |                   | =U/pg_database_owner                   |
(1 row)

gebta=#
gebta=# exit
[postgres@lxceftsgvdb01 backup]$

Restore:
[postgres@lxceftsgvdb01 backup]$ pg_restore -d gebta -Fc -c -v 03_task_gebua_full_backup_binary.dmp 2> 03_task_gebua_full_backup_binary1.log
[postgres@lxceftsgvdb01 backup]$ cat 03_task_gebua_full_backup_binary1.log
pg_restore: connecting to database for restore
pg_restore: dropping CONSTRAINT pgbench_tellers pgbench_tellers_pkey
pg_restore: while PROCESSING TOC:
pg_restore: from TOC entry 4217; 2606 41048 CONSTRAINT pgbench_tellers pgbench_tellers_pkey gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: ALTER TABLE ONLY geb.pgbench_tellers DROP CONSTRAINT pgbench_tellers_pkey;
pg_restore: dropping CONSTRAINT pgbench_branches pgbench_branches_pkey
pg_restore: from TOC entry 4221; 2606 41046 CONSTRAINT pgbench_branches pgbench_branches_pkey gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: ALTER TABLE ONLY geb.pgbench_branches DROP CONSTRAINT pgbench_branches_pkey;
pg_restore: dropping CONSTRAINT pgbench_accounts pgbench_accounts_pkey
pg_restore: from TOC entry 4219; 2606 41050 CONSTRAINT pgbench_accounts pgbench_accounts_pkey gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: ALTER TABLE ONLY geb.pgbench_accounts DROP CONSTRAINT pgbench_accounts_pkey;
pg_restore: dropping CONSTRAINT dept dept_pkey
pg_restore: from TOC entry 4215; 2606 32853 CONSTRAINT dept dept_pkey gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: ALTER TABLE ONLY geb.dept DROP CONSTRAINT dept_pkey;
pg_restore: dropping TABLE pgbench_tellers
pg_restore: from TOC entry 222; 1259 41032 TABLE pgbench_tellers gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: DROP TABLE geb.pgbench_tellers;
pg_restore: dropping TABLE pgbench_history
pg_restore: from TOC entry 221; 1259 41029 TABLE pgbench_history gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: DROP TABLE geb.pgbench_history;
pg_restore: dropping TABLE pgbench_branches
pg_restore: from TOC entry 224; 1259 41038 TABLE pgbench_branches gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: DROP TABLE geb.pgbench_branches;
pg_restore: dropping TABLE pgbench_accounts
pg_restore: from TOC entry 223; 1259 41035 TABLE pgbench_accounts gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: DROP TABLE geb.pgbench_accounts;
pg_restore: dropping TABLE hr
pg_restore: from TOC entry 220; 1259 32859 TABLE hr gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: DROP TABLE geb.hr;
pg_restore: dropping TABLE emp
pg_restore: from TOC entry 218; 1259 32844 TABLE emp gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: DROP TABLE geb.emp;
pg_restore: dropping TABLE dept
pg_restore: from TOC entry 219; 1259 32849 TABLE dept gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: DROP TABLE geb.dept;
pg_restore: dropping SCHEMA geb
pg_restore: from TOC entry 6; 2615 32843 SCHEMA geb gebadm
pg_restore: error: could not execute query: ERROR:  schema "geb" does not exist
Command was: DROP SCHEMA geb;
pg_restore: creating SCHEMA "geb"
pg_restore: error: could not execute query: ERROR:  role "gebadm" does not exist
Command was: ALTER SCHEMA geb OWNER TO gebadm;

pg_restore: creating TABLE "geb.dept"
pg_restore: from TOC entry 219; 1259 32849 TABLE dept gebadm
pg_restore: error: could not execute query: ERROR:  role "gebadm" does not exist
Command was: ALTER TABLE geb.dept OWNER TO gebadm;

pg_restore: creating TABLE "geb.emp"
pg_restore: from TOC entry 218; 1259 32844 TABLE emp gebadm
pg_restore: error: could not execute query: ERROR:  role "gebadm" does not exist
Command was: ALTER TABLE geb.emp OWNER TO gebadm;

pg_restore: creating TABLE "geb.hr"
pg_restore: from TOC entry 220; 1259 32859 TABLE hr gebadm
pg_restore: error: could not set "default_tablespace" to ts_data_uat2: ERROR:  invalid value for parameter "default_tablespace": "ts_data_uat2"
DETAIL:  Tablespace "ts_data_uat2" does not exist.
pg_restore: error: could not execute query: ERROR:  role "gebadm" does not exist
Command was: ALTER TABLE geb.hr OWNER TO gebadm;

pg_restore: creating TABLE "geb.pgbench_accounts"
pg_restore: from TOC entry 223; 1259 41035 TABLE pgbench_accounts gebadm
pg_restore: error: could not execute query: ERROR:  role "gebadm" does not exist
Command was: ALTER TABLE geb.pgbench_accounts OWNER TO gebadm;

pg_restore: creating TABLE "geb.pgbench_branches"
pg_restore: from TOC entry 224; 1259 41038 TABLE pgbench_branches gebadm
pg_restore: error: could not execute query: ERROR:  role "gebadm" does not exist
Command was: ALTER TABLE geb.pgbench_branches OWNER TO gebadm;

pg_restore: creating TABLE "geb.pgbench_history"
pg_restore: from TOC entry 221; 1259 41029 TABLE pgbench_history gebadm
pg_restore: error: could not execute query: ERROR:  role "gebadm" does not exist
Command was: ALTER TABLE geb.pgbench_history OWNER TO gebadm;

pg_restore: creating TABLE "geb.pgbench_tellers"
pg_restore: from TOC entry 222; 1259 41032 TABLE pgbench_tellers gebadm
pg_restore: error: could not execute query: ERROR:  role "gebadm" does not exist
Command was: ALTER TABLE geb.pgbench_tellers OWNER TO gebadm;

pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: processing data for table "geb.hr"
pg_restore: processing data for table "geb.pgbench_accounts"
pg_restore: processing data for table "geb.pgbench_branches"
pg_restore: processing data for table "geb.pgbench_history"
pg_restore: processing data for table "geb.pgbench_tellers"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
pg_restore: warning: errors ignored on restore: 21
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$
[postgres@lxceftsgvdb01 backup]$ psql -d gebta
psql (17.10)
Type "help" for help.

gebta=# \dn+
                                       List of schemas
  Name  |       Owner       |           Access privileges            |      Description
--------+-------------------+----------------------------------------+------------------------
 geb    | postgres          |                                        |
 public | pg_database_owner | pg_database_owner=UC/pg_database_owner+| standard public schema
        |                   | =U/pg_database_owner                   |
(2 rows)

gebta=# \dt geb.*
              List of relations
 Schema |       Name       | Type  |  Owner
--------+------------------+-------+----------
 geb    | dept             | table | postgres
 geb    | emp              | table | postgres
 geb    | hr               | table | postgres
 geb    | pgbench_accounts | table | postgres
 geb    | pgbench_branches | table | postgres
 geb    | pgbench_history  | table | postgres
 geb    | pgbench_tellers  | table | postgres
(7 rows)

gebta=# select count(*) from geb.hr;
 count
-------
     3  <-------------
(1 row)

gebta=#

ConclusionΒ 
If you perform a normal restore, PostgreSQL report errors because it cannot assign ownership to a role that does not exist or create objects in tablespaces that are unavailable on the target server.Β 
However, the database objects and data are still restored successfully. The restored schema is owned by the user performing the restore (for example, postgres), and all objects are created in the target database’s default tablespace.


If you do not want to see these ownership and tablespace-related errors in the restore log, use the --no-owner and --no-tablespaces options.


Restore with –no-owner and –no-tablespaces Options

[postgres@lxceftsgvdb01 backup]$ pg_restore -d gebta -Fc -c -v --no-owner --no-tablespaces 03_task_gebua_full_backup_binary.dmp 2>03_task_gebua_full_backup_binary2.log

Review the restore log:

[postgres@lxceftsgvdb01 backup]$ cat 03_task_gebua_full_backup_binary2.log
pg_restore: connecting to database for restore
pg_restore: dropping CONSTRAINT pgbench_tellers pgbench_tellers_pkey
pg_restore: dropping CONSTRAINT pgbench_branches pgbench_branches_pkey
pg_restore: dropping CONSTRAINT pgbench_accounts pgbench_accounts_pkey
pg_restore: dropping CONSTRAINT dept dept_pkey
pg_restore: dropping TABLE pgbench_tellers
pg_restore: dropping TABLE pgbench_history
pg_restore: dropping TABLE pgbench_branches
pg_restore: dropping TABLE pgbench_accounts
pg_restore: dropping TABLE hr
pg_restore: dropping TABLE emp
pg_restore: dropping TABLE dept
pg_restore: dropping SCHEMA geb
pg_restore: creating SCHEMA "geb"
pg_restore: creating TABLE "geb.dept"
pg_restore: creating TABLE "geb.emp"
pg_restore: creating TABLE "geb.hr"
pg_restore: creating TABLE "geb.pgbench_accounts"
pg_restore: creating TABLE "geb.pgbench_branches"
pg_restore: creating TABLE "geb.pgbench_history"
pg_restore: creating TABLE "geb.pgbench_tellers"
pg_restore: processing data for table "geb.dept"
pg_restore: processing data for table "geb.emp"
pg_restore: processing data for table "geb.hr"
pg_restore: processing data for table "geb.pgbench_accounts"
pg_restore: processing data for table "geb.pgbench_branches"
pg_restore: processing data for table "geb.pgbench_history"
pg_restore: processing data for table "geb.pgbench_tellers"
pg_restore: creating CONSTRAINT "geb.dept dept_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_accounts pgbench_accounts_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_branches pgbench_branches_pkey"
pg_restore: creating CONSTRAINT "geb.pgbench_tellers pgbench_tellers_pkey"
[postgres@lxceftsgvdb01 backup]$
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

Backup & Restore using PostgreSQL COPY

Backup & Restore using PostgreSQL COPY

Table of Contents



1. Understanding the COPY Command

PostgreSQL’s COPY command is one of the most efficient ways to export and import data to/from files. Unlike traditional INSERT statements, COPY can transfer large amounts of data in seconds, making it ideal for backups, data migrations, and bulk operations. Remember to always test restore procedures in non-production environments and maintain multiple backups in different formats for maximum data safety.

  • COPY TO: Exports data from a PostgreSQL table to a file
  • COPY FROM: Imports data from a file into a PostgreSQL table
  • Why use it: 10-100x faster than individual INSERT statements for bulk operations
  • Flexible formatting: Support for tab-delimited, comma-delimited, CSV, and custom formats
  • Query support: Can export results of complex queries, not just entire tables
  • Selective import: Import only specific columns; others receive NULL or DEFAULT values

Key Point: COPY is not meant to replace full backups using pg_dump, but it’s perfect for selective data export/import, data migrations, and quick backups of specific tables.

2. Setup: Create Schema & Test Data

First, create a schema and sample table with test data:

postgres=# \c
You are now connected to database "postgres" as user "postgres".

-- Create user 

postgres=# create user edbadm password 'edbadm';
CREATE ROLE
postgres=# 

-- Create Database 

postgres=# CREATE DATABASE edbua;
CREATE DATABASE
postgres=# 

-- Create schema and insert some data.
postgres=# \c edbua
You are now connected to database "edbua" as user "postgres".
edbua=#
edbua=# CREATE SCHEMA edb AUTHORIZATION edbadm;
CREATE SCHEMA
edbua=#

postgres=# \c edbua edbadm
You are now connected to database "edbua" as user "edbadm".
edbua=>
edbua=> CREATE TABLE edb.emp (id SERIAL PRIMARY KEY, name TEXT NOT NULL, designation TEXT, project TEXT,company TEXT);
CREATE TABLE
edbua=> INSERT INTO edb.emp (name, designation, project, company) VALUES ('Sugi', 'DBA', 'Jetstar', 'iGATE');
INSERT 0 1
edbua=> INSERT INTO edb.emp (name, designation, project, company) VALUES ('Teja', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
edbua=> INSERT INTO edb.emp (name, designation, project, company) VALUES ('RAJ', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
edbua=> INSERT INTO edb.emp (name, designation, project, company) VALUES ('Arun', 'Developer', 'Jetstar', 'TCS');
INSERT 0 1
edbua=> INSERT INTO edb.emp (name, designation, project, company) VALUES ('Priya', 'QA', 'RCM', 'Wipro');
INSERT 0 1
edbua=> SELECT * FROM edb.emp;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=> SELECT COUNT(*) FROM edb.emp;
 count
-------
     5 <-----
(1 row)

edbua=>

Backup directory setup (execute from terminal as root):

[root@pgdb02 ~]# mkdir -p /pgBackup/edbua/backup/
[root@pgdb02 ~]# chown postgres:postgres /pgBackup/edbua/backup/
[root@pgdb02 ~]#

3. Basic Export & Import (Tab-Delimited)

Export: Export all data from a table to a file using the default tab-delimited format:

-- Basic COPY: Exports all data (tab-delimited by default)

postgres=# \c edbua
You are now connected to database "edbua" as user "postgres".
edbua=#
edbua=# COPY edb.emp TO '/pgBackup/edbua/backup/table_backup_edbua_edb_emp.txt';
COPY 5
edbua=#

This creates a simple text file with each record on one line, columns separated by tabs. To view the exported file from terminal:

[postgres@pgdb02 ~]$ ls -ltr /pgBackup/edbua/backup/table_backup_edbua_edb_emp.txt
-rw-r--r--. 1 postgres postgres 116 Jul 10 15:17 /pgBackup/edbua/backup/table_backup_edbua_edb_emp.txt
[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ wc -l /pgBackup/edbua/backup/table_backup_edbua_edb_emp.txt
5 /pgBackup/edbua/backup/table_backup_edbua_edb_emp.txt
[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ cat /pgBackup/edbua/backup/table_backup_edbua_edb_emp.txt
1           Sugi            DBA         Jetstar          iGATE
2           Teja            DBA         RCM              iGATE
3           RAJ             DBA         RCM              iGATE
4           Arun            Developer   Jetstar           TCS
5           Priya           QA          RCM               Wipro
[postgres@pgdb02 ~]$

The output shows each employee record with columns separated by tabs. This format is useful for simple, fast backups.

Import: Restore data from the backup file:

--- Simulate data loss - truncate the table

edbua=# TRUNCATE TABLE edb.emp CASCADE;
TRUNCATE TABLE
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     0
(1 row)

edbua=# COPY edb.emp FROM '/pgBackup/edbua/backup/table_backup_edbua_edb_emp.txt';
COPY 5
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     5  <----
(1 row)

edbua=# SELECT * FROM edb.emp;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=#

4. Custom Delimiters – Export & Import

Use different delimiters to format data for different systems and tools. Choose the delimiter that best matches your target system or data import tool. When importing, ensure the DELIMITER option matches the file format.

Export with Pipe Delimiter (|):

--- Export

edbua=# \c
You are now connected to database "edbua" as user "postgres".
edbua=# COPY edb.emp TO '/pgBackup/edbua/backup/table_backup_edbua_edb_emp_pipe.txt' WITH DELIMITER '|';
COPY 5
edbua=#

edbua=# \! cat /pgBackup/edbua/backup/table_backup_edbua_edb_emp_pipe.txt
1|Sugi|DBA|Jetstar|iGATE
2|Teja|DBA|RCM|iGATE
3|RAJ|DBA|RCM|iGATE
4|Arun|Developer|Jetstar|TCS
5|Priya|QA|RCM|Wipro
edbua=#


----- IMPORT 

--- Simulate data loss - truncate the table
edbua=# TRUNCATE TABLE edb.emp CASCADE;
TRUNCATE TABLE
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     0
(1 row)

edbua=# COPY edb.emp FROM '/pgBackup/edbua/backup/table_backup_edbua_edb_emp_pipe.txt' WITH DELIMITER '|';
COPY 5
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     5  <----
(1 row)

edbua=# SELECT * FROM edb.emp;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=#

Export with Comma Delimiter:

-- EXPORT

edbua=# \c
You are now connected to database "edbua" as user "postgres".
edbua=#
edbua=# COPY edb.emp TO '/pgBackup/edbua/backup/table_backup_edbua_edb_emp_comma.txt' WITH DELIMITER ',';
COPY 5
edbua=#
edbua=# \! cat /pgBackup/edbua/backup/table_backup_edbua_edb_emp_comma.txt
1,Sugi,DBA,Jetstar,iGATE
2,Teja,DBA,RCM,iGATE
3,RAJ,DBA,RCM,iGATE
4,Arun,Developer,Jetstar,TCS
5,Priya,QA,RCM,Wipro
edbua=#

-- IMPORT

--- Simulate data loss - truncate the table
edbua=# TRUNCATE TABLE edb.emp CASCADE;
TRUNCATE TABLE
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     0
(1 row)

edbua=# COPY edb.emp FROM '/pgBackup/edbua/backup/table_backup_edbua_edb_emp_comma.txt' WITH DELIMITER ',';
COPY 5
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     5   <-------
(1 row)

edbua=# SELECT * FROM edb.emp;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=#

Export with Semicolon Delimiter:

-- EXPORT

edbua=# COPY edb.emp TO '/pgBackup/edbua/backup/table_backup_edbua_edb_emp_semicolon.txt' WITH DELIMITER ';';
COPY 5
edbua=# \! cat /pgBackup/edbua/backup/table_backup_edbua_edb_emp_semicolon.txt
1;Sugi;DBA;Jetstar;iGATE
2;Teja;DBA;RCM;iGATE
3;RAJ;DBA;RCM;iGATE
4;Arun;Developer;Jetstar;TCS
5;Priya;QA;RCM;Wipro
edbua=#

-- IMPORT
--- Simulate data loss - truncate the table
edbua=# TRUNCATE TABLE edb.emp CASCADE;
TRUNCATE TABLE
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     0
(1 row)

edbua=# COPY edb.emp FROM '/pgBackup/edbua/backup/table_backup_edbua_edb_emp_semicolon.txt' WITH DELIMITER ';';
COPY 5
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     5  <-----------------
(1 row)

edbua=# SELECT * FROM edb.emp;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=#

5. CSV Format – Export & Import with Headers

CSV (Comma-Separated Values) format is the most portable and human-readable format. Include headers for better clarity.

Export as CSV with column headers & Import

-- EXPORT

edbua=# COPY edb.emp TO '/pgBackup/edbua/backup/table_backup_edbua_edb_emp.csv' WITH CSV HEADER;
COPY 5
edbua=# \! cat /pgBackup/edbua/backup/table_backup_edbua_edb_emp.csv
id,name,designation,project,company
1,Sugi,DBA,Jetstar,iGATE
2,Teja,DBA,RCM,iGATE
3,RAJ,DBA,RCM,iGATE
4,Arun,Developer,Jetstar,TCS
5,Priya,QA,RCM,Wipro
edbua=#
edbua=# \! ls -l /pgBackup/edbua/backup/table_backup_edbua_edb_emp.csv
-rw-r--r--. 1 postgres postgres 152 Jul 10 15:41 /pgBackup/edbua/backup/table_backup_edbua_edb_emp.csv
edbua=#

---- IMPORT
--- Simulate data loss - truncate the table
edbua=# TRUNCATE TABLE edb.emp CASCADE;
TRUNCATE TABLE
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     0
(1 row)

edbua=# COPY edb.emp FROM '/pgBackup/edbua/backup/table_backup_edbua_edb_emp.csv' WITH CSV HEADER;
COPY 5
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     5  <------
(1 row)

edbua=# SELECT * FROM edb.emp;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=#

Export as CSV with custom delimiter and header & Import

edbua=# COPY edb.emp TO '/pgBackup/edbua/backup/table_backup_edbua_edb_emp_custom.csv' WITH CSV HEADER DELIMITER '|';
COPY 5
edbua=# \! cat /pgBackup/edbua/backup/table_backup_edbua_edb_emp_custom.csv
id|name|designation|project|company
1|Sugi|DBA|Jetstar|iGATE
2|Teja|DBA|RCM|iGATE
3|RAJ|DBA|RCM|iGATE
4|Arun|Developer|Jetstar|TCS
5|Priya|QA|RCM|Wipro
edbua=#

--- IMPORT 
--- Simulate data loss - truncate the table
edbua=# TRUNCATE TABLE edb.emp CASCADE;
TRUNCATE TABLE
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     0
(1 row)

edbua=# COPY edb.emp FROM '/pgBackup/edbua/backup/table_backup_edbua_edb_emp_custom.csv' WITH CSV HEADER DELIMITER '|';
COPY 5
edbua=# SELECT COUNT(*) FROM edb.emp;
 count
-------
     5 <-------------------
(1 row)

edbua=# SELECT * FROM edb.emp;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=#

We will see the first line contains column names: id,name,designation,project,company, followed by the data. This format is ideal for importing into Excel, Google Sheets, or other database systems.

6. Filtered Data – Export & Import Specific Queries

Export and import only specific data based on conditions using queries.

Export only DBAs from iGATE:

edbua=# SELECT id, name, designation, project, company FROM edb.emp WHERE designation = 'DBA' AND company = 'iGATE';
 id | name | designation | project | company
----+------+-------------+---------+---------
  1 | Sugi | DBA         | Jetstar | iGATE
  2 | Teja | DBA         | RCM     | iGATE
  3 | RAJ  | DBA         | RCM     | iGATE
(3 rows)

edbua=# COPY ( SELECT id, name, designation, project, company FROM edb.emp WHERE designation = 'DBA' AND company = 'iGATE' ) TO '/pgBackup/edbua/backup/edb_emp_dbas.txt' WITH DELIMITER '|';
COPY 3
edbua=#
edbua=# \! cat /pgBackup/edbua/backup/edb_emp_dbas.txt
1|Sugi|DBA|Jetstar|iGATE
2|Teja|DBA|RCM|iGATE
3|RAJ|DBA|RCM|iGATE
edbua=#

Export specific columns only:

edbua=# SELECT name, designation, company FROM edb.emp WHERE company IN ('iGATE', 'TCS');
 name | designation | company
------+-------------+---------
 Sugi | DBA         | iGATE
 Teja | DBA         | iGATE
 RAJ  | DBA         | iGATE
 Arun | Developer   | TCS
(4 rows)

edbua=# COPY ( SELECT name, designation, company FROM edb.emp WHERE company IN ('iGATE', 'TCS') ) TO '/pgBackup/edbua/backup/edb_emp_selected.txt' WITH CSV HEADER;
COPY 4
edbua=#
edbua=# \! cat /pgBackup/edbua/backup/edb_emp_selected.txt
name,designation,company
Sugi,DBA,iGATE
Teja,DBA,iGATE
RAJ,DBA,iGATE
Arun,Developer,TCS
edbua=#


---- Import with column mapping:

-- Create a staging table with different column structure and Import specific columns mapped to different table
edbua=# CREATE TABLE edb.emp_staging ( full_name TEXT, job_title TEXT, employer TEXT );
CREATE TABLE
edbua=# COPY edb.emp_staging (full_name, job_title, employer) FROM '/pgBackup/edbua/backup/edb_emp_selected.txt' WITH CSV HEADER;
COPY 4
edbua=# SELECT * FROM edb.emp_staging;
 full_name | job_title | employer
-----------+-----------+----------
 Sugi      | DBA       | iGATE
 Teja      | DBA       | iGATE
 RAJ       | DBA       | iGATE
 Arun      | Developer | TCS
(4 rows)

edbua=#

Export with row numbering:

edbua=# SELECT ROW_NUMBER() OVER () as row_num, name, designation, project FROM edb.emp ORDER BY name;
 row_num | name  | designation | project
---------+-------+-------------+---------
       4 | Arun  | Developer   | Jetstar
       5 | Priya | QA          | RCM
       3 | RAJ   | DBA         | RCM
       1 | Sugi  | DBA         | Jetstar
       2 | Teja  | DBA         | RCM
(5 rows)

edbua=# COPY ( SELECT ROW_NUMBER() OVER () as row_num, name, designation, project FROM edb.emp ORDER BY name ) TO '/pgBackup/edbua/backup/edb_emp_numbered.csv' WITH CSV HEADER;
COPY 5
edbua=#
edbua=# \! cat /pgBackup/edbua/backup/edb_emp_numbered.csv
row_num,name,designation,project
4,Arun,Developer,Jetstar
5,Priya,QA,RCM
3,RAJ,DBA,RCM
1,Sugi,DBA,Jetstar
2,Teja,DBA,RCM
edbua=#

This approach is perfect for creating targeted backups, archiving old data, generating reports, and selectively importing data into different table structures.

7. Handling Special Cases (NULLs, Special Characters, Duplicates)

A. Handling NULL Values During Export & Import:

-- Create table with nullable columns
edbua=# CREATE TABLE edb.emp_nullable ( id SERIAL PRIMARY KEY, name TEXT, designation TEXT, project TEXT, company TEXT );
CREATE TABLE
edbua=#

-- Insert data with some NULL values
edbua=# INSERT INTO edb.emp_nullable (name, designation, project, company) VALUES ('Sugi', 'DBA', 'Jetstar', NULL), ('Teja', 'DBA', NULL, 'iGATE'), ('RAJ', NULL, 'RCM', 'iGATE');
INSERT 0 3
edbua=#

-- Export (NULLs appear as empty fields)
edbua=# COPY edb.emp_nullable TO '/pgBackup/edbua/backup/edb_emp_nulls.csv' WITH CSV HEADER;
COPY 3
edbua=#
edbua=# SELECT * FROM edb.emp_nullable;
 id | name | designation | project | company
----+------+-------------+---------+---------
  1 | Sugi | DBA         | Jetstar |
  2 | Teja | DBA         |         | iGATE
  3 | RAJ  |             | RCM     | iGATE
(3 rows)

edbua=#
-- Import back (empty fields become NULL)
edbua=# TRUNCATE TABLE edb.emp_nullable;
TRUNCATE TABLE
edbua=# COPY edb.emp_nullable FROM '/pgBackup/edbua/backup/edb_emp_nulls.csv' WITH CSV HEADER;
COPY 3
edbua=# SELECT * FROM edb.emp_nullable;  -- Notice NULL values preserved
 id | name | designation | project | company
----+------+-------------+---------+---------
  1 | Sugi | DBA         | Jetstar |
  2 | Teja | DBA         |         | iGATE
  3 | RAJ  |             | RCM     | iGATE
(3 rows)

edbua=#

B. Exporting & Importing Data with Special Characters:

-- Create table with special characters
edbua=# CREATE TABLE edb.emp_special ( id SERIAL PRIMARY KEY, name TEXT, description TEXT );
CREATE TABLE
edbua=# 

-- Insert data with quotes and commas
edbua=# INSERT INTO edb.emp_special (name, description) VALUES ('John "The Expert" Doe', 'Senior DBA, 10 years experience'), ('Mary O''Brien', 'Works with Oracle, PostgreSQL, MySQL');
INSERT 0 2
edbua=# 

-- Export with proper escaping (CSV handles this automatically)
edbua=# COPY edb.emp_special TO '/pgBackup/edbua/backup/edb_emp_special.csv' WITH CSV HEADER QUOTE '"' ESCAPE '"';
COPY 2
edbua=#
edbua=# SELECT * FROM edb.emp_special;
 id |         name          |             description
----+-----------------------+--------------------------------------
  1 | John "The Expert" Doe | Senior DBA, 10 years experience
  2 | Mary O'Brien          | Works with Oracle, PostgreSQL, MySQL
(2 rows)

edbua=#

-- Import from the file (escaping automatically handled)

edbua=# TRUNCATE TABLE edb.emp_special;
TRUNCATE TABLE
edbua=# COPY edb.emp_special FROM '/pgBackup/edbua/backup/edb_emp_special.csv' WITH CSV HEADER QUOTE '"' ESCAPE '"';
COPY 2
edbua=# SELECT * FROM edb.emp_special;
 id |         name          |             description
----+-----------------------+--------------------------------------
  1 | John "The Expert" Doe | Senior DBA, 10 years experience
  2 | Mary O'Brien          | Works with Oracle, PostgreSQL, MySQL
(2 rows)

edbua=#

C. Handling Duplicate Keys:

-- If importing data might have duplicate primary keys:

-- Option 1: Truncate first (removes all data)
TRUNCATE TABLE edb.emp CASCADE;

-- Option 2: Import to staging table first, then validate
CREATE TABLE edb.emp_staging (LIKE edb.emp);
COPY edb.emp_staging FROM '/pgBackup/edbua/backup/edb_emp.csv' WITH CSV HEADER;

-- Check for issues, then copy valid data
SELECT COUNT(*) FROM edb.emp_staging;
INSERT INTO edb.emp SELECT * FROM edb.emp_staging WHERE id NOT IN (SELECT id FROM edb.emp);

8. Copying Data Between Tables (emp to emp02)

Transfer data from one table to another table.

-- Step 1: Export emp data to file
edbua=# select * from edb.emp;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=# COPY edb.emp TO '/pgBackup/edbua/backup/emp_to_emp02.csv' WITH CSV HEADER;
COPY 5
edbua=#

-- Step 2: Create emp02 table 
edbua=# CREATE TABLE edb.emp02 ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, designation TEXT, project TEXT, company TEXT );
CREATE TABLE
edbua=#

-- Step 3: Import data from file into emp02
edbua=# select * from edb.emp02;
 id | name | designation | project | company
----+------+-------------+---------+---------
(0 rows)

edbua=# COPY edb.emp02 FROM '/pgBackup/edbua/backup/emp_to_emp02.csv' WITH CSV HEADER;
COPY 5
edbua=# select * from edb.emp02;
 id | name  | designation | project | company
----+-------+-------------+---------+---------
  1 | Sugi  | DBA         | Jetstar | iGATE
  2 | Teja  | DBA         | RCM     | iGATE
  3 | RAJ   | DBA         | RCM     | iGATE
  4 | Arun  | Developer   | Jetstar | TCS
  5 | Priya | QA          | RCM     | Wipro
(5 rows)

edbua=#
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

Databases in PostgreSQL

Databases in PostgreSQL

Table of Contents



1. Understanding PostgreSQL Templates

In Oracle, there is typically only one database. When using the multitenant architecture, Oracle has two default containers: the root container (CDB$ROOT) and the seed pluggable database (PDB$SEED).

PostgreSQL comes with two built-in templates databases (template0 and template01) and additionally a database called β€œpostgres”, that means three databases by default.

postgres=# \l
                                                     List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +
           |          |          |                 |             |             |        |           | postgres=CTc/postgres
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +
           |          |          |                 |             |             |        |           | postgres=CTc/postgres
(3 rows)

postgres=#

Template0 is the original master copy. It’s read-only and never changes. PostgreSQL protects it to keep it completely clean and empty.

Template1 is the default template that PostgreSQL uses when you create a new database. You can customize Template1 by adding extensions, settings, and other objects. When you create new databases from Template1, they automatically get all these customizations.

Why need two templetes? In a new PostgreSQL installation, template0 and template1 are identical. So why are there two template databases? The reason is that template0 serves as a clean backup copy. If template1 is modified too much or accidentally changed by adding unwanted objects, extensions, or settings, you can use template0 to create a fresh database and recover easily.

Key Points:

  • When you create a database without specifying which template to use, PostgreSQL automatically uses Template1.
  • Template1 can be modified with extensions and settings. Any new database created from Template1 will inherit these changes.
  • Template0 never changes. It always stays clean and empty.
  • If you want a brand new, completely empty database with no customizations, use Template0 instead of Template1.

When you run CREATE DATABASE mydb without specifying a template, PostgreSQL uses template1. To get a completely clean database without any customizations, explicitly use template0.

2. View Existing Templates

Before making any changes to your templates, it’s good practice to verify their current state. The following queries show you all templates in your PostgreSQL instance:

-- This query shows you all template databases with their names, template status, and access control lists (ACL).

[postgres@pgdb02 ~]$ psql
psql (17.10)
Type "help" for help.

postgres=# SELECT datname, datistemplate, datacl FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate |               datacl
-----------+---------------+-------------------------------------
 template0 | t             | {=c/postgres,postgres=CTc/postgres}
 template1 | t             | {=c/postgres,postgres=CTc/postgres}
(2 rows)

postgres=#
postgres=# \l+ temp*
                                                                                   List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   | Tablespace |            Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+------------+------------------------------------
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7569 kB | pg_default | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
(2 rows)

postgres=#

3. Create Databases with Template0 (Clean Slate)

When you need a completely fresh database with no existing objects or extensions, create it from template0.

-- Create a fresh database from template0

postgres=# CREATE DATABASE testdb WITH TEMPLATE template0;
CREATE DATABASE
postgres=# \l
                                                     List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +
           |          |          |                 |             |             |        |           | postgres=CTc/postgres
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +
           |          |          |                 |             |             |        |           | postgres=CTc/postgres
 testdb    | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |
(4 rows)

postgres=#

postgres=# SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database WHERE datname IN ('template0','testdb') ORDER BY pg_database_size(datname) DESC;
  datname  |  size
-----------+---------
 template0 | 7702 kB
 testdb    | 7702 kB
(2 rows)

postgres=#

Note: Template0 is read-only by design. You cannot modify it directly. This ensures you always have a pristine copy to work from.

4. Create Databases with Template1 (Default)

Template1 is the default template used when creating new databases. Most development and testing databases are created from template1 because it can be customized to include common extensions and configurations.

-- Create a database from template1 (most common)
postgres=# CREATE DATABASE testdb02 WITH TEMPLATE template1;
CREATE DATABASE
postgres=# \l+
                                                                                       List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   | Tablespace |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+------------+--------------------------------------------
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7774 kB | pg_default | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7569 kB | pg_default | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
 testdb    | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7545 kB | pg_default |
 testdb02  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7569 kB | pg_default |
(5 rows)

postgres=#


-- Create another database from template1

postgres=# CREATE DATABASE testdb03 TEMPLATE template1 ENCODING 'UTF8' OWNER postgres CONNECTION LIMIT 200;
CREATE DATABASE
postgres=# SELECT datname, datconnlimit FROM pg_database WHERE datname = 'testdb03';
 datname  | datconnlimit
----------+--------------
 testdb03 |          200
(1 row)

postgres=#

5. Create Simple Databases

For quick testing or development, you can create databases with minimal syntax. PostgreSQL will automatically use template1 as the default:

-- Most basic creation (uses template1 by default)
postgres=# CREATE DATABASE testdb04;
CREATE DATABASE
postgres=#

-- With specific owner
postgres=# CREATE DATABASE testdb05 OWNER postgres;
CREATE DATABASE
postgres=#

6. Customize Template1

You can add extensions and objects to template1 so that all future databases inherit them automatically. Be cautious in production, as changes to template1 affect all subsequently created databases:

-- Add useful extensions to template1:
postgres=# \c template1
You are now connected to database "template1" as user "postgres".
template1=# 
template1=# \dx
                 List of installed extensions
  Name   | Version |   Schema   |         Description
---------+---------+------------+------------------------------
 plpgsql | 1.0     | pg_catalog | PL/pgSQL procedural language
(1 row)

template1=# CREATE EXTENSION pg_stat_statements;
CREATE EXTENSION
template1=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
template1=# 
template1=# \dx
                                            List of installed extensions
        Name        | Version |   Schema   |                              Description
--------------------+---------+------------+------------------------------------------------------------------------
 pg_stat_statements | 1.11    | public     | track planning and execution statistics of all SQL statements executed
 pgcrypto           | 1.3     | public     | cryptographic functions
 plpgsql            | 1.0     | pg_catalog | PL/pgSQL procedural language
(3 rows)

template1=#

-- Create database with Templete1 and verify extensions
template1=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=#
postgres=#
postgres=# CREATE DATABASE testdb06 TEMPLATE template1;
CREATE DATABASE
postgres=#
postgres=# \c testdb06
You are now connected to database "testdb06" as user "postgres".
testdb06=#
testdb06=# \dx
                                            List of installed extensions
        Name        | Version |   Schema   |                              Description
--------------------+---------+------------+------------------------------------------------------------------------
 pg_stat_statements | 1.11    | public     | track planning and execution statistics of all SQL statements executed
 pgcrypto           | 1.3     | public     | cryptographic functions
 plpgsql            | 1.0     | pg_catalog | PL/pgSQL procedural language
(3 rows)

testdb06=#

Warning: Modifying template1 is a significant operation. Ensure you have a backup of your cluster before making changes, and test thoroughly in a non-production environment first.

7. Drop Default Database (Can we drop the β€œpostgres” database?)

In some scenarios, you may want to remove the default postgres database. First, disconnect all connections to it:

postgres=# \c
You are now connected to database "postgres" as user "postgres".
postgres=#
postgres=# drop database postgres;
ERROR: cannot drop the currently open database
postgres=#

You can not drop a database which users are currently connected to (in this case it is my own connection). So lets try to connect to template1 and then drop the β€œpostgres” database

postgres=# \c template1
You are now connected to database "template1" as user "postgres".
template1=#
template1=# drop database postgres;
DROP DATABASE
template1=#

 -- Recreate database "postgres" if needed

[postgres@pgdb02 ~]$ psql
psql: error: connection to server on socket "/run/postgresql/.s.PGSQL.5432" failed: FATAL:  database "postgres" does not exist
[postgres@pgdb02 ~]$ psql template1
psql (17.10)
Type "help" for help.

template1=# CREATE DATABASE postgres;
CREATE DATABASE
template1=#

template1=# \l postgres
                                                   List of databases
   Name   |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules | Access privileges
----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-------------------
 postgres | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |
(1 row)

template1=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=#

8. Create Custom Templates

Beyond template0 and template1, you can create your own custom templates for specific purposes. Custom templates are useful when different applications need different baseline configurations:

-- Create a custom template from template1
postgres=# CREATE DATABASE template2 TEMPLATE template1;
CREATE DATABASE
postgres=# SELECT datname, datistemplate, datacl FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate |               datacl
-----------+---------------+-------------------------------------
 template0 | t             | {=c/postgres,postgres=CTc/postgres}
 template1 | t             | {=c/postgres,postgres=CTc/postgres}
 template2 | f             |
(3 rows)

postgres=#

-- Mark it as a template

update pg_database set datistemplate = true where datname = 'template2'; -- OR ---  ALTER DATABASE template2 IS_TEMPLATE true;

postgres=# ALTER DATABASE template2 IS_TEMPLATE true;
ALTER DATABASE
postgres=#
postgres=# SELECT datname, datistemplate, datacl FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate |               datacl
-----------+---------------+-------------------------------------
 template0 | t             | {=c/postgres,postgres=CTc/postgres}
 template1 | t             | {=c/postgres,postgres=CTc/postgres}
 template2 | t             |
(3 rows)

postgres=#

-- Add extensions

template2=# \c
You are now connected to database "template2" as user "postgres".
template2=#
template2=# CREATE EXTENSION "pageinspect";
CREATE EXTENSION
template2=# \dx
                                            List of installed extensions
        Name        | Version |   Schema   |                              Description
--------------------+---------+------------+------------------------------------------------------------------------
 pageinspect        | 1.12    | public     | inspect the contents of database pages at a low level
 pg_stat_statements | 1.11    | public     | track planning and execution statistics of all SQL statements executed
 pgcrypto           | 1.3     | public     | cryptographic functions
 plpgsql            | 1.0     | pg_catalog | PL/pgSQL procedural language
(4 rows)

template2=#


-- Now create databases from your custom template:
template2=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=#
postgres=# CREATE DATABASE testdb07 TEMPLATE template2 OWNER postgres;
CREATE DATABASE
postgres=#
postgres=# \c testdb07
You are now connected to database "testdb07" as user "postgres".
testdb07=#
testdb07=# \dx
                                            List of installed extensions
        Name        | Version |   Schema   |                              Description
--------------------+---------+------------+------------------------------------------------------------------------
 pageinspect        | 1.12    | public     | inspect the contents of database pages at a low level
 pg_stat_statements | 1.11    | public     | track planning and execution statistics of all SQL statements executed
 pgcrypto           | 1.3     | public     | cryptographic functions
 plpgsql            | 1.0     | pg_catalog | PL/pgSQL procedural language
(4 rows)

testdb07=#

--- If you want to drop template2 db

template1=# drop database template2;
ERROR: cannot drop a template database
template1=#

template1=# SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate | datallowconn
-----------+---------------+--------------
 template0 | t             | f
 template1 | t             | t
 template2 | t             | t
(3 rows)

template1=#
template1=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=#
postgres=# update pg_database set datistemplate = false where datname = 'template2';
UPDATE 1
postgres=#
postgres=# SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate | datallowconn
-----------+---------------+--------------
 template0 | t             | f
 template1 | t             | t
 template2 | f             | t
(3 rows)

postgres=# drop database template2;
DROP DATABASE
postgres=#
postgres=# SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate | datallowconn
-----------+---------------+--------------
 template0 | t             | f
 template1 | t             | t
(2 rows)

postgres=#

9. Database Properties and Management

View comprehensive information about all your databases, including their size and template status:

-- View database properties

postgres=# SELECT datname, datistemplate, datallowconn,  datcollate, datctype, datacl FROM pg_database WHERE datname NOT LIKE 'pg_%' ORDER BY datname;
  datname  | datistemplate | datallowconn | datcollate  |  datctype   |               datacl
-----------+---------------+--------------+-------------+-------------+-------------------------------------
 postgres  | f             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
 template0 | t             | f            | en_SG.UTF-8 | en_SG.UTF-8 | {=c/postgres,postgres=CTc/postgres}
 template1 | t             | t            | en_SG.UTF-8 | en_SG.UTF-8 | {=c/postgres,postgres=CTc/postgres}
 template2 | t             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
 testdb    | f             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
 testdb02  | f             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
 testdb03  | f             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
 testdb04  | f             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
 testdb05  | f             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
 testdb06  | f             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
 testdb07  | f             | t            | en_SG.UTF-8 | en_SG.UTF-8 |
(11 rows)

postgres=#

-- Get database size

postgres=# SELECT datname, pg_size_pretty(pg_database_size(datname)) AS size FROM pg_database WHERE datname NOT LIKE 'pg_%' ORDER BY pg_database_size(datname) DESC;
  datname  |  size
-----------+---------
 testdb07  | 7854 kB
 template2 | 7854 kB
 template1 | 7822 kB
 testdb06  | 7822 kB
 postgres  | 7822 kB
 testdb05  | 7726 kB
 testdb02  | 7726 kB
 testdb03  | 7726 kB
 testdb04  | 7726 kB
 template0 | 7702 kB
 testdb    | 7702 kB
(11 rows)

postgres=#

10. Complete Workflow Example

-- Step 1: Create from template0 (clean database)
postgres=# CREATE DATABASE orcl01 TEMPLATE template0 OWNER postgres;
CREATE DATABASE
postgres=#

-- Step 2: Create from template1 (with default extensions)
postgres=# CREATE DATABASE orcl02 TEMPLATE template1 OWNER postgres;
CREATE DATABASE
postgres=#

-- Step 3: Create custom template for staging
postgres=# CREATE DATABASE custom_template TEMPLATE template1 OWNER postgres;
CREATE DATABASE
postgres=# ALTER DATABASE custom_template IS_TEMPLATE true;  -- OR -- update pg_database set datistemplate = true where datname = 'custom_template';
ALTER DATABASE
postgres=#

-- Step 4: Create from custom template
postgres=# CREATE DATABASE orcl03 TEMPLATE custom_template OWNER postgres;
CREATE DATABASE
postgres=#

-- Step 5: View all created databases

postgres=# SELECT datname, datistemplate, datcollate FROM pg_database WHERE datname LIKE 'orcl%' OR datname LIKE '%_template' ORDER BY datname;
     datname     | datistemplate | datcollate
-----------------+---------------+-------------
 custom_template | t             | en_SG.UTF-8
 orcl01          | f             | en_SG.UTF-8
 orcl02          | f             | en_SG.UTF-8
 orcl03          | f             | en_SG.UTF-8
(4 rows)

postgres=#

11. Drop Template1 and Create from Template0

Let’s go back to the datistemplate and datallowconn settings. template0 is the only database where datallowconn is set to false, which means users cannot connect to it. This is because template0 is intended to remain unchanged and should not be modified.

In a new PostgreSQL installation, template0 and template1 are identical. So why are there two template databases? The reason is that template0 serves as a clean backup copy. If template1 is modified too much or accidentally changed by adding unwanted objects, extensions, or settings, you can use template0 to create a fresh database and recover easily.

-- Verify current templates before changes

postgres=# drop database template1;
ERROR: cannot drop a template database
postgres=#

postgres=# SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate | datallowconn
-----------+---------------+--------------
 template0 | t             | f
 template1 | t             | t
(2 rows)

postgres=#

postgres=# update pg_database set datistemplate = false where datname = 'template1';   --- OR --- ALTER DATABASE template1 IS_TEMPLATE true;
UPDATE 1
postgres=# drop database template1;
DROP DATABASE
postgres=#
postgres=# SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate | datallowconn
-----------+---------------+--------------
 template0 | t             | f
(1 row)

postgres=#
postgres=# \l temp*
                                                     List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +
           |          |          |                 |             |             |        |           | postgres=CTc/postgres
(1 row)

postgres=#

----Recreate CREATE DATABASE template1 

postgres=# create database template1 template template0;
CREATE DATABASE
postgres=#
postgres=# SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate | datallowconn
-----------+---------------+--------------
 template0 | t             | f
 template1 | f             | t
(2 rows)

postgres=#                                                ^
postgres=# update pg_database set datistemplate = true where datname = 'template1';
UPDATE 1
postgres=#
postgres=# SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname LIKE 'template%' ORDER BY datname;
  datname  | datistemplate | datallowconn
-----------+---------------+--------------
 template0 | t             | f
 template1 | t             | t
(2 rows)

postgres=#

12. Can we drop “Template0” database?

Yes, we can drop by changing update pg_database set datistemplate = false where datname = 'template0'; , but Do not drop template0. There is no practical benefit, and it removes PostgreSQL's built-in clean template database. If template0 is accidentally modified or removed, recovery usually requires restoring it from another PostgreSQL instance of the same version or reinitializing the cluster. 

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/

PostgreSQL User & Role Management

PostgreSQL User & Role Management

Table of Contents



1. Users vs. Roles: There’s No Difference

The primary difference between CREATE ROLE and CREATE USER is that CREATE USER automatically includes the LOGIN privilege, allowing the user to connect to the database, whereas CREATE ROLE does not grant the LOGIN privilege unless it is explicitly specified.

PostgreSQL internally treats users and groups as roles. Therefore, using CREATE ROLE is often recommended. However, CREATE USER and CREATE GROUP are still supported and commonly used by DBAs. You can use whichever command you find easier to understand and manage.

Both users and roles are stored in the same PostgreSQL system catalog (pg_authid / pg_roles). However, the pg_user view displays only usersΒ  & roles with the LOGIN privilege, not all roles.

postgres=# CREATE USER rama;
CREATE ROLE
postgres=# SELECT rolname, rolcanlogin FROM pg_roles WHERE rolname = 'rama';
 rolname | rolcanlogin
---------+-------------
 rama    | t    <--------- CREATE USER auto-sets rolcanlogin = true 
(1 row)

postgres=#
postgres=# CREATE ROLE ravi;
CREATE ROLE
postgres=# SELECT rolname, rolcanlogin FROM pg_roles WHERE rolname = 'ravi';
 rolname | rolcanlogin
---------+-------------
 ravi    | f   <---------- CREATE ROLE leaves rolcanlogin = false
(1 row)

postgres=#

postgres-# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS
 rama      |
 ravi      | Cannot login

postgres-#

2. Creating Users and Roles

-- Login accounts
postgres=# CREATE USER raj WITH PASSWORD 'raj_pwd123';
CREATE ROLE
postgres=# CREATE USER sugi WITH PASSWORD 'sugi_pwd123';
CREATE ROLE
postgres=# CREATE USER teja WITH PASSWORD 'teja_pwd123';
CREATE ROLE
postgres=# CREATE USER gebadm WITH PASSWORD 'gebadm_pwd123';   <-- we will set as schema owner
CREATE ROLE
postgres=# CREATE USER gebusr WITH PASSWORD 'gebusr_pwd123';   <-- app read-only user
CREATE ROLE
postgres=#

-- NOLOGIN group roles (permission bundles)

postgres=# CREATE ROLE geb_ro NOLOGIN;  <-- read-only privilege bundle
CREATE ROLE 
postgres=# CREATE ROLE geb_rw NOLOGIN;  <-- read-write privilege bundle
CREATE ROLE
postgres=#
postgres=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 geb_ro    | Cannot login
 geb_rw    | Cannot login
 gebadm    |
 gebusr    |
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS
 raj       |
 rama      |
 ravi      | Cannot login
 sugi      |
 teja      |

postgres=#

Both users and roles are stored in the same PostgreSQL system catalog (pg_authid / pg_roles). However, the pg_user view displays only usersΒ  & roles with the LOGIN privilege, not all roles.
postgres=# select rolname from pg_roles;
           rolname
-----------------------------
 pg_database_owner
 pg_read_all_data
 pg_write_all_data
 pg_monitor
 pg_read_all_settings
 pg_read_all_stats
 pg_stat_scan_tables
 pg_read_server_files
 pg_write_server_files
 pg_execute_server_program
 pg_signal_backend
 pg_checkpoint
 pg_maintain
 pg_use_reserved_connections
 pg_create_subscription
 postgres
 rama
 ravi
 raj
 sugi
 teja
 gebadm
 gebusr
 geb_ro
 geb_rw
(25 rows)

postgres=#
postgres=# select usename from pg_user;
 usename
----------
 postgres
 rama
 raj
 sugi
 teja
 gebadm
 gebusr
(7 rows)

postgres=#

Roles like geb_ro and geb_rw never log in directly. Instead, real users get added to them with GRANT role TO user, which is far easier to manage than granting privileges to each person individually.

3. Databases, Schemas, and Ownership

Once the roles exist, you can create a database and schema owned by the appropriate role, then open the “door” to that schema for everyone who needs it.

postgres=# CREATE DATABASE gebua;
CREATE DATABASE
postgres=#
postgres=# \c gebua postgres
You are now connected to database "gebua" as user "postgres".
gebua=#
gebua=# CREATE SCHEMA geb AUTHORIZATION gebadm;
CREATE SCHEMA
gebua=# GRANT USAGE ON SCHEMA geb TO geb_ro, geb_rw, raj, sugi, teja;
GRANT
gebua=#

gebua=# \l gebua
                                                 List of databases
 Name  |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules | Access privileges
-------+----------+----------+-----------------+-------------+-------------+--------+-----------+-------------------
 gebua | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |
(1 row)

gebua=#
gebua=# \dn
      List of schemas
  Name  |       Owner
--------+-------------------
 geb    | gebadm
 public | pg_database_owner
(2 rows)

gebua=#
gebua=# \dn+
                                       List of schemas
  Name  |       Owner       |           Access privileges            |      Description
--------+-------------------+----------------------------------------+------------------------
 geb    | gebadm            | gebadm=UC/gebadm                      +|
        |                   | geb_ro=U/gebadm                       +|
        |                   | geb_rw=U/gebadm                       +|
        |                   | raj=U/gebadm                          +|
        |                   | sugi=U/gebadm                         +|
        |                   | teja=U/gebadm                          |
 public | pg_database_owner | pg_database_owner=UC/pg_database_owner+| standard public schema
        |                   | =U/pg_database_owner                   |
(2 rows)

gebua=#

U = USAGE privilege   <---- USAGE means the user can see that tables and other objects exist in the schema, but cannot view or modify their data unless additional permissions are granted.
C = CREATE privilege
postgres=# \c gebua gebadm
You are now connected to database "gebua" as user "gebadm".
gebua=>

gebua=> CREATE TABLE geb.dept ( dept_id SERIAL PRIMARY KEY, dept_name VARCHAR(100) NOT NULL);
CREATE TABLE
gebua=> CREATE TABLE geb.emp (emp_id SERIAL PRIMARY KEY, emp_name VARCHAR(100) NOT NULL,dept_id INT REFERENCES geb.dept(dept_id),salary NUMERIC(10,2));
CREATE TABLE
gebua=>
gebua=> \dt geb.*
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+--------
 geb    | dept | table | gebadm
 geb    | emp  | table | gebadm
(2 rows)

gebua=>
gebua=> INSERT INTO geb.dept (dept_name) VALUES ('Engineering'), ('Sales'), ('HR');
INSERT 0 3
gebua=> INSERT INTO geb.emp (emp_name, dept_id, salary) VALUES ('Arjun',  1, 75000),('Meena',  2, 65000),('Kabir',  3, 60000);
INSERT 0 3
gebua=>
gebua=> select * from emp;
ERROR:  relation "emp" does not exist
LINE 1: select * from emp;
                      ^
gebua=> select * from geb.emp;
 emp_id | emp_name | dept_id |  salary
--------+----------+---------+----------
      1 | Arjun    |       1 | 75000.00
      2 | Meena    |       2 | 65000.00
      3 | Kabir    |       3 | 60000.00
(3 rows)

gebua=> select * from geb.dept;
 dept_id |  dept_name
---------+-------------
       1 | Engineering
       2 | Sales
       3 | HR
(3 rows)

gebua=>

4. Granting Privileges on Existing Objects

GRANT SELECT ON ALL TABLES IN SCHEMA geb TO geb_ro; <------Will automatically give SELECT access to future tables. It does not.
This command grants permissions only to the tables that exist at the time you run it. Any tables created later will not receive these permissions automatically. To ensure that new tables also get the required permissions, you must use ALTER DEFAULT PRIVILEGES. 

-- Grant privilleges to RO (Read-only) role.

[postgres@pgdb02 ~]$ psql
psql (17.10)
Type "help" for help.

postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA geb TO geb_ro;
ERROR:  schema "geb" does not exist
postgres=#
postgres=# \c gebua
You are now connected to database "gebua" as user "postgres".
gebua=#
gebua=# GRANT SELECT ON ALL TABLES IN SCHEMA geb TO geb_ro;
GRANT
gebua=# GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA geb TO geb_ro;
GRANT
gebua=#

-- Grant privilleges to RW (Read-Write) role.
gebua=# GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA geb TO geb_rw;
GRANT
gebua=# GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA geb TO geb_rw;
GRANT
gebua=#
-- Assign RO role to user
gebua=# GRANT geb_ro TO gebusr;
GRANT ROLE
gebua=#

gebua=# \dp geb.*
                                      Access privileges
 Schema |       Name       |   Type   |   Access privileges    | Column privileges | Policies
--------+------------------+----------+------------------------+-------------------+----------
 geb    | dept             | table    | gebadm=arwdDxtm/gebadm+|                   |
        |                  |          | geb_ro=r/gebadm       +|                   |
        |                  |          | geb_rw=arwd/gebadm     |                   |
 geb    | dept_dept_id_seq | sequence | gebadm=rwU/gebadm     +|                   |
        |                  |          | geb_ro=rU/gebadm      +|                   |
        |                  |          | geb_rw=rU/gebadm       |                   |
 geb    | emp              | table    | gebadm=arwdDxtm/gebadm+|                   |
        |                  |          | geb_ro=r/gebadm       +|                   |
        |                  |          | geb_rw=arwd/gebadm     |                   |
 geb    | emp_emp_id_seq   | sequence | gebadm=rwU/gebadm     +|                   |
        |                  |          | geb_ro=rU/gebadm      +|                   |
        |                  |          | geb_rw=rU/gebadm       |                   |
(4 rows)

gebua=#

| Code | Meaning    |
| ---- | ---------- |
| r    | SELECT     |
| a    | INSERT     |
| w    | UPDATE     |
| d    | DELETE     |
| D    | TRUNCATE   |
| x    | REFERENCES |
| t    | TRIGGER    |
| m    | MAINTAIN   |  <------

What is m (MAINTAIN)?

The MAINTAIN privilege allows operations such as:
VACUUM
ANALYZE
REINDEX
CLUSTER
REFRESH MATERIALIZED VIEW
LOCK TABLE

-- Verify 
[postgres@pgdb02 ~]$ psql -d gebua -U gebusr
psql (17.10)
Type "help" for help.

gebua=> \c
You are now connected to database "gebua" as user "gebusr".
gebua=>
gebua=> \dt geb.*
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+--------
 geb    | dept | table | gebadm
 geb    | emp  | table | gebadm
(2 rows)

gebua=> select * from geb.emp;
 emp_id | emp_name | dept_id |  salary
--------+----------+---------+----------
      1 | Arjun    |       1 | 75000.00
      2 | Meena    |       2 | 65000.00
      3 | Kabir    |       3 | 60000.00
(3 rows)

gebua=> select * from geb.dept;
 dept_id |  dept_name
---------+-------------
       1 | Engineering
       2 | Sales
       3 | HR
(3 rows)

gebua=>

5. Default Privileges for Future Objects

ALTER DEFAULT PRIVILEGES allows you to define permissions that will be automatically granted to future objects created by a specific role.

In this example, whenever gebadm creates a new table in the geb schema:

  • geb_ro automatically receives SELECT permission (read-only access).
  • geb_rw automatically receives SELECT, INSERT, UPDATE, and DELETE permissions (read-write access).
-- For RO Role

gebua=# \c
You are now connected to database "gebua" as user "postgres".

gebua=# ALTER DEFAULT PRIVILEGES FOR ROLE gebadm IN SCHEMA geb GRANT SELECT ON TABLES TO geb_ro;
ALTER DEFAULT PRIVILEGES
gebua=# ALTER DEFAULT PRIVILEGES FOR ROLE gebadm IN SCHEMA geb GRANT USAGE, SELECT ON SEQUENCES TO geb_ro;
ALTER DEFAULT PRIVILEGES
gebua=#

-- For RW Role

gebua=# ALTER DEFAULT PRIVILEGES FOR ROLE gebadm IN SCHEMA geb GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO geb_rw;
ALTER DEFAULT PRIVILEGES
gebua=# ALTER DEFAULT PRIVILEGES FOR ROLE gebadm IN SCHEMA geb GRANT USAGE, SELECT ON SEQUENCES TO geb_rw;
ALTER DEFAULT PRIVILEGES
gebua=#

-- Live proof: a brand-new table already has the right grants

[postgres@pgdb02 ~]$ psql -d gebua -U gebadm
psql (17.10)
Type "help" for help.

gebua=> \c
You are now connected to database "gebua" as user "gebadm".
gebua=>
gebua=> CREATE TABLE geb.payroll (payroll_id SERIAL PRIMARY KEY, amount NUMERIC);
CREATE TABLE

gebua=> INSERT INTO geb.payroll (amount) VALUES (50000.00);
INSERT 0 1
gebua=>
gebua=> \dp geb.payroll
                                Access privileges
 Schema |  Name   | Type  |   Access privileges    | Column privileges | Policies
--------+---------+-------+------------------------+-------------------+----------
 geb    | payroll | table | gebadm=arwdDxtm/gebadm+|                   |
        |         |       | geb_ro=r/gebadm       +|                   |
        |         |       | geb_rw=arwd/gebadm     |                   |
(1 row)

gebua=>

ALTER DEFAULT PRIVILEGES allows you to define permissions that will be automatically granted to future objects.

[postgres@pgdb02 ~]$ psql -d gebua -U gebusr
psql (17.10)
Type "help" for help.

gebua=> \c
You are now connected to database "gebua" as user "gebusr".
gebua=>
gebua=> select * from geb.payroll;
 payroll_id |  amount
------------+----------
          1 | 50000.00    <------
(1 row)

gebua=>

6. Per-User, Per-Table Grants and Revokes

Sometimes you want a single user to see exactly one table, with no role membership involved:

postgres=# \c gebua
You are now connected to database "gebua" as user "postgres".

gebua=# GRANT SELECT ON geb.emp TO raj;
GRANT
gebua=# GRANT SELECT ON geb.dept TO sugi;
GRANT
gebua=# GRANT SELECT ON geb.payroll TO teja;
GRANT
gebua=#

-- Schema level 
gebua=# \dn+ geb
                 List of schemas
 Name | Owner  | Access privileges | Description
------+--------+-------------------+-------------
 geb  | gebadm | gebadm=UC/gebadm +|
      |        | geb_ro=U/gebadm  +|
      |        | geb_rw=U/gebadm  +|
      |        | raj=U/gebadm     +|
      |        | sugi=U/gebadm    +|
      |        | teja=U/gebadm     |
(1 row)

gebua=#

-- Table Level 
gebua-# \dp geb.*
                                         Access privileges
 Schema |          Name          |   Type   |   Access privileges    | Column privileges | Policies
--------+------------------------+----------+------------------------+-------------------+----------
 geb    | dept                   | table    | gebadm=arwdDxtm/gebadm+|                   |
        |                        |          | geb_ro=r/gebadm       +|                   |
        |                        |          | geb_rw=arwd/gebadm    +|                   |
        |                        |          | sugi=r/gebadm          |                   |
 geb    | dept_dept_id_seq       | sequence | gebadm=rwU/gebadm     +|                   |
        |                        |          | geb_ro=rU/gebadm      +|                   |
        |                        |          | geb_rw=rU/gebadm       |                   |
 geb    | emp                    | table    | gebadm=arwdDxtm/gebadm+|                   |
        |                        |          | geb_ro=r/gebadm       +|                   |
        |                        |          | geb_rw=arwd/gebadm    +|                   |
        |                        |          | raj=r/gebadm           |                   |
 geb    | emp_emp_id_seq         | sequence | gebadm=rwU/gebadm     +|                   |
        |                        |          | geb_ro=rU/gebadm      +|                   |
        |                        |          | geb_rw=rU/gebadm       |                   |
 geb    | payroll                | table    | gebadm=arwdDxtm/gebadm+|                   |
        |                        |          | geb_ro=r/gebadm       +|                   |
        |                        |          | geb_rw=arwd/gebadm    +|                   |
        |                        |          | teja=r/gebadm          |                   |
 geb    | payroll_payroll_id_seq | sequence | gebadm=rwU/gebadm     +|                   |
        |                        |          | geb_ro=rU/gebadm      +|                   |
        |                        |          | geb_rw=rU/gebadm       |                   |
(6 rows)

gebua-#

=== LIVE TEST: raj can read emp, but NOT dept/hr ===

gebua-# \c gebua raj
You are now connected to database "gebua" as user "raj".
gebua->
gebua=>
gebua=> SELECT * FROM geb.emp;
 emp_id | emp_name | dept_id |  salary
--------+----------+---------+----------
      1 | Arjun    |       1 | 75000.00
      2 | Meena    |       2 | 65000.00
      3 | Kabir    |       3 | 60000.00
(3 rows)

gebua=>
gebua=> SELECT * FROM geb.dept;
ERROR: permission denied for table dept
gebua=>
gebua=> SELECT * FROM geb.hr;
ERROR: relation "geb.hr" does not exist
LINE 1: SELECT * FROM geb.hr;
^
gebua=>

=== LIVE TEST: sugi can read dept, but NOT emp/hr ===

gebua=> \c gebua sugi
You are now connected to database "gebua" as user "sugi".
gebua=>
gebua=> SELECT * FROM geb.dept;
 dept_id |  dept_name
---------+-------------
       1 | Engineering
       2 | Sales
       3 | HR
(3 rows)

gebua=> SELECT * FROM geb.emp;
ERROR:  permission denied for table emp
gebua=>
gebua=> SELECT * FROM geb.hr;
ERROR:  relation "geb.hr" does not exist
LINE 1: SELECT * FROM geb.hr;
                      ^
gebua=>


=== LIVE TEST: teja can read hr, but NOT emp/dept ===

gebua=> \c gebua teja
You are now connected to database "gebua" as user "teja".
gebua=>
gebua=> SELECT * FROM geb.payroll;
 payroll_id |  amount
------------+----------
          1 | 50000.00
(1 row)

gebua=> SELECT * FROM geb.emp;
ERROR:  permission denied for table emp
gebua=>
gebua=> SELECT * FROM geb.dept;
ERROR:  permission denied for table dept
gebua=>

Each of these users has no membership in geb_ro or geb_rw β€” they get exactly the one table explicitly granted, nothing more. Taking access away later uses REVOKE.

--- Revoke
[postgres@pgdb02 ~]$ psql
psql (17.10)
Type "help" for help.

postgres=# \c gebua
You are now connected to database "gebua" as user "postgres".
gebua=# REVOKE SELECT ON geb.emp  FROM raj;
REVOKE
gebua=# REVOKE SELECT ON geb.dept FROM sugi;
REVOKE
gebua=# REVOKE SELECT ON geb.payroll   FROM teja;
REVOKE
gebua=#
gebua=# \dp geb.emp;
                               Access privileges
 Schema | Name | Type  |   Access privileges    | Column privileges | Policies
--------+------+-------+------------------------+-------------------+----------
 geb    | emp  | table | gebadm=arwdDxtm/gebadm+|                   |
        |      |       | geb_ro=r/gebadm       +|                   |
        |      |       | geb_rw=arwd/gebadm     |                   |
(1 row)

gebua=# \dp geb.dept;
                               Access privileges
 Schema | Name | Type  |   Access privileges    | Column privileges | Policies
--------+------+-------+------------------------+-------------------+----------
 geb    | dept | table | gebadm=arwdDxtm/gebadm+|                   |
        |      |       | geb_ro=r/gebadm       +|                   |
        |      |       | geb_rw=arwd/gebadm     |                   |
(1 row)

gebua=# \dp geb.payroll;
                                Access privileges
 Schema |  Name   | Type  |   Access privileges    | Column privileges | Policies
--------+---------+-------+------------------------+-------------------+----------
 geb    | payroll | table | gebadm=arwdDxtm/gebadm+|                   |
        |         |       | geb_ro=r/gebadm       +|                   |
        |         |       | geb_rw=arwd/gebadm     |                   |
(1 row)

gebua=#
gebua=# \c gebua raj
You are now connected to database "gebua" as user "raj".
gebua=> select * from geb.emp;
ERROR:  permission denied for table emp
gebua=>
gebua=> \c gebua sugi;
You are now connected to database "gebua" as user "sugi".
gebua=>
gebua=> select * from geb.dept;
ERROR:  permission denied for table dept
gebua=>
gebua=> \c gebua teja
You are now connected to database "gebua" as user "teja".
gebua=>
gebua=> select * from geb.payroll;
ERROR:  permission denied for table payroll
gebua=>

-- Re GRANT 

gebua=# \c
You are now connected to database "gebua" as user "postgres".
gebua=# GRANT SELECT ON geb.emp TO raj;
GRANT
gebua=# GRANT SELECT ON geb.dept TO sugi;
GRANT
gebua=# GRANT SELECT ON geb.payroll TO teja;
GRANT
gebua=#

You can confirm what’s actually in effect with \dn+ geb (schema-level owner and ACL) and \dp geb.* (table-level ACL for every object).

7. The PUBLIC Pseudo-Role

Every role you create β€” including ones that don’t exist yet β€” is automatically and silently a member of PUBLIC. You never grant membership to it; it’s implicit and universal. Anything granted “TO PUBLIC” is inherited by every current and future user.

Fresh databases ship with a few defaults granted to PUBLIC:

  • CONNECT and TEMP on every new database
  • EXECUTE on every newly created function or procedure
  • USAGE + CREATE on the public schema (PG < 15 only β€” PG15+ removed CREATE from PUBLIC by default)

gebua=# \c gebua raj
You are now connected to database “gebua” as user “raj”.
gebua=> create table test (id init);
ERROR: permission denied for schema public
LINE 1: create table test (id init);
^
gebua=>

gebua=> \c gebua postgres
You are now connected to database "gebua" as user "postgres".
gebua=# REVOKE ALL ON DATABASE gebua FROM PUBLIC;
REVOKE
gebua=# REVOKE ALL ON SCHEMA public FROM PUBLIC;
REVOKE
gebua=#

gebua=# \c gebua raj
connection to server on socket "/run/postgresql/.s.PGSQL.5432" failed: FATAL: permission denied for database "gebua"
DETAIL: User does not have CONNECT privilege.
Previous connection kept
gebua=#

gebua=# GRANT CONNECT ON DATABASE gebua TO raj, sugi, teja, gebadm, gebusr;
GRANT
gebua=#
gebua=# \c gebua raj
You are now connected to database "gebua" as user "raj".
gebua=>

8. GRANT ALL

GRANT ALL is broader than it sounds. On a table, it grants every applicable privilege β€” SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER β€” not just the common four.

The extra three matter:

  • TRUNCATE β€” can wipe the entire table instantly
  • REFERENCES β€” can create a foreign key pointing at this table
  • TRIGGER β€” can create triggers on this table
gebua=# CREATE USER anu WITH PASSWORD 'anu';
CREATE ROLE
gebua=# GRANT CONNECT ON DATABASE GEBUA TO ANU;
GRANT
gebua=# GRANT ALL PRIVILEGES ON GEB.EMP TO ANU;
GRANT
gebua=#
gebua=# \dp geb.emp;
                               Access privileges
 Schema | Name | Type  |   Access privileges    | Column privileges | Policies
--------+------+-------+------------------------+-------------------+----------
 geb    | emp  | table | gebadm=arwdDxtm/gebadm+|                   |
        |      |       | geb_ro=r/gebadm       +|                   |
        |      |       | geb_rw=arwd/gebadm    +|                   |
        |      |       | raj=r/gebadm          +|                   |
        |      |       | anu=arwdDxtm/gebadm    |                   |
(1 row)

gebua=#

9. Inspecting Roles: pg_roles, pg_user, pg_shadow, pg_group

PostgreSQL exposes several system catalogs for auditing roles, each with a different scope:

  • pg_roles β€” all roles, both login users and NOLOGIN roles.
  • pg_user β€” a view filtered from pg_roles showing only roles where rolcanlogin = true. Roles like geb_ro/geb_rw never appear here.
  • pg_shadow β€” password hashes (SCRAM/MD5, never plaintext), visible only to superusers or for your own row.
  • pg_group β€” a legacy compatibility view predating the unified role system; it only lists NOLOGIN roles and derives its data live from pg_auth_members.

For a complete, modern view of role memberships β€” including login roles that are members of other roles β€” query pg_auth_members directly:

gebua=# select * from pg_roles;
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig |  oid
-----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+-------------+---------------+--------------+-----------+-------
 pg_database_owner           | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  6171
 pg_read_all_data            | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  6181
 pg_write_all_data           | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  6182
 pg_monitor                  | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  3373
 pg_read_all_settings        | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  3374
 pg_read_all_stats           | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  3375
 pg_stat_scan_tables         | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  3377
 pg_read_server_files        | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  4569
 pg_write_server_files       | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  4570
 pg_execute_server_program   | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  4571
 pg_signal_backend           | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  4200
 pg_checkpoint               | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  4544
 pg_maintain                 | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  6337
 pg_use_reserved_connections | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  4550
 pg_create_subscription      | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           |  6304
 postgres                    | t        | t          | t             | t           | t           | t              |           -1 | ********    |               | t            |           |    10
 rama                        | f        | t          | f             | f           | t           | f              |           -1 | ********    |               | f            |           | 41527
 ravi                        | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           | 41528
 raj                         | f        | t          | f             | f           | t           | f              |           -1 | ********    |               | f            |           | 41531
 sugi                        | f        | t          | f             | f           | t           | f              |           -1 | ********    |               | f            |           | 41532
 teja                        | f        | t          | f             | f           | t           | f              |           -1 | ********    |               | f            |           | 41533
 gebadm                      | f        | t          | f             | f           | t           | f              |           -1 | ********    |               | f            |           | 41534
 gebusr                      | f        | t          | f             | f           | t           | f              |           -1 | ********    |               | f            |           | 41535
 geb_ro                      | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           | 41536
 geb_rw                      | f        | t          | f             | f           | f           | f              |           -1 | ********    |               | f            |           | 41537
 anu                         | f        | t          | f             | f           | t           | f              |           -1 | ********    |               | f            |           | 41572
(26 rows)

gebua=#
gebua=# select * from pg_user;
 usename  | usesysid | usecreatedb | usesuper | userepl | usebypassrls |  passwd  | valuntil | useconfig
----------+----------+-------------+----------+---------+--------------+----------+----------+-----------
 postgres |       10 | t           | t        | t       | t            | ******** |          |
 rama     |    41527 | f           | f        | f       | f            | ******** |          |
 raj      |    41531 | f           | f        | f       | f            | ******** |          |
 sugi     |    41532 | f           | f        | f       | f            | ******** |          |
 teja     |    41533 | f           | f        | f       | f            | ******** |          |
 gebadm   |    41534 | f           | f        | f       | f            | ******** |          |
 gebusr   |    41535 | f           | f        | f       | f            | ******** |          |
 anu      |    41572 | f           | f        | f       | f            | ******** |          |
(8 rows)

gebua=#

gebua=# select * from pg_shadow;
 usename  | usesysid | usecreatedb | usesuper | userepl | usebypassrls |                                                                passwd                                                                 | valuntil | useconfig
----------+----------+-------------+----------+---------+--------------+---------------------------------------------------------------------------------------------------------------------------------------+----------+-----------
 postgres |       10 | t           | t        | t       | t            | SCRAM-SHA-256$4096:IXXmstZ3yAPBDYk9SaYwoQ==$XERgxvz+WfnEzw0FO5wdHWgkZDNXGTJwh+9ku0fAHUE=:i9zQsVpTsUxxBpe3Rs08ValuokiqjnrNHjtk9eKDT8A= |          |
 rama     |    41527 | f           | f        | f       | f            |                                                                                                                                       |          |
 raj      |    41531 | f           | f        | f       | f            | SCRAM-SHA-256$4096:83y0vE12G/RH9B6pxOx9FA==$lYuVyvhTsvaGvjUXqWBir2F34gZLq7C7fW3zg8L6jZA=:R1PzeM8NTQjT0kHUASeSgnSXhFWiX5dcTwd9fNiy7Lg= |          |
 sugi     |    41532 | f           | f        | f       | f            | SCRAM-SHA-256$4096:obX6SJ88dSoqJDh9YgKQ6Q==$sH5xVe6Li+95vTluTyell1y/IUIVbip9nUINWkQirQk=:SpJjKrDCnv3LNvwZBzoh6nY23D9fCCtKNYoMl9AKpKg= |          |
 teja     |    41533 | f           | f        | f       | f            | SCRAM-SHA-256$4096:VD9NCq0s1UbQv/ucdEtOMg==$FaWKK/ovAC45oxgOfGKmTqNQqvavQaPdKRUGEgAi7Rc=:EQwYGJhvD89OGrkqVrOWr27I0OftzNgdO7kiZgGnaPM= |          |
 gebadm   |    41534 | f           | f        | f       | f            | SCRAM-SHA-256$4096:Xo6mPeiuPXBaIqN6tFbH7Q==$WG4m8yARZ9ZV40H7HgZVkG5TrvS83HgSFj59Uc1GlWo=:p/1zT72iOnajg7dwwo9xjmD2wRIuOugtr/0lJWXA6t0= |          |
 gebusr   |    41535 | f           | f        | f       | f            | SCRAM-SHA-256$4096:mvnPDdeNDh+olgPT6d05Yg==$19cDwk3Yy/hQRC8SmGcgHkwoHT86YFkYHAsdRTatzyQ=:CZupkFOFhqRIyK4LUhg7OcQZFpzpKB8VKdzNZphrkrQ= |          |
 anu      |    41572 | f           | f        | f       | f            | SCRAM-SHA-256$4096:mXGdfJgtLi3531WT+4S93g==$wlYQ1SLzh0aNcESBEQ7jVgLkQqr4F6d674xQsNpSo1U=:WRudEkJcQvuHqcOpTgqWf6wQlizqPcS9MJ6lyT2AsyI= |          |
(8 rows)

gebua=# select * from pg_authid;

gebua=# SELECT * FROM pg_ident_file_mappings;
 map_number | file_name | line_number | map_name | sys_name | pg_username | error
------------+-----------+-------------+----------+----------+-------------+-------
(0 rows)

gebua=#

gebua=# select * from pg_group;
           groname           | grosysid | grolist
-----------------------------+----------+---------
 pg_database_owner           |     6171 | {}
 pg_read_all_data            |     6181 | {}
 pg_write_all_data           |     6182 | {}
 pg_monitor                  |     3373 | {}
 pg_read_all_settings        |     3374 | {3373}
 pg_read_all_stats           |     3375 | {3373}
 pg_stat_scan_tables         |     3377 | {3373}
 pg_read_server_files        |     4569 | {}
 pg_write_server_files       |     4570 | {}
 pg_execute_server_program   |     4571 | {}
 pg_signal_backend           |     4200 | {}
 pg_checkpoint               |     4544 | {}
 pg_maintain                 |     6337 | {}
 pg_use_reserved_connections |     4550 | {}
 pg_create_subscription      |     6304 | {}
 ravi                        |    41528 | {}
 geb_ro                      |    41536 | {41535}
 geb_rw                      |    41537 | {}
(18 rows)

gebua=#

-- Granted Roles
gebua=# SELECT r.rolname AS member, g.rolname AS granted_role FROM pg_auth_members m JOIN pg_roles r ON m.member = r.oid JOIN pg_roles g ON m.roleid = g.oid ORDER BY g.rolname, r.rolname;
   member   |     granted_role
------------+----------------------
 gebusr     | geb_ro
 pg_monitor | pg_read_all_settings
 pg_monitor | pg_read_all_stats
 pg_monitor | pg_stat_scan_tables
(4 rows)

gebua=#

One more distinction worth clearing up: pg_ident.conf is not a password catalog at all. It’s a config file mapping OS-level usernames to Postgres role names, used only for ident/peer/GSSAPI/cert authentication. It contains zero passwords β€” pg_shadow answers “is this the right password for this role?”, while pg_ident answers “which Postgres role does this externally-authenticated identity map to?”

10. Password Management

PostgreSQL has no native equivalent to “force password change on first login.” The closest built-in tool is VALID UNTIL, which can only block login after a timestamp β€” it can’t force a change flow. Common workarounds:

  • Set VALID UNTIL to a timestamp already in the past, so the account is “pre-expired” and a DBA must reset it before the user’s first login.
  • Track a must_change_password flag in your own application table and enforce it in app logic.
  • Use community extensions like passwordcheck or credcheck for complexity/expiry policy enforcement.
gebua=# show password_encryption;
 password_encryption
---------------------
 scram-sha-256
(1 row)

gebua=#

-- Change Your Own Password After Login

[postgres@pgdb02 ~]$ psql -d postgres -U raj
psql (17.10)
Type "help" for help.

postgres=> \password
Enter new password for user "raj":
Enter it again:
postgres=>



[postgres@pgdb02 data]$ PGPASSWORD='raj_pwd123' psql -h 192.168.2.23 -d gebua -U raj
psql (17.10)
Type "help" for help.

gebua=> \c
You are now connected to database "gebua" as user "raj".
gebua=>

-- Simulate a "pre-expired" account

gebua=# ALTER USER raj VALID UNTIL '2020-01-01';
ALTER ROLE
gebua=# SELECT usename, valuntil FROM pg_user WHERE usename = 'raj';
 usename |        valuntil
---------+------------------------
 raj     | 2020-01-01 00:00:00+08   <------------
(1 row)

gebua=# \du raj
                      List of roles
 Role name |                 Attributes
-----------+---------------------------------------------
 raj       | Password valid until 2020-01-01 00:00:00+08

gebua=#

[postgres@pgdb02 data]$ cat pg_hba.conf | grep -i raj
host       gebua         raj            0.0.0.0/0              md5
[postgres@pgdb02 data]$

[postgres@pgdb02 data]$ pg_ctl reload -D /pgData/pgsql17/data/
server signaled
[postgres@pgdb02 data]$

[postgres@pgdb02 data]$ PGPASSWORD='raj_pwd123' psql -h 192.168.2.23 -d gebua -U raj
psql: error: connection to server at "192.168.2.23", port 5432 failed: FATAL: password authentication failed for user "raj"
[postgres@pgdb02 data]$ 

-- Extend validity again later

ALTER USER raj VALID UNTIL '2027-08-06'; ---- OR ------ ALTER USER raj VALID UNTIL 'infinity';

postgres=# ALTER USER raj VALID UNTIL 'infinity';
ALTER ROLE
postgres=# exit
[postgres@pgdb02 data]$ PGPASSWORD='raj_pwd123' psql -h 192.168.2.23 -d gebua -U raj
psql (17.10)
Type "help" for help.

gebua=> \c
You are now connected to database "gebua" as user "raj".
gebua=>

postgres=# \du raj
               List of roles
 Role name |          Attributes
-----------+-------------------------------
 raj       | Password valid until infinity

postgres=#

--- Restore the OLD password using the saved hash

[postgres@pgdb02 data]$ cat pg_hba.conf | grep -i anu
host         gebua         raj,anu              0.0.0.0/0         md5
[postgres@pgdb02 data]$
[postgres@pgdb02 data]$ pg_ctl reload -D /pgData/pgsql17/data/
server signaled
[postgres@pgdb02 data]$ 

[postgres@pgdb02 data]$ PGPASSWORD='anu' psql -h 192.168.2.23 -d gebua -U anu
psql (17.10)
Type "help" for help.

gebua=> 

1. Show current hash

select rolpassword from pg_authid where rolname='anu';

--- OR ---
postgres=# SELECT usename, passwd FROM pg_shadow WHERE usename = 'anu';
 usename |                                                                passwd
---------+---------------------------------------------------------------------------------------------------------------------------------------
 anu     | SCRAM-SHA-256$4096:mXGdfJgtLi3531WT+4S93g==$wlYQ1SLzh0aNcESBEQ7jVgLkQqr4F6d674xQsNpSo1U=:WRudEkJcQvuHqcOpTgqWf6wQlizqPcS9MJ6lyT2AsyI=
(1 row)

postgres=#

2. Change password (simulate "forgot to save old one")

postgres=# ALTER USER anu WITH PASSWORD 'temporary_new_pass';
ALTER ROLE
postgres=#

3. "Restore" old password using saved hash string

[postgres@pgdb02 ~]$ PGPASSWORD='anu' psql -h 192.168.2.23 -d gebua -U anu
psql: error: connection to server at "192.168.2.23", port 5432 failed: FATAL: password authentication failed for user "anu"
[postgres@pgdb02 ~]$

postgres=# \c
You are now connected to database "postgres" as user "postgres".
postgres=#
postgres=# ALTER USER anu WITH PASSWORD 'SCRAM-SHA-256$4096:mXGdfJgtLi3531WT+4S93g==$wlYQ1SLzh0aNcESBEQ7jVgLkQqr4F6d674xQsNpSo1U=:WRudEkJcQvuHqcOpTgqWf6wQlizqPcS9MJ6lyT2AsyI=';
ALTER ROLE
postgres=#

4. Confirm hash matches original

postgres=# SELECT usename, passwd FROM pg_shadow WHERE usename = 'anu';
 usename |                                                                passwd
---------+---------------------------------------------------------------------------------------------------------------------------------------
 anu     | SCRAM-SHA-256$4096:mXGdfJgtLi3531WT+4S93g==$wlYQ1SLzh0aNcESBEQ7jVgLkQqr4F6d674xQsNpSo1U=:WRudEkJcQvuHqcOpTgqWf6wQlizqPcS9MJ6lyT2AsyI=
(1 row)

postgres=#

5. Login test β€” original plaintext password works again
[postgres@pgdb02 ~]$ PGPASSWORD='anu' psql -h 192.168.2.23 -d gebua -U anu
psql (17.10)
Type "help" for help.

gebua=> \c
You are now connected to database "gebua" as user "anu".
gebua=>

Note: Resetting the password does not extend the account's validity. The password will still expire unless you update it using one of the following commands
 ALTER USER raj VALID UNTIL '2027-08-06'; ---- OR ------ ALTER USER raj VALID UNTIL 'infinity';

Note that VALID UNTIL only controls the time window β€” it never touches the password hash itself. Extending expiry, without also running ALTER USER ... PASSWORD, leaves the original password value completely unchanged. Postgres also deliberately shows the same generic authentication error for an expired account as for a wrong password, so failed logins don’t leak the cause.

11. session_user vs. current_user

These two functions answer different questions:

  • session_user β€” the role that actually authenticated the connection. Fixed for the whole session.
  • current_user β€” the role whose privileges are being checked right now for the current statement. Changes with SET ROLE, or inside a SECURITY DEFINER function.
---- Difference between session_user and current_user
postgres=# SELECT current_user, session_user;
 current_user | session_user
--------------+--------------
 postgres     | postgres
(1 row)

postgres=# \c postgres sam
You are now connected to database "postgres" as user "sam".
postgres=>
postgres=> SELECT current_user, session_user;
 current_user | session_user
--------------+--------------
 sam          | sam
(1 row)

postgres=>
postgres=> \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=#
postgres=# SET ROLE sam;
SET
postgres=>
postgres=> SELECT current_user, session_user;
 current_user | session_user
--------------+--------------
 sam          | postgres
(1 row)

postgres=>
postgres=> CREATE TABLE test(a int);
ERROR:  permission denied for schema public
LINE 1: CREATE TABLE test(a int);
                     ^
postgres=>
postgres=> SET ROLE NONE;
SET
postgres=#
postgres=# SELECT current_user, session_user;
 current_user | session_user
--------------+--------------
 postgres     | postgres
(1 row)

postgres=#

--- SET SESSION AUTHORIZATION
postgres=# SET SESSION AUTHORIZATION sam;
SET
postgres=>
postgres=> SELECT current_user, session_user;
 current_user | session_user
--------------+--------------
 sam          | sam
(1 row)

postgres=> CREATE TABLE test(a int);
ERROR:  permission denied for schema public
LINE 1: CREATE TABLE test(a int);
                     ^
postgres=> SET ROLE NONE;
SET
postgres=>
postgres=> SELECT current_user, session_user;
 current_user | session_user
--------------+--------------
 sam          | sam
(1 row)

postgres=> RESET ROLE;
RESET
postgres=> SELECT current_user, session_user;
 current_user | session_user
--------------+--------------
 sam          | sam
(1 row)

postgres=> \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=#
postgres=# SELECT current_user, session_user;
 current_user | session_user
--------------+--------------
 postgres     | postgres
(1 row)

postgres=#

12. search_path

gebua=# 
postgres=# \c gebua
You are now connected to database "gebua" as user "postgres".
gebua=#
gebua=# show search_path;
   search_path
-----------------
 "$user", public
(1 row)

gebua=# \dt geb.*
         List of relations
 Schema |  Name   | Type  | Owner
--------+---------+-------+--------
 geb    | dept    | table | gebadm
 geb    | emp     | table | gebadm
 geb    | payroll | table | gebadm
(3 rows)

gebua=# select * from geb.emp;
 emp_id | emp_name | dept_id |  salary
--------+----------+---------+----------
      1 | Arjun    |       1 | 75000.00
      2 | Meena    |       2 | 65000.00
      3 | Kabir    |       3 | 60000.00
(3 rows)

gebua=#
gebua=# select * from emp;
ERROR:  relation "emp" does not exist
LINE 1: select * from emp;
                      ^
gebua=#
gebua=# SET search_path to geb;
SET
gebua=# show search_path;
 search_path
-------------
 geb   <------------
(1 row)

gebua=# select * from emp;
 emp_id | emp_name | dept_id |  salary
--------+----------+---------+----------
      1 | Arjun    |       1 | 75000.00
      2 | Meena    |       2 | 65000.00
      3 | Kabir    |       3 | 60000.00
(3 rows)

gebua=#

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/

Types of Shutdown in PostgreSQL

Types of Shutdown in PostgreSQL

PostgreSQL Shutdown TypeOracleBehavior
Smart (SIGTERM)SHUTDOWN NORMALThe server stops accepting new connections but allows existing sessions to continue running normally. PostgreSQL shuts down only after all active sessions disconnect and their transactions complete successfully.
Fast (SIGINT – Default)SHUTDOWN IMMEDIATEThe server stops accepting new connections and immediately terminates all active sessions. Any uncommitted transactions are rolled back, and PostgreSQL performs a clean shutdown gracefully.
Immediate (SIGQUIT)SHUTDOWN ABORTThe server terminates all processes instantly without performing a proper shutdown. No cleanup or checkpoint occurs, so PostgreSQL performs crash recovery by replaying WAL files during the next startup.
Shutdown TypeSignalCommand ExampleBehavior
SmartSIGTERMpg_ctl stop -D /pgData -m smartStops new connections, waits for existing sessions to finish normally, then shuts down.
Fast (Default)SIGINTpg_ctl stop -D /pgdata -m fastStops new connections, terminates active sessions, rolls back uncommitted transactions, and shuts down cleanly.
ImmediateSIGQUITpg_ctl stop -D /pgdata -m immediateStops immediately without proper shutdown. Recovery from WAL files happens during next startup.

Difference Between Reload and Restart

  • When we change server configuration parameters, PostgreSQL needs to read those changes before they become active.
  • Reload applies the new configuration without stopping or restarting the database service. Existing connections and database activity continue normally.
  • Some configuration parameter changes cannot be applied through reload and will only take effect after a restart.
  • Restart stops the PostgreSQL server gracefully, ends all running activities, releases resources, closes open files, and then starts the server again with the new configuration.

 

Smart Shutdown (SIGTERM):

[postgres@pgdb02 ~]$ pg_ctl stop -D /pgData/pgsql17/data -m smart
waiting for server to shut down.... done
server stopped
[postgres@pgdb02 ~]$

2026-07-03 14:26:59.741 +08 [3476] LOG:  received smart shutdown request
2026-07-03 14:26:59.752 +08 [3476] LOG:  background worker "logical replication launcher" (PID 3483) exited with exit code 1
2026-07-03 14:26:59.753 +08 [3478] LOG:  shutting down
2026-07-03 14:26:59.755 +08 [3478] LOG:  checkpoint starting: shutdown immediate
2026-07-03 14:26:59.765 +08 [3478] LOG:  checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.002 s, sync=0.003 s, total=0.012 s; sync files=2, longest=0.003 s, average=0.002 s; distance=0 kB, estimate=0 kB; lsn=1/105465F0, redo lsn=1/105465F0
2026-07-03 14:26:59.771 +08 [3476] LOG:  database system is shut down


[postgres@pgdb02 ~]$ pg_ctl start -D /pgData/pgsql17/data
waiting for server to start....2026-07-03 14:27:18.394 +08 [3487] LOG:  redirecting log output to logging collector process
2026-07-03 14:27:18.394 +08 [3487] HINT:  Future log output will appear in directory "log".
 done
server started
[postgres@pgdb02 ~]$

2026-07-03 14:27:18.394 +08 [3487] LOG:  starting PostgreSQL 17.10 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-14), 64-bit
2026-07-03 14:27:18.396 +08 [3487] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2026-07-03 14:27:18.396 +08 [3487] LOG:  listening on IPv6 address "::", port 5432
2026-07-03 14:27:18.399 +08 [3487] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2026-07-03 14:27:18.404 +08 [3487] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2026-07-03 14:27:18.413 +08 [3491] LOG:  database system was shut down at 2026-07-03 14:26:59 +08
2026-07-03 14:27:18.425 +08 [3487] LOG:  database system is ready to accept connections

Fast Shutdown (SIGINT – Default):

[postgres@pgdb02 ~]$ pg_ctl stop -D /pgData/pgsql17/data -m fast
waiting for server to shut down.... done
server stopped
[postgres@pgdb02 ~]$

2026-07-03 14:28:26.839 +08 [3487] LOG:  received fast shutdown request
2026-07-03 14:28:26.844 +08 [3487] LOG:  aborting any active transactions
2026-07-03 14:28:26.854 +08 [3487] LOG:  background worker "logical replication launcher" (PID 3494) exited with exit code 1
2026-07-03 14:28:26.860 +08 [3489] LOG:  shutting down
2026-07-03 14:28:26.862 +08 [3489] LOG:  checkpoint starting: shutdown immediate
2026-07-03 14:28:26.874 +08 [3489] LOG:  checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.002 s, sync=0.005 s, total=0.015 s; sync files=2, longest=0.004 s, average=0.003 s; distance=0 kB, estimate=0 kB; lsn=1/105466A0, redo lsn=1/105466A0
2026-07-03 14:28:26.882 +08 [3487] LOG:  database system is shut down

[postgres@pgdb02 ~]$ pg_ctl start -D /pgData/pgsql17/data
waiting for server to start....2026-07-03 14:29:00.574 +08 [3505] LOG:  redirecting log output to logging collector process
2026-07-03 14:29:00.574 +08 [3505] HINT:  Future log output will appear in directory "log".
 done
server started
[postgres@pgdb02 ~]$

2026-07-03 14:29:00.575 +08 [3505] LOG:  starting PostgreSQL 17.10 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-14), 64-bit
2026-07-03 14:29:00.579 +08 [3505] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2026-07-03 14:29:00.580 +08 [3505] LOG:  listening on IPv6 address "::", port 5432
2026-07-03 14:29:00.582 +08 [3505] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2026-07-03 14:29:00.587 +08 [3505] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2026-07-03 14:29:00.595 +08 [3509] LOG:  database system was shut down at 2026-07-03 14:28:26 +08
2026-07-03 14:29:00.607 +08 [3505] LOG:  database system is ready to accept connections

Immediate Shutdown (SIGQUIT):

[postgres@pgdb02 ~]$ pg_ctl stop -D /pgData/pgsql17/data -m immediate
waiting for server to shut down.... done
server stopped
[postgres@pgdb02 ~]$

2026-07-03 14:29:47.471 +08 [3505] LOG:  received immediate shutdown request
2026-07-03 14:29:47.485 +08 [3505] LOG:  database system is shut down


[postgres@pgdb02 ~]$ pg_ctl start -D /pgData/pgsql17/data
waiting for server to start....2026-07-03 14:30:17.965 +08 [3520] LOG:  redirecting log output to logging collector process
2026-07-03 14:30:17.965 +08 [3520] HINT:  Future log output will appear in directory "log".
. done
server started
[postgres@pgdb02 ~]$

2026-07-03 14:30:17.966 +08 [3520] LOG:  starting PostgreSQL 17.10 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-14), 64-bit
2026-07-03 14:30:17.966 +08 [3520] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2026-07-03 14:30:17.966 +08 [3520] LOG:  listening on IPv6 address "::", port 5432
2026-07-03 14:30:17.970 +08 [3520] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2026-07-03 14:30:17.974 +08 [3520] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2026-07-03 14:30:17.983 +08 [3524] LOG:  database system was interrupted; last known up at 2026-07-03 14:29:00 +08
2026-07-03 14:30:19.211 +08 [3524] LOG:  database system was not properly shut down; automatic recovery in progress
2026-07-03 14:30:19.216 +08 [3524] LOG:  redo starts at 1/10546718
2026-07-03 14:30:19.216 +08 [3524] LOG:  invalid record length at 1/10546750: expected at least 24, got 0
2026-07-03 14:30:19.217 +08 [3524] LOG:  redo done at 1/10546718 system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s
2026-07-03 14:30:19.221 +08 [3522] LOG:  checkpoint starting: end-of-recovery immediate wait
2026-07-03 14:30:19.231 +08 [3522] LOG:  checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.002 s, sync=0.003 s, total=0.012 s; sync files=2, longest=0.002 s, average=0.002 s; distance=0 kB, estimate=0 kB; lsn=1/10546750, redo lsn=1/10546750
2026-07-03 14:30:19.239 +08 [3520] LOG:  database system is ready to accept connections

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/

How SELECT, INSERT, UPDATE, and DELETE Work Internally in PostgreSQL

 

How SELECT, INSERT, UPDATE, and DELETE work internally in PostgreSQL?

PostgreSQL usesΒ MVCC (Multi-Version Concurrency Control), which means every modification creates a new version of the row instead of overwriting the old one. This is the core concept behind all DML operations.

1. Common Foundation (Applies to All Operations)

  • Heap: Data is stored inΒ heap filesΒ (tables). Each row is aΒ tuple.
  • Tuple Header: Every row contains:
    • xmin: Transaction ID that created the row
    • xmax: Transaction ID that deleted/updated the row (null if active)
    • Other visibility information
  • WAL (Write-Ahead Log): All changes are first written to WAL for durability before being applied to data files.
  • Shared Buffers: Data pages are read into memory before being modified.
  • Visibility Rules: A row is visible to a transaction based on its snapshot (which transactions it can see).

2. How SELECT Works

Β  Β  Β  Β  Β  Visibility Check: For each row, PostgreSQL checks:

    • The row’sΒ xminΒ must be committed and visible to the current transaction.
    • The row’sΒ xmaxΒ must be either null or not visible to the current transaction.

 


3. How INSERT Works

  1. Transaction Starts: A new transaction ID (xid) is assigned.
  2. Buffer Allocation: PostgreSQL finds a free slot in a heap page (or allocates a new page).
  3. Tuple Creation: A new row is created with:
    • xminΒ = current transaction ID
    • xmaxΒ = null
  4. WAL Logging: The change is written to theΒ WAL bufferΒ first.
  5. Page Modification: The new tuple is inserted into the shared buffer.
  6. Commit: On commit, the WAL is flushed to disk (fsync), making the change durable.

4. How UPDATE Works

UPDATE in PostgreSQL doesΒ notΒ modify the existing row. It creates aΒ new versionΒ of the row.

  1. Find the rowΒ using the same visibility rules as SELECT.
  2. Mark old row as dead: SetΒ xmaxΒ = current transaction ID on the old tuple.
  3. Insert new row: Create a completely new tuple with:
    • xminΒ = current transaction ID
    • xmaxΒ = null
    • Updated column values
  4. Update indexesΒ (if needed): New index entries point to the new tuple.
  5. WAL Logging: Both the old row’sΒ xmaxΒ change and the new tuple are logged in WAL.
  6. Commit: Changes become visible to other transactions after commit.

Important: The old row version remains in the table untilΒ VACUUMΒ cleans it up.


5. How DELETE Works

DELETE also uses MVCC β€” it doesn’t remove the row immediately.

  1. Locate the rowΒ using visibility rules.
  2. Mark as deleted: SetΒ xmaxΒ = current transaction ID on the tuple.
  3. WAL Logging: The change is logged.
  4. Commit: The row becomes invisible to new transactions.
  5. Physical Removal: The row is not physically deleted from disk untilΒ VACUUMΒ runs.

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/

Uninstall PostgreSQL 17 client

Uninstall PostgreSQL 17 client on Linux

Table of Contents



1. Uninstall PostgreSQL 17 client

[root@client01 ~]# dnf remove -y postgresql17
Dependencies resolved.
=================================================================================================
 Package                    Architecture    Version                       Repository        Size
=================================================================================================
Removing:
 postgresql17               x86_64          17.10-2PGDG.rhel9.8           @pgdg17           11 M
Removing unused dependencies:
 postgresql17-libs          x86_64          17.10-2PGDG.rhel9.8           @pgdg17          1.2 M

Transaction Summary
=================================================================================================
Remove  2 Packages

Freed space: 12 M
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                         1/1
  Erasing          : postgresql17-17.10-2PGDG.rhel9.8.x86_64                                 1/2
  Running scriptlet: postgresql17-17.10-2PGDG.rhel9.8.x86_64                                 1/2
  Erasing          : postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64                            2/2
  Running scriptlet: postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64                            2/2
  Verifying        : postgresql17-17.10-2PGDG.rhel9.8.x86_64                                 1/2
  Verifying        : postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64                            2/2

Removed:
  postgresql17-17.10-2PGDG.rhel9.8.x86_64      postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64

Complete!
[root@client01 ~]#

2. Remove the official PostgreSQL (PGDG) repository

[root@client01 ~]# dnf remove pgdg-redhat-repo -y
Dependencies resolved.
=================================================================================================================================
 Package                                        Architecture                         Version               Repository       Size
=================================================================================================================================
Removing:
 pgdg-redhat-repo                               noarch                               42.0-64.rhel9PGDG     @@commandline    16 k

Transaction Summary
=================================================================================================================================
Remove  1 Package

Freed space: 16 k
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                         1/1
  Erasing          : pgdg-redhat-repo-42.0-64.rhel9PGDG.noarch                                                               1/1
  Verifying        : pgdg-redhat-repo-42.0-64.rhel9PGDG.noarch                                                               1/1

Removed:
  pgdg-redhat-repo-42.0-64.rhel9PGDG.noarch

Complete!
[root@client01 ~]#

3. Verify the installation

[root@client01 ~]# psql --version
-bash: /usr/bin/psql: No such file or directory
[root@client01 ~]#

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/

Install PostgreSQL 17 client only

Install PostgreSQL 17 client only (no server) on Linux 9

Table of Contents



1. Add the official PostgreSQL (PGDG) repository

[root@client01 ~]# dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
Last metadata expiration check: 0:31:34 ago on Mon 22 Jun 2026 05:19:56 PM.
pgdg-redhat-repo-latest.noarch.rpm                                                                           63 kB/s |  13 kB     00:00
Dependencies resolved.
=======================================================================================================================================
 Package                                        Architecture    Version               Repository                                  Size
=======================================================================================================================================
Installing:
 pgdg-redhat-repo                               noarch          42.0-64.rhel9PGDG     @commandline                                13 k

Transaction Summary
=======================================================================================================================================
Install  1 Package

Total size: 13 k
Installed size: 16 k
Downloading Packages:
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                              1/1
  Installing       : pgdg-redhat-repo-42.0-64.rhel9PGDG.noarch                                                                    1/1
  Verifying        : pgdg-redhat-repo-42.0-64.rhel9PGDG.noarch                                                                    1/1

Installed:
  pgdg-redhat-repo-42.0-64.rhel9PGDG.noarch

Complete!
[root@client01 ~]#

2. Install only the PostgreSQL 17 client

[root@client01 ~]# dnf install -y postgresql17
PostgreSQL common RPMs for RHEL / Rocky Linux / AlmaLinux 9 - x8 1.0 kB/s | 659  B     00:00
PostgreSQL common RPMs for RHEL / Rocky Linux / AlmaLinux 9 - x8 1.3 MB/s | 2.4 kB     00:00
Importing GPG key 0x08B40D20:
..
..
Dependencies resolved.
=================================================================================================
 Package                    Architecture    Version                        Repository       Size
=================================================================================================
Installing:
 postgresql17               x86_64          17.10-2PGDG.rhel9.8            pgdg17          1.9 M
Installing dependencies:
 postgresql17-libs          x86_64          17.10-2PGDG.rhel9.8            pgdg17          342 k

Transaction Summary
=================================================================================================
Install  2 Packages

Total download size: 2.2 M
Installed size: 12 M
Downloading Packages:
(1/2): postgresql17-17.10-2PGDG.rhel9.8.x86_64.rpm               3.5 MB/s | 1.9 MB     00:00
(2/2): postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64.rpm          258 kB/s | 342 kB     00:01
-------------------------------------------------------------------------------------------------
Total                                                            1.7 MB/s | 2.2 MB     00:01
PostgreSQL 17 for RHEL / Rocky Linux / AlmaLinux 9 - x86_64      2.4 MB/s | 2.4 kB     00:00
Importing GPG key 0x08B40D20:
 Userid     : "PostgreSQL RPM Repository <pgsql-pkg-yum@lists.postgresql.org>"
 Fingerprint: D4BF 08AE 67A0 B4C7 A1DB CCD2 40BC A2B4 08B4 0D20
 From       : /etc/pki/rpm-gpg/PGDG-RPM-GPG-KEY-RHEL
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                         1/1
  Installing       : postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64                            1/2
  Running scriptlet: postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64                            1/2
  Installing       : postgresql17-17.10-2PGDG.rhel9.8.x86_64                                 2/2
  Running scriptlet: postgresql17-17.10-2PGDG.rhel9.8.x86_64                                 2/2
  Verifying        : postgresql17-17.10-2PGDG.rhel9.8.x86_64                                 1/2
  Verifying        : postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64                            2/2

Installed:
  postgresql17-17.10-2PGDG.rhel9.8.x86_64      postgresql17-libs-17.10-2PGDG.rhel9.8.x86_64

Complete!
[root@client01 ~]#

3. Verify the installation

[root@client01 ~]# psql --version
psql (PostgreSQL) 17.10  <-----------------
[root@client01 ~]#

4. Create OS User (if not exists)

[root@client01 ~]# useradd raj
[root@client01 ~]# passwd raj
Changing password for user raj.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
[root@client01 ~]#

[root@client01 ~]# echo 'export PATH=$PATH:/usr/pgsql-17/bin' >> /home/raj/.bash_profile
[root@client01 ~]#
[root@client01 ~]# ls -ltra /home/raj/.bash_profile
-rw-r--r--. 1 raj raj 177 Jun 22 18:20 /home/raj/.bash_profile
[root@client01 ~]#
[root@client01 ~]# cat /home/raj/.bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs
export PATH=$PATH:/usr/pgsql-17/bin
[root@client01 ~]#

5. Verify psql is Accessible

[root@client01 ~]# su - raj
[raj@client01 ~]$ psql --version
psql (PostgreSQL) 17.10   <-----------------
[raj@client01 ~]$

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/

Uninstall PostgreSQL 17(Source Installation)

Uninstall PostgreSQL 17(Source Installation)

Table of Contents



1. Stop the PostgreSQL Service

[root@pgdb02 ~]# systemctl stop postgresql-17
[root@pgdb02 ~]# systemctl disable postgresql-17
Removed "/etc/systemd/system/multi-user.target.wants/postgresql-17.service".
[root@pgdb02 ~]#

2. Remove the systemd Service File (if created)

[root@pgdb02 ~]# ls -l /etc/systemd/system/postgresql-17.service
-rw-r--r--. 1 root root 588 Jun 19 21:20 /etc/systemd/system/postgresql-17.service
[root@pgdb02 ~]#
[root@pgdb02 ~]# rm -f /etc/systemd/system/postgresql-17.service
[root@pgdb02 ~]#
[root@pgdb02 ~]# systemctl daemon-reload
[root@pgdb02 ~]#

3. Force Remove the Entire PostgreSQL Directory

WARNING: This permanently deletes all binaries, libraries, and data. Ensure your data is backed up before this step.

[root@pgdb02 ~]# rm -rf /pgBin/*
[root@pgdb02 ~]#

4. Remove Leftover Temporary Files if any

rm -f /tmp/.s.PGSQL.*
rm -f /tmp/.s.PGSQL.*.lock

5. Remove the postgres OS User (Optional)

[root@pgdb02 ~]# userdel -r postgres
[root@pgdb02 ~]# groupdel postgres
groupdel: group 'postgres' does not exist
[root@pgdb02 ~]#

6. Refresh the Library Cache

[root@pgdb02 ~]# ldconfig
[root@pgdb02 ~]#

Rebuilds the OS shared library cache to remove stale references to deleted PostgreSQL libraries.

The files are gone but the OS cache still remembers them. ldconfig clears that memory β€” it's a one-second cleanup that prevents broken library reference errors for any app that linked against libpq.

7. Verify Complete Removal

[root@pgdb02 ~]# ps -ef | grep postgres
root        4818    3561  0 19:44 pts/1    00:00:00 grep --color=auto postgres
[root@pgdb02 ~]# systemctl status postgresql-17
Unit postgresql-17.service could not be found.
[root@pgdb02 ~]#
[root@pgdb02 ~]# find /usr/local -name "*pgsql*" 2>/dev/null
[root@pgdb02 ~]# ss -tulpn | grep 543
[root@pgdb02 ~]#

Note: No need to run make uninstall β€” the rm -rf in Step 3 already handles complete removal of all installed files.

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/

Create a Second PostgreSQL Instance on the Same Linux Server

Create a Second PostgreSQL Instance on the Same Linux Server

Table of Contents



0. Verify existing setup

[postgres@pgdb02 ~]$ ps -ef | grep postgres
root        3641    3561  0 16:57 pts/1    00:00:00 su - postgres
postgres    3642    3641  0 16:57 pts/1    00:00:00 -bash
postgres    3711       1  0 17:03 ?        00:00:00 /pgBin/pgsql/17.4/bin/postgres -D /pgData/pgsql/17.4
postgres    3712    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: checkpointer
postgres    3713    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: background writer
postgres    3715    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: walwriter
postgres    3716    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: autovacuum launcher
postgres    3717    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: logical replication launcher
postgres    3731    3642  0 17:03 pts/1    00:00:00 psql
postgres    3732    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: postgres postgres [local] idle
root        3748    3164  0 17:09 pts/0    00:00:00 su - postgres
postgres    3749    3748  0 17:09 pts/0    00:00:00 -bash
postgres    3911    3749  0 17:59 pts/0    00:00:00 ps -ef
postgres    3912    3749  0 17:59 pts/0    00:00:00 grep --color=auto postgres
[postgres@pgdb02 ~]$

1. Create new directories

[root@pgdb02 ~]# mkdir -p /pgData/pgsql/17.4/dev
[root@pgdb02 ~]# mkdir -p /pgWal/pgsql/17.4/dev
[root@pgdb02 ~]# chown -R postgres:postgres /pgData /pgWal
[root@pgdb02 ~]#

2. Initialize second cluster

# As postgres user 

[postgres@pgdb02 ~]$ /pgBin/pgsql/17.4/bin/initdb -D /pgData/pgsql/17.4/dev --waldir=/pgWal/pgsql/17.4/dev --wal-segsize=128
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_SG.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

fixing permissions on existing directory /pgData/pgsql/17.4/dev ... ok
fixing permissions on existing directory /pgWal/pgsql/17.4/dev ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... Asia/Singapore
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /pgBin/pgsql/17.4/bin/pg_ctl -D /pgData/pgsql/17.4/dev -l logfile start

[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ ls -ld /pgData/pgsql/17.4/dev
drwx------. 18 postgres postgres 4096 Jun 20 18:03 /pgData/pgsql/17.4/dev
[postgres@pgdb02 ~]$
[postgres@pgdb02 ~]$ ls -ltr /pgData/pgsql/17.4/dev
total 56
lrwxrwxrwx. 1 postgres postgres    21 Jun 20 18:03 pg_wal -> /pgWal/pgsql/17.4/dev
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_commit_ts
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_dynshmem
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_twophase
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_tblspc
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_stat_tmp
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_snapshots
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_serial
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_replslot
drwx------. 2 postgres postgres     6 Jun 20 18:03 pg_notify
drwx------. 4 postgres postgres    36 Jun 20 18:03 pg_multixact
-rw-------. 1 postgres postgres     3 Jun 20 18:03 PG_VERSION
-rw-------. 1 postgres postgres 30718 Jun 20 18:03 postgresql.conf
-rw-------. 1 postgres postgres    88 Jun 20 18:03 postgresql.auto.conf
-rw-------. 1 postgres postgres  5711 Jun 20 18:03 pg_hba.conf
-rw-------. 1 postgres postgres  2640 Jun 20 18:03 pg_ident.conf
drwx------. 2 postgres postgres    18 Jun 20 18:03 pg_xact
drwx------. 2 postgres postgres    18 Jun 20 18:03 pg_subtrans
drwx------. 2 postgres postgres  4096 Jun 20 18:03 global
drwx------. 5 postgres postgres    33 Jun 20 18:03 base
drwx------. 4 postgres postgres    68 Jun 20 18:03 pg_logical
drwx------. 2 postgres postgres    25 Jun 20 18:03 pg_stat
[postgres@pgdb02 ~]$

**** we can see here 700 permission set by initdb command.

3. Edit second instance config

[postgres@pgdb02 ~]$ egrep "^(#)?(port|cluster_name)" /pgData/pgsql/17.4/dev/postgresql.conf
#port = 5432                            # (change requires restart)
#cluster_name = ''                      # added to process titles if nonempty
[postgres@pgdb02 ~]$


[postgres@pgdb02 ~]$ cp /pgData/pgsql/17.4/dev/postgresql.conf /pgData/pgsql/17.4/dev/postgresql.conf.bkp
[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ sed -i "s/^#port = 5432.*/port = 5433/" /pgData/pgsql/17.4/dev/postgresql.conf
[postgres@pgdb02 ~]$ sed -i "s/^#cluster_name = ''.*/cluster_name = 'PGDB_UAT'/" /pgData/pgsql/17.4/dev/postgresql.conf
[postgres@pgdb02 ~]$
[postgres@pgdb02 ~]$ egrep "^(#)?(port|cluster_name)" /pgData/pgsql/17.4/dev/postgresql.conf
port = 5433
cluster_name = 'PGDB_UAT'
[postgres@pgdb02 ~]$

4. Start PostgreSQL Service

[postgres@pgdb02 ~]$ /pgBin/pgsql/17.4/bin/pg_ctl -D /pgData/pgsql/17.4/dev -l logfile start
waiting for server to start.... done
server started
[postgres@pgdb02 ~]$

5. Connect to second instance

[postgres@pgdb02 ~]$ psql -p 5433
psql (17.4)
Type "help" for help.

postgres=# SHOW port;
 port
------
 5433  <-----------
(1 row)

postgres=# SHOW cluster_name;
 cluster_name
--------------
 PGDB_UAT  <---------------
(1 row)

postgres=#\q

[postgres@pgdb02 ~]$ pg_ctl stop -D /pgData/pgsql/17.4/dev
waiting for server to shut down.... done
server stopped
[postgres@pgdb02 ~]$

6. Create second systemd service

[root@pgdb02 ~]# cp /etc/systemd/system/postgresql-17.service /etc/systemd/system/postgresql-17-dev.service
[root@pgdb02 ~]#
[root@pgdb02 ~]# grep -i Environment=PGDATA /etc/systemd/system/postgresql-17-dev.service
Environment=PGDATA=/pgData/pgsql/17.4
[root@pgdb02 ~]#

[root@pgdb02 ~]# sed -i 's|Environment=PGDATA=/pgData/pgsql/17.4|Environment=PGDATA=/pgData/pgsql/17.4/dev|' /etc/systemd/system/postgresql-17-dev.service
[root@pgdb02 ~]# grep -i Environment=PGDATA /etc/systemd/system/postgresql-17-dev.service
Environment=PGDATA=/pgData/pgsql/17.4/dev
[root@pgdb02 ~]#

[root@pgdb02 ~]# systemctl daemon-reload
[root@pgdb02 ~]# systemctl start postgresql-17-dev
[root@pgdb02 ~]# systemctl enable postgresql-17-dev
Created symlink /etc/systemd/system/multi-user.target.wants/postgresql-17-dev.service β†’ /etc/systemd/system/postgresql-17-dev.service.
[root@pgdb02 ~]#
[root@pgdb02 ~]# systemctl status postgresql-17-dev
● postgresql-17-dev.service - PostgreSQL 17 Database Server
     Loaded: loaded (/etc/systemd/system/postgresql-17-dev.service; enabled; preset: disabled)
     Active: active (running) since Sat 2026-06-20 18:25:39 +08; 12s ago
       Docs: https://www.postgresql.org/docs/17/
   Main PID: 4106 (postgres)
      Tasks: 6 (limit: 15700)
     Memory: 15.2M
        CPU: 62ms
     CGroup: /system.slice/postgresql-17-dev.service
             β”œβ”€4106 /pgBin/pgsql/17.4/bin/postgres -D /pgData/pgsql/17.4/dev
             β”œβ”€4107 "postgres: PGDB_UAT: checkpointer "
             β”œβ”€4108 "postgres: PGDB_UAT: background writer "
             β”œβ”€4110 "postgres: PGDB_UAT: walwriter "
             β”œβ”€4111 "postgres: PGDB_UAT: autovacuum launcher "
             └─4112 "postgres: PGDB_UAT: logical replication launcher "

Jun 20 18:25:39 pgdb02 systemd[1]: Starting PostgreSQL 17 Database Server...
Jun 20 18:25:39 pgdb02 pg_ctl[4103]: waiting for server to start.... done
Jun 20 18:25:39 pgdb02 pg_ctl[4103]: server started
Jun 20 18:25:39 pgdb02 systemd[1]: Started PostgreSQL 17 Database Server.
[root@pgdb02 ~]#

7. Verify instances

[postgres@pgdb02 ~]$ ps -ef | grep postgres
postgres    3711       1  0 17:03 ?        00:00:00 /pgBin/pgsql/17.4/bin/postgres -D /pgData/pgsql/17.4
postgres    3712    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: checkpointer
postgres    3713    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: background writer
postgres    3715    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: walwriter
postgres    3716    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: autovacuum launcher
postgres    3717    3711  0 17:03 ?        00:00:00 postgres: PGDB_SIT: logical replication launcher
root        3748    3164  0 17:09 pts/0    00:00:00 su - postgres
postgres    3749    3748  0 17:09 pts/0    00:00:00 -bash
postgres    4106       1  0 18:25 ?        00:00:00 /pgBin/pgsql/17.4/bin/postgres -D /pgData/pgsql/17.4/dev
postgres    4107    4106  0 18:25 ?        00:00:00 postgres: PGDB_UAT: checkpointer
postgres    4108    4106  0 18:25 ?        00:00:00 postgres: PGDB_UAT: background writer
postgres    4110    4106  0 18:25 ?        00:00:00 postgres: PGDB_UAT: walwriter
postgres    4111    4106  0 18:25 ?        00:00:00 postgres: PGDB_UAT: autovacuum launcher
postgres    4112    4106  0 18:25 ?        00:00:00 postgres: PGDB_UAT: logical replication launcher
postgres    4157    3749 99 18:26 pts/0    00:00:00 ps -ef
postgres    4158    3749  0 18:26 pts/0    00:00:00 grep --color=auto postgres
[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ ss -tulpn | grep 543
tcp   LISTEN 0      200        127.0.0.1:5433       0.0.0.0:*    users:(("postgres",pid=4106,fd=7))
tcp   LISTEN 0      200        127.0.0.1:5432       0.0.0.0:*    users:(("postgres",pid=3711,fd=7))
tcp   LISTEN 0      200            [::1]:5432          [::]:*    users:(("postgres",pid=3711,fd=6))
tcp   LISTEN 0      200            [::1]:5433          [::]:*    users:(("postgres",pid=4106,fd=6))
[postgres@pgdb02 ~]$

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/

Uninstall PostgreSQL 17 on Linux (RPM Method)

Uninstall PostgreSQL 17 on Linux (Installed Using RPM Method)

Table of Contents



0. Important Caution Before Proceeding

** Before uninstalling PostgreSQL PostgreSQL 17, first take a logical or physical backup. **

If PostgreSQL was installed using RPM packages, removing the package does not automatically remove:

Database files
WAL files
Backup directories
Custom configuration files

1. Check Installed PostgreSQL RPM Packages

[root@pgdb02 ~]# rpm -qa | grep postgres
postgresql17-libs-17.6-1PGDG.rhel9.x86_64
postgresql17-17.6-1PGDG.rhel9.x86_64
postgresql17-server-17.6-1PGDG.rhel9.x86_64
postgresql17-contrib-17.6-1PGDG.rhel9.x86_64
[root@pgdb02 ~]#

2. Stop PostgreSQL Service

[root@pgdb02 ~]# systemctl stop postgresql-17
[root@pgdb02 ~]# systemctl status postgresql-17
β—‹ postgresql-17.service - PostgreSQL 17 database server
Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
Active: inactive (dead)
Docs: https://www.postgresql.org/docs/17/static/
[root@pgdb02 ~]#

3. Disable PostgreSQL Service

[root@pgdb02 ~]# systemctl disable postgresql-17
Removed "/etc/systemd/system/multi-user.target.wants/postgresql-17.service".
[root@pgdb02 ~]#

4. Remove and Verify PostgreSQL RPM Packages

WARNING: This permanently deletes all binaries, libraries, and data. Ensure your data is backed up before this step.

[root@pgdb02 ~]# rpm -qa | grep postgres
postgresql17-libs-17.6-1PGDG.rhel9.x86_64
postgresql17-17.6-1PGDG.rhel9.x86_64
postgresql17-server-17.6-1PGDG.rhel9.x86_64
postgresql17-contrib-17.6-1PGDG.rhel9.x86_64
[root@pgdb02 ~]#
[root@pgdb02 ~]# rpm -e postgresql17-contrib-17.6-1PGDG.rhel9.x86_64
[root@pgdb02 ~]# rpm -e postgresql17-server-17.6-1PGDG.rhel9.x86_64
[root@pgdb02 ~]# rpm -e postgresql17-17.6-1PGDG.rhel9.x86_64
[root@pgdb02 ~]# rpm -e postgresql17-libs-17.6-1PGDG.rhel9.x86_64
[root@pgdb02 ~]#

5. Verify Packages Are Removed

[root@pgdb02 ~]# rpm -qa | grep postgres
[root@pgdb02 ~]#

6. Remove PostgreSQL System User (Optional)

[root@pgdb02 ~]# id postgres
uid=26(postgres) gid=26(postgres) groups=26(postgres)
[root@pgdb02 ~]# userdel postgres
[root@pgdb02 ~]#
[root@pgdb02 ~]# groupdel postgres
groupdel: group 'postgres' does not exist
[root@pgdb02 ~]#
[root@pgdb02 ~]# id postgres
id: β€˜postgres’: no such user
[root@pgdb02 ~]#

7. Remove PostgreSQL Configuration Files

# It's already removed in step no. 3

[root@pgdb02 ~]# ls -l /usr/lib/systemd/system/postgresql-17.service
ls: cannot access '/usr/lib/systemd/system/postgresql-17.service': No such file or directory
[root@pgdb02 ~]# 
[root@pgdb02 ~]# ls -l /etc/systemd/system/postgresql-17.service
-rw-r--r--. 1 root root 588 Jun 19 21:20 /etc/systemd/system/postgresql-17.service
[root@pgdb02 ~]#
[root@pgdb02 ~]# rm -f /etc/systemd/system/postgresql-17.service
[root@pgdb02 ~]#

8. Verify Complete Removal

[root@pgdb02 ~]# id postgres
id: β€˜postgres’: no such user
[root@pgdb02 ~]#
[root@pgdb02 ~]# rpm -qa | grep postgres
[root@pgdb02 ~]#
[root@pgdb02 ~]# systemctl status postgresql-17
Unit postgresql-17.service could not be found.
[root@pgdb02 ~]#

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/

PostgreSQL 17 DBA Free Training Roadmap

PostgreSQL DBA Free Coaching

Free PostgreSQL DBA Training in Telugu for Beginners | Live Ongoing Batch | June 15 - July 31, 2026.
ఀెలుగులో ΰ°¨ΰ±‡ΰ°°ΰ±ΰ°šΰ±ΰ°•ΰ±‹ΰ°‚ΰ°‘ΰ°Ώ Β· 5 Weeks Β· Online Β· Beginner Friendly Β· 100% Free

DBA Training Program
// 5-week structured training Β· 19 sessions Β· hands-on labs
5
Weeks
19
Sessions
100+
Topics
∞
Future Free
Week 01 Lab Setup, Linux & PostgreSQL Fundamentals
Session 01 Lab Setup & Storage Configuration β–Ύ
Pre-requisites
  • Install VirtualBox on Windows (Do your self)
  • Install PgAdmin4 on Windows (Do your self)
  • Configure Oracle Linux 9.6 VM (will share link)
Linux VM Setup
  • Create Oracle Linux 9.6 VM
  • VM Hardware Sizing for PostgreSQL
  • Add Multiple Virtual Disks
Storage Configuration
  • Create Partitions
  • Create Filesystems
  • Mount Filesystems
  • Configure /etc/fstab
PostgreSQL Directory Layout
  • Create Mount Points: /pgData, /pgWal, /pgArch, /pgBackup, /pgLog
Session 02 Linux Administration for DBAs β–Ύ
  • Basic Linux Commands
  • File and Directory Management
  • User and Group Management
  • Permissions and Ownership
  • Process Management
  • Service Management using systemctl
  • Network Commands
  • Disk and Memory Monitoring
Session 03 PostgreSQL 17 Installation β–Ύ
Overview
  • PostgreSQL Overview and Versions
Installation Methods
  • RPM Installation
  • DNF/YUM Installation
  • Source Code Installation
Database Initialization
  • initdb
  • Custom WAL Location
  • PostgreSQL Service Configuration
Validation
  • Start PostgreSQL
  • Connect using psql
  • Connect using PgAdmin4
Session 04 PostgreSQL Architecture β–Ύ
Memory Architecture
  • Shared Buffers
  • WAL Buffers
  • Work Memory
  • Maintenance Work Memory
Process Architecture
  • Postmaster
  • Backend Processes
  • Checkpointer
  • Background Writer
  • WAL Writer
  • Autovacuum
Physical Storage Layout
  • Base Directory
  • Global Directory
  • WAL Directory
  • Tablespaces
Session 05 PostgreSQL Configuration Files β–Ύ
  • postgresql.conf
  • postgresql.auto.conf
  • pg_hba.conf
  • pg_ident.conf
  • Reload vs Restart
Week 02 Administration & Security
Session 06 Startup, Shutdown β–Ύ
  • PostgreSQL Startup Process
  • Smart Shutdown
  • Fast Shutdown (default)
  • Immediate Shutdown
Session 07 Database Administration β–Ύ
  • Creating Databases
  • Creating Schemas
  • Schema Search Path
  • Roles and Users
  • Access Control
Session 08 Tablespaces Management β–Ύ
  • pg_default
  • pg_global
  • Custom Tablespaces
  • Move Objects Between Tablespaces
  • Tablespace Monitoring
Session 09 Security β–Ύ
  • pg_hba.conf
  • Authentication Methods
  • pg_ident.conf
  • .pgpass
  • SSL/TLS Setup
Session 10 Vacuum and Analyze β–Ύ
  • MVCC Concepts
  • Dead Tuples
  • VACUUM
  • VACUUM FULL
  • ANALYZE
  • Autovacuum
Week 03 Backup & Recovery
Session 11 WAL Archiving β–Ύ
  • WAL Fundamentals
  • Archive Mode
  • Archive Command
Session 12 Logical Backup and Restore β–Ύ
  • pg_dump
  • pg_dumpall
  • Backup Formats
  • pg_restore
  • Restore using psql
Session 13 Physical Backup and Restore β–Ύ
  • pg_basebackup
  • Full Cluster Backup
  • Database Refresh on New Server
Session 14 PITR β€” Point-in-Time Recovery β–Ύ
  • PITR Concepts and Architecture
  • PITR Demonstration (hands-on)
Session 15 Full Recovery & Disaster Recovery β–Ύ
  • Full Database Recovery
  • Disaster Recovery Scenarios
Week 04 Replication, Failover
Session 16 Streaming Replication β–Ύ
  • Primary Configuration
  • Replica Configuration
  • Base Backup for Replica
  • Verify Replication
Session 17 Replication Administration β–Ύ
  • Replication Slots
  • Monitoring Replication
  • Async Replication
  • Sync Replication
  • Convert from ASYNC to SYNC
Session 18 Failover and pg_rewind β–Ύ
  • Manual Failover
  • Promote Replica
  • pg_rewind
  • Rejoin Old Primary as Replica
Week 05 Upgrades
Session 19 PostgreSQL Upgrades & Final Lab β–Ύ
  • Minor Version Upgrade
  • Major Version Upgrades
  • pg_upgrade
  • Upgrade using pg_dump/pg_restore
  • Upgrade Validation
  • Final End-to-End Lab
Future Batch Advanced Topics β€” Free Training
// Topics reserved for the next advanced batch Β· access is free
EXPLAIN / EXPLAIN ANALYZE Index Types & Tuning Table Partitioning Performance Tuning PostgreSQL Extensions PgBouncer pgmetrics pgcollector pgbadger Repmgr Patroni Maintenance Operations Oracle β†’ PostgreSQL (Ora2Pg) Advanced Data Migration Logical Replication Multi-Node HA Architectures

PostgreSQL DBA Free Training Roadmap Β· Click any session card to expand topics

Install PostgreSQL 17 using RPM Packages (Offline Method)

Install PostgreSQL 17 on Linux 9 Using RPM Packages (Offline Method)

Table of Contents



0. Download and Check Required Dependencies

*** Download PostgreSQL server RPM packages **** 
https://yum.postgresql.org/rpmchart/

https://download.postgresql.org/pub/repos/yum/17/redhat/rhel-9.6-x86_64/

[root@pgdb02 ~]# ls -ltr *.rpm
-rw-r--r--. 1 root root 1991253 Jun  4 19:24 postgresql17-17.6-1PGDG.rhel9.x86_64.rpm
-rw-r--r--. 1 root root 7265750 Jun  4 19:24 postgresql17-server-17.6-1PGDG.rhel9.x86_64.rpm
-rw-r--r--. 1 root root  349311 Jun  4 19:24 postgresql17-libs-17.6-1PGDG.rhel9.x86_64.rpm
-rw-r--r--. 1 root root  747670 Jun  4 19:24 postgresql17-contrib-17.6-1PGDG.rhel9.x86_64.rpm
[root@pgdb02 ~]#

*** Check dependency List ***

root@pgdb02 ~]# rpm -qa | grep -E "libicu|openssl|readline|zlib"
zlib-1.2.11-40.el9.x86_64
libicu-67.1-9.el9.x86_64
readline-8.1-4.el9.x86_64
openssl-fips-provider-so-3.0.7-6.0.1.el9_5.x86_64
openssl-fips-provider-3.0.7-6.0.1.el9_5.x86_64
openssl-libs-3.2.2-6.0.1.el9_5.1.x86_64
openssl-3.2.2-6.0.1.el9_5.1.x86_64
xmlsec1-openssl-1.2.29-13.el9.x86_64
[root@pgdb02 ~]#

*** This gives you the exact official dependency list from the RPM itself ***

rpm -qpR postgresql17-libs-17.6-1PGDG.rhel9.x86_64.rpm
rpm -qpR postgresql17-17.6-1PGDG.rhel9.x86_64.rpm
rpm -qpR postgresql17-server-17.6-1PGDG.rhel9.x86_64.rpm
rpm -qpR postgresql17-contrib-17.6-1PGDG.rhel9.x86_64.rpm

q = query
p = package file (local file)
R = Requirements (dependencies)

****To Check What is Already Installed vs Missing*****

rpm -qpR postgresql17-libs-17.6-1PGDG.rhel9.x86_64.rpm \
postgresql17-17.6-1PGDG.rhel9.x86_64.rpm \
postgresql17-server-17.6-1PGDG.rhel9.x86_64.rpm \
postgresql17-contrib-17.6-1PGDG.rhel9.x86_64.rpm 2>/dev/null | grep "^lib" | sort -u | while read dep; do
rpm -q --whatprovides "$dep" &>/dev/null && echo "INSTALLED : $dep" || echo "MISSING : $dep"
done

[root@pgdb02 ~]# rpm -qpR postgresql17-libs-17.6-1PGDG.rhel9.x86_64.rpm \
postgresql17-17.6-1PGDG.rhel9.x86_64.rpm \
postgresql17-server-17.6-1PGDG.rhel9.x86_64.rpm \
postgresql17-contrib-17.6-1PGDG.rhel9.x86_64.rpm 2>/dev/null | grep "^lib" | sort -u | while read dep; do
rpm -q --whatprovides "$dep" &>/dev/null && echo "INSTALLED : $dep" || echo "MISSING : $dep"
done
INSTALLED : libcrypto.so.3()(64bit)
INSTALLED : libcrypto.so.3(OPENSSL_3.0.0)(64bit)
INSTALLED : libc.so.6()(64bit)
INSTALLED : libc.so.6(GLIBC_2.10)(64bit)
INSTALLED : libc.so.6(GLIBC_2.11)(64bit)
INSTALLED : libc.so.6(GLIBC_2.14)(64bit)
INSTALLED : libc.so.6(GLIBC_2.15)(64bit)
INSTALLED : libc.so.6(GLIBC_2.17)(64bit)
INSTALLED : libc.so.6(GLIBC_2.2.5)(64bit)
INSTALLED : libc.so.6(GLIBC_2.25)(64bit)
INSTALLED : libc.so.6(GLIBC_2.27)(64bit)
INSTALLED : libc.so.6(GLIBC_2.3.2)(64bit)
INSTALLED : libc.so.6(GLIBC_2.32)(64bit)
INSTALLED : libc.so.6(GLIBC_2.33)(64bit)
INSTALLED : libc.so.6(GLIBC_2.3.4)(64bit)
INSTALLED : libc.so.6(GLIBC_2.34)(64bit)
INSTALLED : libc.so.6(GLIBC_2.3)(64bit)
INSTALLED : libc.so.6(GLIBC_2.4)(64bit)
INSTALLED : libc.so.6(GLIBC_2.6)(64bit)
INSTALLED : libc.so.6(GLIBC_2.7)(64bit)
INSTALLED : libc.so.6(GLIBC_2.9)(64bit)
INSTALLED : libecpg.so.6()(64bit)
INSTALLED : libgssapi_krb5.so.2()(64bit)
INSTALLED : libgssapi_krb5.so.2(gssapi_krb5_2_MIT)(64bit)
INSTALLED : libicu
INSTALLED : libicudata.so.67()(64bit)
INSTALLED : libicui18n.so.67()(64bit)
INSTALLED : libicuuc.so.67()(64bit)
INSTALLED : libldap.so.2()(64bit)
INSTALLED : libldap.so.2(OPENLDAP_2.200)(64bit)
INSTALLED : liblz4.so.1()(64bit)
INSTALLED : libm.so.6()(64bit)
INSTALLED : libm.so.6(GLIBC_2.2.5)(64bit)
INSTALLED : libm.so.6(GLIBC_2.29)(64bit)
INSTALLED : libpam.so.0()(64bit)
INSTALLED : libpam.so.0(LIBPAM_1.0)(64bit)
INSTALLED : libperl.so.5.32()(64bit)
INSTALLED : libpgtypes.so.3()(64bit)
INSTALLED : libpq.so.5()(64bit)
INSTALLED : libpython3.9.so.1.0()(64bit)
INSTALLED : libreadline.so.8()(64bit)
INSTALLED : libselinux.so.1()(64bit)
INSTALLED : libselinux.so.1(LIBSELINUX_1.0)(64bit)
INSTALLED : libssl.so.3()(64bit)
INSTALLED : libssl.so.3(OPENSSL_3.0.0)(64bit)
INSTALLED : libsystemd.so.0()(64bit)
INSTALLED : libsystemd.so.0(LIBSYSTEMD_209)(64bit)
INSTALLED : libuuid.so.1()(64bit)
INSTALLED : libuuid.so.1(UUID_1.0)(64bit)
INSTALLED : libxml2.so.2()(64bit)
INSTALLED : libxml2.so.2(LIBXML2_2.4.30)(64bit)
INSTALLED : libxml2.so.2(LIBXML2_2.6.0)(64bit)
INSTALLED : libxml2.so.2(LIBXML2_2.6.23)(64bit)
INSTALLED : libxml2.so.2(LIBXML2_2.6.5)(64bit)
INSTALLED : libxml2.so.2(LIBXML2_2.6.8)(64bit)
INSTALLED : libxslt.so.1()(64bit)
INSTALLED : libxslt.so.1(LIBXML2_1.0.11)(64bit)
INSTALLED : libxslt.so.1(LIBXML2_1.0.18)(64bit)
INSTALLED : libxslt.so.1(LIBXML2_1.0.22)(64bit)
INSTALLED : libz.so.1()(64bit)
MISSING : libzstd >= 1.4.0  <--- Β is a REQUIREMENT defined by PostgreSQL RPM β€” not something libzstd declares.
INSTALLED : libzstd.so.1()(64bit)
[root@pgdb02 ~]#

*** libzstd library is installed BUT the version is NEWER than 1.4.0, It's fine. Verify manually to confirm. (Script error) ****

[root@pgdb02 ~]# rpm -q libzstd
libzstd-1.5.5-1.el9.x86_64  <--- It's 1.5.5
[root@pgdb02 ~]#

[root@pgdb02 ~]# rpm -q --provides libzstd
libzstd = 1.5.5-1.el9
libzstd(x86-64) = 1.5.5-1.el9
libzstd.so.1()(64bit)
[root@pgdb02 ~]#

1. Verify Downloaded RPM Packages

[root@pgdb02 ~]# ls -ltr *.rpm
-rw-r--r--. 1 root root 1991253 Jun  4 19:24 postgresql17-17.6-1PGDG.rhel9.x86_64.rpm
-rw-r--r--. 1 root root 7265750 Jun  4 19:24 postgresql17-server-17.6-1PGDG.rhel9.x86_64.rpm
-rw-r--r--. 1 root root  349311 Jun  4 19:24 postgresql17-libs-17.6-1PGDG.rhel9.x86_64.rpm
-rw-r--r--. 1 root root  747670 Jun  4 19:24 postgresql17-contrib-17.6-1PGDG.rhel9.x86_64.rpm
[root@pgdb02 ~]#

# Always install in this order:
rpm -ivh postgresql17-libs-17.6-1PGDG.rhel9.x86_64.rpm    # 1st - Shared library files (Foundation)
rpm -ivh postgresql17-17.6-1PGDG.rhel9.x86_64.rpm         # 2nd - Client tools
rpm -ivh postgresql17-server-17.6-1PGDG.rhel9.x86_64.rpm  # 3rd - Server
rpm -ivh postgresql17-contrib-17.6-1PGDG.rhel9.x86_64.rpm # 4th - Extensions

The postgresql17-server RPM is the core package required to host and run a PostgreSQL 17 database instance. It contains the database engine, background services, and utilities needed to initialize and manage a database cluster.
i = Install
v = Verbose (show me what's happening)
h = Hashes (show progress bar)
PartMeaning
17PostgreSQL Major version β€” 17
17.6Minor version β€” 17.6 (6th patch of version 17)
1RPM Build number β€” built 1 time
PGDGPostgreSQL Global Development Group β€” official PostgreSQL community repo, not Red Hat
rhel9Built for RHEL 9 / Oracle Linux 9
x86_6464-bit Intel or AMD processor

2. Install PostgreSQL Libraries Package

[root@pgdb02 ~]# rpm -ivh postgresql17-libs-17.6-1PGDG.rhel9.x86_64.rpm
warning: postgresql17-libs-17.6-1PGDG.rhel9.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID 08b40d20: NOKEY
Verifying...                          ################################# [100%]
Preparing...                          ################################# [100%]
Updating / installing...
   1:postgresql17-libs-17.6-1PGDG.rhel################################# [100%]
[root@pgdb02 ~]#

3. Install PostgreSQL Client Package

[root@pgdb02 ~]# rpm -ivh postgresql17-17.6-1PGDG.rhel9.x86_64.rpm
warning: postgresql17-17.6-1PGDG.rhel9.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID 08b40d20: NOKEY
Verifying...                          ################################# [100%]
Preparing...                          ################################# [100%]
Updating / installing...
   1:postgresql17-17.6-1PGDG.rhel9    ################################# [100%]
[root@pgdb02 ~]#

[root@pgdb02 ~]# psql --version
psql (PostgreSQL) 17.6
[root@pgdb02 ~]#

4. Install PostgreSQL Server Package

[root@pgdb02 ~]# rpm -ivh postgresql17-server-17.6-1PGDG.rhel9.x86_64.rpm
warning: postgresql17-server-17.6-1PGDG.rhel9.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID 08b40d20: NOKEY
Verifying...                          ################################# [100%]
Preparing...                          ################################# [100%]
Updating / installing...
   1:postgresql17-server-17.6-1PGDG.rh################################# [100%]
[root@pgdb02 ~]# 
[root@pgdb02 ~]# id postgres
uid=26(postgres) gid=26(postgres) groups=26(postgres)
[root@pgdb02 ~]#

5. Install PostgreSQL Contrib Package (Optional but Recommended)

[root@pgdb02 ~]# rpm -ivh postgresql17-contrib-17.6-1PGDG.rhel9.x86_64.rpm
warning: postgresql17-contrib-17.6-1PGDG.rhel9.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID 08b40d20: NOKEY
Verifying...                          ################################# [100%]
Preparing...                          ################################# [100%]
Updating / installing...
   1:postgresql17-contrib-17.6-1PGDG.r################################# [100%]
[root@pgdb02 ~]#

6. Verify Installed Packages

[root@pgdb02 ~]# rpm -qa | grep postgresql17
postgresql17-libs-17.6-1PGDG.rhel9.x86_64
postgresql17-17.6-1PGDG.rhel9.x86_64
postgresql17-server-17.6-1PGDG.rhel9.x86_64
postgresql17-contrib-17.6-1PGDG.rhel9.x86_64
[root@pgdb02 ~]#

7. Initialize PostgreSQL Database Cluster

[root@pgdb02 ~]# mkdir -p /pgData/pgsql17/data
[root@pgdb02 ~]# chown -R postgres:postgres /pgData
[root@pgdb02 ~]#
[root@pgdb02 ~]# mkdir -p /pgWal/pgsql17/wal
[root@pgdb02 ~]# chown -R postgres:postgres /pgWal
[root@pgdb02 ~]#
[root@pgdb02 ~]# su - postgres
[postgres@pgdb02 ~]$ Β 
[postgres@pgdb02 ~]$ /usr/pgsql-17/bin/initdb -D /pgData/pgsql17/data -X /pgWal/pgsql17/wal --wal-segsize=64
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_SG.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

fixing permissions on existing directory /pgData/pgsql17/data ... ok
fixing permissions on existing directory /pgWal/pgsql17/wal ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... Asia/Singapore
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /usr/pgsql-17/bin/pg_ctl -D /pgData/pgsql17/data -l logfile start

[postgres@pgdb02 ~]$

8. Start PostgreSQL Service

[postgres@pgdb02 ~]$ id postgres
uid=26(postgres) gid=26(postgres) groups=26(postgres)
[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ /usr/pgsql-17/bin/pg_ctl -D /pgData/pgsql17/data -l /pgData/pgsql17/data/postgresql.log start
waiting for server to start.... done
server started
[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ ps -ef | grep postgres
root        4366    3019  0 20:50 pts/0    00:00:00 su - postgres
postgres    4367    4366  0 20:50 pts/0    00:00:00 -bash
postgres 4559 1 0 21:32 ? 00:00:00 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data
postgres    4560    4559  0 21:32 ?        00:00:00 postgres: logger
postgres    4561    4559  0 21:32 ?        00:00:00 postgres: checkpointer
postgres    4562    4559  0 21:32 ?        00:00:00 postgres: background writer
postgres    4564    4559  0 21:32 ?        00:00:00 postgres: walwriter
postgres    4565    4559  0 21:32 ?        00:00:00 postgres: autovacuum launcher
postgres    4566    4559  0 21:32 ?        00:00:00 postgres: logical replication launcher
postgres    4568    4367  0 21:33 pts/0    00:00:00 ps -ef
postgres    4569    4367  0 21:33 pts/0    00:00:00 grep --color=auto postgres
[postgres@pgdb02 ~]$
[postgres@pgdb02 ~]$ pstree -p 4559
postgres(4559)─┬─postgres(4560) ----- postgres: logger
               β”œβ”€postgres(4561) ----- postgres: checkpointer
               β”œβ”€postgres(4562) ----- postgres: background writer
               β”œβ”€postgres(4564) ----- postgres: walwriter
               β”œβ”€postgres(4565) ----- postgres: autovacuum launcher
               └─postgres(4566) ----- postgres: logical replication launcher
[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ ls -ltr /pgData/pgsql17/data
total 72
lrwxrwxrwx. 1 postgres postgres 18 Jun 4 21:31 pg_wal -> /pgWal/pgsql17/wal
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_twophase
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_snapshots
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_serial
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_replslot
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_notify
drwx------. 4 postgres postgres    36 Jun  4 21:31 pg_multixact
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_dynshmem
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_commit_ts
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_tblspc
drwx------. 2 postgres postgres     6 Jun  4 21:31 pg_stat_tmp
-rw-------. 1 postgres postgres     3 Jun  4 21:31 PG_VERSION
-rw-------. 1 postgres postgres 30703 Jun  4 21:31 postgresql.conf
-rw-------. 1 postgres postgres    88 Jun  4 21:31 postgresql.auto.conf
-rw-------. 1 postgres postgres  2640 Jun  4 21:31 pg_ident.conf
-rw-------. 1 postgres postgres  5711 Jun  4 21:31 pg_hba.conf
drwx------. 2 postgres postgres    18 Jun  4 21:31 pg_xact
drwx------. 2 postgres postgres    18 Jun  4 21:31 pg_subtrans
drwx------. 5 postgres postgres    33 Jun  4 21:31 base
drwx------. 4 postgres postgres    68 Jun  4 21:31 pg_logical
drwx------. 2 postgres postgres    32 Jun  4 21:32 log
-rw-------. 1 postgres postgres   185 Jun  4 21:32 postgresql.log
-rw-------. 1 postgres postgres    30 Jun  4 21:32 current_logfiles
-rw-------. 1 postgres postgres    55 Jun  4 21:32 postmaster.opts
drwx------. 2 postgres postgres     6 Jun  4 21:32 pg_stat
-rw-------. 1 postgres postgres    97 Jun  4 21:32 postmaster.pid
drwx------. 2 postgres postgres  4096 Jun  4 21:33 global
[postgres@pgdb02 ~]$

[postgres@pgdb02 ~]$ ls -l /pgWal/pgsql17/wal
total 65536
-rw-------. 1 postgres postgres 67108864 Jun  4 21:33 000000010000000000000001
drwx------. 2 postgres postgres        6 Jun  4 21:31 archive_status
drwx------. 2 postgres postgres        6 Jun  4 21:31 summaries
[postgres@pgdb02 ~]$

9. Connect to PostgreSQL Database

# Add below entries .bash_profile or custom profile and then reload profile

export PGHOME=/usr/pgsql-17
export PGDATA=/pgData/pgsql17/data
export PATH=$PGHOME/bin:$PATH

# reload 
[postgres@pgdb02 ~]$ . .bash_profile
[postgres@pgdb02 ~]$
[postgres@pgdb02 ~]$ psql -c "SELECT version();"

                                                 version
----------------------------------------------------------------------------------------------------------
 PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-5), 64-bit
(1 row)

[postgres@pgdb02 ~]$

10. Enable PostgreSQL service at boot (Automatic Restart at boot)

Issue: Failed to start "systemctl start postgresql-17"

[root@pgdb02 ~]# tail -f /var/log/messages
..
..
Jun 18 20:07:55 lxceftsgvdb01 systemd[1]: Starting PostgreSQL 17 database server...
Jun 18 20:07:55 lxceftsgvdb01 postgresql-17-check-db-dir[3641]: "/var/lib/pgsql/17/data/" is missing or empty.
Jun 18 20:07:55 lxceftsgvdb01 postgresql-17-check-db-dir[3641]: Use "/usr/pgsql-17/bin/postgresql-17-setup initdb" to initialize the database cluster.
Jun 18 20:07:55 lxceftsgvdb01 postgresql-17-check-db-dir[3641]: See /usr/share/doc/postgresql17/README.rpm-dist for more information.
Jun 18 20:07:55 lxceftsgvdb01 systemd[1]: postgresql-17.service: Control process exited, code=exited, status=1/FAILURE
Jun 18 20:07:55 lxceftsgvdb01 systemd[1]: postgresql-17.service: Failed with result 'exit-code'.
Jun 18 20:07:55 lxceftsgvdb01 systemd[1]: Failed to start PostgreSQL 17 database server.

# Verify postgresql-17.service
[postgres@pgdb02 ~]$ cat /usr/lib/systemd/system/postgresql-17.service
# It's not recommended to modify this file in-place, because it will be
# overwritten during package upgrades.  It is recommended to use systemd
# "dropin" feature;  i.e. create file with suffix .conf under
# /etc/systemd/system/postgresql-17.service.d directory overriding the
# unit's defaults. You can also use "systemctl edit postgresql-17"
# Look at systemd.unit(5) manual page for more info.

# Note: changing PGDATA will typically require adjusting SELinux
# configuration as well.

# Note: do not use a PGDATA pathname containing spaces, or you will
# break postgresql-17-setup.
[Unit]
Description=PostgreSQL 17 database server
Documentation=https://www.postgresql.org/docs/17/static/
After=syslog.target
After=network-online.target

[Service]
Type=notify

User=postgres
Group=postgres

# Note: avoid inserting whitespace in these Environment= lines, or you may
# break postgresql-setup.

# Location of database directory
Environment=PGDATA=/var/lib/pgsql/17/data/   <------ 

# Where to send early-startup messages from the server (before the logging
# options of postgresql.conf take effect)
# This is normally controlled by the global default set by systemd
# StandardOutput=syslog

# Disable OOM kill on postgres main process
OOMScoreAdjust=-1000
Environment=PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
Environment=PG_OOM_ADJUST_VALUE=0

ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA}
ExecStart=/usr/pgsql-17/bin/postgres -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT

# Do not set any timeout value, so that systemd will not kill postgres
# main process during crash recovery.
TimeoutSec=0

# 0 is the same as infinity, but "infinity" needs systemd 229
TimeoutStartSec=0

TimeoutStopSec=1h

[Install]
WantedBy=multi-user.target
[postgres@pgdb02 ~]$


1. Stop PostgreSQL as Postgres user using pg_ctl if running
# As postgres user
[postgres@pgdb02 ~]$ pg_ctl stop
waiting for server to shut down.... done
server stopped
[postgres@pgdb02 ~]$

2. Set DATA Directory location as root user
# As root user
[root@pgdb02  ~]# grep -i Environment=PGDATA /usr/lib/systemd/system/postgresql-17.service
Environment=PGDATA=/var/lib/pgsql/17/data/   <--- set to wrong location, need to correct this. 
[root@pgdb02  ~]#
[root@pgdb02  ~]# sed -i 's|Environment=PGDATA=/var/lib/pgsql/17/data/|Environment=PGDATA=/pgData/pgsql17/data/|' /usr/lib/systemd/system/postgresql-17.service
[root@pgdb02  ~]#
[root@pgdb02  ~]# grep -i Environment=PGDATA /usr/lib/systemd/system/postgresql-17.service
Environment=PGDATA=/pgData/pgsql17/data/
[root@pgdb02  ~]#

3. Enable PostgreSQL service at boot

[root@pgdb02 ~]# systemctl enable postgresql-17
Created symlink /etc/systemd/system/multi-user.target.wants/postgresql-17.service β†’ /usr/lib/systemd/system/postgresql-17.service.
[root@pgdb02 ~]#

4. Start PostgreSQL service
[root@pgdb02 ~]# systemctl start postgresql-17
[root@pgdb02 ~]#

5. Verify Status

[root@pgdb02 ~]# systemctl status postgresql-17
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Thu 2026-06-18 20:44:47 +08; 9s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 3959 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 3964 (postgres)
      Tasks: 7 (limit: 15700)
     Memory: 17.6M
        CPU: 79ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€3964 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data/
             β”œβ”€3965 "postgres: logger "
             β”œβ”€3966 "postgres: checkpointer "
             β”œβ”€3967 "postgres: background writer "
             β”œβ”€3969 "postgres: walwriter "
             β”œβ”€3970 "postgres: autovacuum launcher "
             └─3971 "postgres: logical replication launcher "

Jun 18 20:44:47 pgdb02 systemd[1]: Starting PostgreSQL 17 database server...
Jun 18 20:44:47 pgdb02 postgres[3964]: 2026-06-18 20:44:47.663 +08 [3964] LOG:  redirecting log output to logging collector process
Jun 18 20:44:47 pgdb02 postgres[3964]: 2026-06-18 20:44:47.663 +08 [3964] HINT:  Future log output will appear in directory "log".
Jun 18 20:44:47 pgdb02 systemd[1]: Started PostgreSQL 17 database server.
[root@pgdb02 ~]#

[postgres@pgdb02 ~]$ tail -f /pgData/pgsql17/data/log/postgresql-Thu.log
..
..
2026-06-18 20:44:47.665 +08 [3964] LOG:  starting PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-5), 64-bit
2026-06-18 20:44:47.667 +08 [3964] LOG:  listening on IPv6 address "::1", port 5432
2026-06-18 20:44:47.667 +08 [3964] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2026-06-18 20:44:47.668 +08 [3964] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2026-06-18 20:44:47.672 +08 [3964] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2026-06-18 20:44:47.679 +08 [3968] LOG:  database system was shut down at 2026-06-18 20:44:43 +08
2026-06-18 20:44:47.688 +08 [3964] LOG:  database system is ready to accept connections

[root@pgdb02 ~]# tail -f /var/log/messages
..
..
Jun 18 20:44:47 pgdb02 systemd[1]: Starting PostgreSQL 17 database server...
Jun 18 20:44:47 pgdb02 postgres[3964]: 2026-06-18 20:44:47.663 +08 [3964] LOG:  redirecting log output to logging collector process
Jun 18 20:44:47 pgdb02 postgres[3964]: 2026-06-18 20:44:47.663 +08 [3964] HINT:  Future log output will appear in directory "log".
Jun 18 20:44:47 pgdb02 systemd[1]: Started PostgreSQL 17 database server.
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/

PostgreSQL DBA Terminology

PostgreSQL DBA Field Guide
DBA Reference

PostgreSQL Internals
Field Guide

Core concepts every PostgreSQL DBA must know β€” explained in plain English, no jargon fog.

πŸ—„οΈ
01 Β· Storage Layer
How Postgres Stores Data
Tuple
aka row / record
A tuple is simply one row in a table. Postgres calls rows "tuples" internally. Every tuple has a hidden header (t_xmin, t_xmax) that tracks which transaction created and deleted it β€” the foundation of MVCC.
Page / Block
8 KB default unit
Postgres reads/writes data in 8 KB pages (also called blocks). A table file is a sequence of pages. Each page holds multiple tuples. Changing one byte forces the whole 8 KB page to be written to disk.
Heap
the table's main file
The heap is the raw data file for a table β€” tuples stored in no particular order. Unlike B-tree indexes, the heap has no sorted structure. pg_relation_filepath('mytable') shows you the file on disk.
OID / Relfilenode
internal object identifiers
Every database object has an OID (Object ID). The relfilenode is the actual filename on disk (a number like 16384). After CLUSTER or VACUUM FULL, the relfilenode changes even though the table name stays the same.
TOAST
The Oversized-Attribute Storage Technique
When a column value is too large to fit in a page, Postgres automatically compresses or moves it to a separate TOAST table. Large TEXT, JSONB, or BYTEA values live there. Transparent to SQL, important for bloat investigations.
Fork
relation file sub-types
Each relation (table/index) is stored in up to 3 forks on disk:
β€’ Main fork β€” actual data
β€’ FSM fork β€” Free Space Map (which pages have room)
β€’ VM fork β€” Visibility Map (which pages are all-visible)
You'll see suffixes like _fsm, _vm in the data directory.
πŸ‘οΈ
02 Β· Concurrency
MVCC β€” Multi-Version Concurrency Control
What is MVCC?
Postgres never overwrites a row in place. Instead, an UPDATE creates a new tuple version and marks the old one as dead. This means readers never block writers and writers never block readers. Each transaction sees a snapshot of the database from when it started β€” like a photograph taken at that moment in time.
Row v1 (xmin=100)
β†’ UPDATE β†’
Row v2 (xmin=201)
+
Row v1 (xmax=201) dead
xmin / xmax
hidden system columns
xmin = Transaction ID that inserted this tuple. xmax = Transaction ID that deleted/updated this tuple (0 means it's still live). You can see them with:
SELECT xmin, xmax, * FROM mytable;
Transaction ID (XID)
32-bit counter, wraps around!
Every transaction gets a monotonically increasing XID. It's a 32-bit integer β€” after ~2 billion transactions it wraps. This is the famous XID wraparound problem. Unvacuumed tables can lose data if wraparound occurs.
⚠️
Monitor this! age(datfrozenxid) must stay below 2 billion. Alert at 500 million.
Snapshot
your transaction's "world view"
When your transaction starts, Postgres takes a snapshot listing all currently active XIDs. Your query only sees tuples committed before your snapshot. Rows inserted by concurrent transactions are invisible to you until you start a new transaction.
Isolation Levels
READ COMMITTED Β· REPEATABLE READ Β· SERIALIZABLE
READ COMMITTED (default) β€” new snapshot per statement. You can see rows committed between statements in the same transaction.

REPEATABLE READ β€” snapshot taken at first statement, held for whole transaction.

SERIALIZABLE β€” full SSI, as if transactions ran one by one.
🧹
03 Β· Housekeeping
VACUUM β€” The Garbage Collector
Why VACUUM Exists
Because MVCC creates dead tuples on every UPDATE/DELETE, someone has to clean them up. VACUUM marks dead tuple space as reusable (but doesn't shrink the file). Think of it as "marking empty seats in a theater" β€” others can sit there but the theater size stays the same.
Key point: Regular VACUUM does NOT return space to the OS. Only VACUUM FULL does (but it locks the table).
VACUUM
non-blocking cleanup
Marks dead tuples as free space, updates the FSM and VM, and advances relfrozenxid. Runs concurrently with reads and most writes.
VACUUM (VERBOSE, ANALYZE) mytable;
VACUUM FULL
⚠️ table-locking rewrite
Rewrites the entire table to a new file, reclaiming all dead space and returning it to the OS. Acquires an exclusive lock β€” no reads or writes during this time. Use pg_repack instead in production for zero-downtime compaction.
ANALYZE
stats collector for the planner
Samples the table and updates pg_statistic with column data distributions (histograms, most-common-values). The query planner uses these stats to pick the best plan. Stale stats = bad plans = slow queries.
Freeze
XID wraparound prevention
VACUUM freezes old tuples by replacing their xmin with a special FrozenXID. Frozen tuples are visible to all future transactions, preventing wraparound. VACUUM FREEZE forces this for the whole table regardless of age.
Visibility Map (VM)
vacuum's shortcut
A bitmap with 2 bits per page. Bit 1 = all tuples on this page are visible to all transactions. Bit 2 = all tuples are frozen. VACUUM skips pages where both bits are set. Index-only scans also use the VM to avoid heap fetches.
⚑
04 Β· Transactions
ACID & Transaction Management
ACID
the four guarantees
Atomicity β€” all or nothing.
Consistency β€” constraints always satisfied.
Isolation β€” concurrent transactions don't interfere.
Durability β€” committed data survives crashes (via WAL).
Savepoint
partial rollback
A bookmark inside a transaction. If something fails, you roll back to the savepoint instead of the whole transaction. Used heavily in ORMs to handle expected errors without aborting the whole session.
SAVEPOINT my_save; -- do risky stuff ROLLBACK TO my_save;
Two-Phase Commit (2PC)
distributed transactions
For distributed systems. Phase 1: PREPARE TRANSACTION (durable write, not yet committed). Phase 2: COMMIT PREPARED. If the coordinator crashes between phases, pg_prepared_xacts holds the zombie transaction. Monitor and clean these!
Idle in Transaction
the silent killer
A connection that's opened a transaction but isn't doing anything. Holds locks, prevents VACUUM from cleaning rows, bloats the table. Find them with:
SELECT pid, state, now() - xact_start FROM pg_stat_activity WHERE state = 'idle in transaction';
πŸ”’
05 Β· Locking
Locks & Blocking
Lock Levels (lightest β†’ heaviest)
LockWho Takes ItBlocks
ACCESS SHARESELECTOnly DROP TABLE
ROW SHARESELECT FOR UPDATEDROP, ALTER
ROW EXCLUSIVEINSERT/UPDATE/DELETEALTER TABLE, LOCK
SHARE UPDATE EXCLUSIVEVACUUM, CREATE INDEX CONCURRENTLYOther VACUUMs, ALTER
SHARECREATE INDEX (non-concurrent)All writes
ACCESS EXCLUSIVEDROP, TRUNCATE, VACUUM FULL, some ALTEREverything including SELECT
Deadlock
circular lock wait
Session A waits for Session B's lock, and Session B waits for Session A's lock. Postgres detects this within deadlock_timeout (default 1s) and kills one transaction. Fix: always acquire locks in a consistent order in your application code.
Lock Wait Monitoring
find who's blocking whom
SELECT blocking.pid, blocked.pid AS waiting FROM pg_stat_activity blocked JOIN pg_stat_activity blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid));
Advisory Locks
application-level mutexes
Custom locks your application defines β€” Postgres doesn't know their meaning. Useful for preventing two workers from running the same job simultaneously.
SELECT pg_advisory_lock(12345); -- do work SELECT pg_advisory_unlock(12345);
πŸ’Ύ
06 Β· Memory
Buffers & Caches
shared_buffers
Postgres's own page cache
The shared memory pool all backends share. Hot pages live here. Start at 25% of RAM. A cache hit means no disk I/O. Monitor hit ratio β€” should be >99% for OLTP:
SELECT round(blks_hit * 100.0 / (blks_hit + blks_read), 2) AS hit_ratio FROM pg_stat_database WHERE datname = current_database();
work_mem
per-sort / per-hash memory
Memory per sort operation or hash table. Each query can use multiple work_mem chunks. Set too low β†’ spills to disk (slow). Set too high Γ— many connections = OOM. Typical: 4–64 MB. Use SET LOCAL for specific heavy queries.
effective_cache_size
planner hint, not allocated
Tells the planner how much memory is available for caching (shared_buffers + OS page cache). Not actually allocated! Higher value nudges the planner toward index scans. Typical: 50–75% of RAM.
Buffer Eviction (Clock Sweep)
how Postgres manages its cache
When shared_buffers is full, Postgres uses a clock sweep algorithm to evict pages. Each buffer has a usage count. The sweeper decrements counts as it scans; it evicts the first buffer with count 0. Frequently accessed pages survive longer.
πŸ“
07 Β· Durability
WAL β€” Write-Ahead Log
What is WAL?
Before any data page is modified on disk, Postgres writes a log record first (write-ahead). If Postgres crashes mid-write, it replays WAL on restart to get back to a consistent state. WAL is stored in pg_wal/. It's also the foundation for replication β€” standbys stream WAL from primary.
Transaction COMMIT
β†’
WAL flushed to disk
β†’
Client gets "success"
β†’
Data pages written later
LSN
Log Sequence Number
A byte offset into the WAL stream (e.g. 0/3A4F2B0). Used to track replication lag, confirm data has been received, and coordinate crash recovery. Compare primary vs replica LSN to measure lag:
SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn) AS lag_bytes FROM pg_stat_replication;
Checkpoint
flushing dirty pages to disk
A checkpoint flushes all dirty shared_buffers to disk and writes a checkpoint record in WAL. Crash recovery only needs to replay WAL from the last checkpoint. Controlled by checkpoint_completion_target and max_wal_size.
WAL Level
minimal Β· replica Β· logical
minimal β€” bare minimum for crash recovery.
replica β€” enough for physical standby replication (default).
logical β€” needed for logical replication, pgoutput decoder, CDC tools like Debezium.
synchronous_commit
durability vs speed dial
Controls when Postgres confirms a COMMIT to the client:
on (default) β€” WAL flushed before reply.
off β€” reply immediately, WAL flushed in background. Risk: up to wal_writer_delay (200ms) of data loss on crash. No corruption risk β€” only recent uncommitted transactions could be lost.
πŸ”„
08 Β· Replication
HA & Standbys
Streaming Replication
physical, byte-for-byte copy
Standby connects to primary and streams WAL records in real time. The standby is a binary copy β€” same Postgres major version required. Standbys can serve read-only queries (hot_standby = on).
Logical Replication
row-level, selective
Replicates individual DML changes (INSERT/UPDATE/DELETE) decoded from WAL. Can replicate specific tables, across major versions, and to non-Postgres targets. Publisher β†’ Subscriber model. Useful for zero-downtime major upgrades.
Replication Slot
⚠️ WAL retention mechanism
A slot makes the primary retain WAL until the subscriber consumes it. If a subscriber goes offline for a long time, WAL accumulates and can fill your disk. Monitor pg_replication_slots closely β€” drop stale slots!
⚠️
Disk full risk: An inactive replication slot will make Postgres keep WAL forever.
Failover vs Switchover
planned vs unplanned promotion
Switchover β€” planned, graceful. Primary is demoted cleanly, standby promoted. Zero data loss.

Failover β€” unplanned, primary is dead. Standby is promoted. Potential data loss equal to replication lag at time of failure.
pg_basebackup
base backup for new standbys
Creates a consistent physical backup of a running Postgres cluster. Used to provision new standbys or as a base for PITR restores. Includes WAL needed to make the backup consistent on replay.
πŸ”
09 Β· Indexes
Index Types & Usage
B-tree
the default, for =, <, >, BETWEEN
Balanced tree. Good for equality and range queries on any orderable type. Supports ORDER BY without a sort step. Use for 90% of indexes.
GIN
Generalized Inverted Index
Indexes elements within a value β€” arrays, JSONB keys, full-text tsvector. Slow to build and update, fast to query. Use for @>, &&, @@ operators.
GiST / BRIN
geometry / sorted large tables
GiST β€” for geometric types, PostGIS, full-text, exclusion constraints. Lossy (checks heap).

BRIN β€” tiny index storing min/max per page range. Only good when data is physically sorted (time-series, log tables).
Partial Index
index a subset of rows
Index only rows matching a WHERE clause. Smaller, faster, and allows unique constraints on subsets:
CREATE INDEX idx_active_users ON users(email) WHERE status = 'active';
Index-Only Scan
heap access avoided
If all columns needed by a query are in the index, Postgres reads only the index without touching the heap β€” very fast. Requires the VM to confirm tuples are visible. This is why VACUUM matters for performance.
CREATE INDEX CONCURRENTLY
zero-downtime index builds
Builds the index without locking the table for writes. Takes longer and does 2 passes. If it fails, leaves an INVALID index β€” check pg_indexes and drop/rebuild.
SELECT indexname, indisvalid FROM pg_indexes JOIN pg_index USING(indexrelid) WHERE NOT indisvalid;
πŸ€–
10 Β· Automation
Autovacuum β€” The Background Daemon
How Autovacuum Decides to Run
Autovacuum fires on a table when dead tuples exceed this threshold:
threshold = autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor Γ— reltuples -- default: 50 + 0.2 Γ— table_rows -- so a 1M row table triggers at 200,050 dead tuples
For large, hot tables: set per-table storage parameters to lower the threshold:
ALTER TABLE big_table SET (autovacuum_vacuum_scale_factor = 0.01);
autovacuum_max_workers
parallel vacuum workers
How many autovacuum workers can run simultaneously (default 3). Each worker handles one table. On busy databases with many tables, increase this. Workers are throttled by autovacuum_vacuum_cost_delay to be gentle on I/O.
Monitoring Autovacuum
is it keeping up?
-- Last vacuum/analyze times per table SELECT relname, last_autovacuum, last_autoanalyze, n_dead_tup, n_live_tup FROM pg_stat_user_tables ORDER BY n_dead_tup DESC LIMIT 10;
Autovacuum & Long Transactions
the nemesis
A long-running transaction prevents autovacuum from removing dead tuples created before it started β€” those rows are still "potentially visible" to the old transaction. This causes table bloat fast. Kill idle-in-transaction sessions promptly.
πŸ“ˆ
11 Β· Bloat
Table & Index Bloat
Table Bloat
wasted space in the heap
Dead tuples not yet reclaimed by VACUUM. The file grows but never shrinks (unless VACUUM FULL or pg_repack). Bloat causes more I/O: Postgres reads pages full of dead rows looking for live ones. High bloat = slow sequential scans.
Index Bloat
indexes bloat too!
B-tree index leaf pages accumulate dead entries. Regular VACUUM cleans index entries but doesn't shrink the tree. Use REINDEX CONCURRENTLY to rebuild a bloated index online without downtime.
pg_repack
online table/index compaction
Extension that rebuilds a table in the background and swaps it in with minimal locking β€” unlike VACUUM FULL which locks the whole time. The go-to tool for reclaiming bloat in production without a maintenance window.
FSM β€” Free Space Map
the recycling bin registry
Tracks how much free space exists in each page. After VACUUM marks dead tuples as free, it updates the FSM. INSERTs consult the FSM to find pages with room, avoiding writing to the end of the file constantly.
🧠
12 Β· Query Planner
EXPLAIN & Query Optimization
EXPLAIN ANALYZE β€” your most important tool
Shows the actual execution plan with real timing. Never tune without it.
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT * FROM orders WHERE user_id = 42;
Key things to look for: Rows estimate vs actual (big gap = stale stats), Seq Scan on large tables (missing index?), Hash Batches > 1 (work_mem too low), Buffers: hit vs read (cache misses).
Seq Scan vs Index Scan
planner chooses based on cost
The planner chooses a Seq Scan when it's cheaper β€” for example, if it estimates most of the table will be returned, reading sequentially is faster than random index lookups. A Seq Scan on a large table isn't always wrong.
Join Types
nested loop Β· hash join Β· merge join
Nested Loop β€” outer row Γ— inner scan. Good for small tables or indexed inner.
Hash Join β€” build hash table of smaller side, probe with larger. Good for large unsorted sets.
Merge Join β€” both inputs must be sorted. Good when inputs are pre-sorted via index.
pg_stat_statements
query performance history
Extension that tracks query performance across all executions β€” total time, calls, rows. Essential for finding which queries to optimize first:
SELECT query, calls, mean_exec_time, total_exec_time FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;

PostgreSQL DBA Field Guide Β· Internal Concepts Reference

PostgreSQL 16+ DBA Edition

Install PostgreSQL 17.4 from Source code

Install PostgreSQL 17.4 Using Source Code (Linux 9)

Table of Contents



0. Environment

ParameterValue
Host Namepgdb01
IP192.168.2.71
OSLinux 9
PostgreSQL Version17.4
Data Directory/pgData/pgsql/17.4
PG WAL/pgWal/pgsql/17.4
BIN Directory/pgbin/pgsql/17.4/bin
Software Staging Directory/pg_Backup/stage

1. Set SELINUX to Permissive and Restart the server

# Set SELINUX to permissive

[root@pgdb02 ~]# grep ^SELINUX= /etc/selinux/config
SELINUX=enforcing
[root@pgdb02 ~]#
[root@pgdb02 ~]# sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config
[root@pgdb02 ~]#
[root@pgdb02 ~]# grep ^SELINUX= /etc/selinux/config
SELINUX=permissive
[root@pgdb02 ~]#
[root@pgdb02 ~]# shutdown -Fr now   <---- Restart the server to take effect

2. Install Dependencies

**Note:** For testing purposes, I intentionally did not install the following dependency packages:Β dnf install -y perl perl-core perl-ExtUtils-MakeMakerWe can see dependency-related error to be reproduced and observed during the installation process.**Caution:** If you do not want toΒ  encounter the error described in **Step 7**, install the above packages before proceeding.As part of this exercise, the installation will be cleaned up after the error is encountered, and the installation process will then be repeated with the required dependencies installed to demonstrate a successful installation.
[root@pgdb01 ~]# dnf install -y readline-devel zlib-devel gcc make libicu-devel openssl-devel bison flex wget tar
Last metadata expiration check: 0:08:12 ago on Tue 21 Apr 2026 07:35:12 PM.
Package wget-1.21.1-8.el9_4.x86_64 is already installed.
Package tar-2:1.34-7.el9.x86_64 is already installed.
Dependencies resolved.
==============================================================================================================================================================================================================
 Package                                                 Architecture                          Version                                                 Repository                                        Size
==============================================================================================================================================================================================================
Installing:
 bison                                                   x86_64                                3.7.4-5.el9                                             ol9_appstream                                    1.0 M
 flex                                                    x86_64                                2.6.4-9.el9                                             ol9_appstream                                    341 k
 gcc                                                     x86_64                                11.5.0-11.0.2.el9                                       ol9_appstream                                     33 M
 libicu-devel                                            x86_64                                67.1-10.el9_6                                           ol9_appstream                                    1.3 M
 make                                                    x86_64                                1:4.3-8.el9                                             ol9_baseos_latest                                570 k
 openssl-devel                                           x86_64                                1:3.5.1-7.0.1.el9_7                                     ol9_appstream                                    4.2 M
 readline-devel                                          x86_64                                8.1-4.el9                                               ol9_appstream                                    238 k
 zlib-devel                                              x86_64                                1.2.11-40.el9                                           ol9_appstream                                     51 k
Upgrading:
 cpp                                                     x86_64                                11.5.0-11.0.2.el9                                       ol9_appstream                                     11 M
 glibc                                                   x86_64                                2.34-231.0.1.el9_7.10                                   ol9_baseos_latest                                2.0 M
 glibc-all-langpacks                                     x86_64                                2.34-231.0.1.el9_7.10                                   ol9_baseos_latest                                 18 M
 glibc-common                                            x86_64                                2.34-231.0.1.el9_7.10                                   ol9_baseos_latest                                330 k
 glibc-gconv-extra                                       x86_64                                2.34-231.0.1.el9_7.10                                   ol9_baseos_latest                                1.8 M
 glibc-langpack-en                                       x86_64                                2.34-231.0.1.el9_7.10                                   ol9_baseos_latest                                969 k
 libgcc                                                  x86_64                                11.5.0-11.0.2.el9                                       ol9_baseos_latest                                 94 k
 libgomp                                                 x86_64                                11.5.0-11.0.2.el9                                       ol9_baseos_latest                                263 k
 libicu                                                  x86_64                                67.1-10.el9_6                                           ol9_baseos_latest                                9.6 M
 openssl                                                 x86_64                                1:3.5.1-7.0.1.el9_7                                     ol9_baseos_latest                                1.6 M
 openssl-fips-provider                                   x86_64                                3.0.7-8.0.1.el9                                         ol9_baseos_latest                                8.3 k
 openssl-fips-provider-so                                x86_64                                3.0.7-8.0.1.el9                                         ol9_baseos_latest                                575 k
 openssl-libs                                            x86_64                                1:3.5.1-7.0.1.el9_7                                     ol9_baseos_latest                                2.3 M
 tar                                                     x86_64                                2:1.34-9.el9_7                                          ol9_baseos_latest                                927 k
Installing dependencies:
 glibc-devel                                             x86_64                                2.34-231.0.1.el9_7.10                                   ol9_appstream                                     60 k
 glibc-headers                                           x86_64                                2.34-231.0.1.el9_7.10                                   ol9_appstream                                    921 k
 kernel-headers                                          x86_64                                5.14.0-611.47.1.el9_7                                   ol9_appstream                                    3.6 M
 libxcrypt-devel                                         x86_64                                4.4.18-3.el9                                            ol9_appstream                                     42 k
 m4                                                      x86_64                                1.4.19-1.el9                                            ol9_appstream                                    333 k
 ncurses-c++-libs                                        x86_64                                6.2-10.20210508.el9                                     ol9_appstream                                     36 k
 ncurses-devel                                           x86_64                                6.2-10.20210508.el9                                     ol9_appstream                                    684 k

Transaction Summary
==============================================================================================================================================================================================================
Install  15 Packages
Upgrade  14 Packages

Total download size: 95 M
Downloading Packages:
(1/29): make-4.3-8.el9.x86_64.rpm                                                                                                                                             1.3 MB/s | 570 kB     00:00
(2/29): flex-2.6.4-9.el9.x86_64.rpm                                                                                                                                           792 kB/s | 341 kB     00:00
(3/29): bison-3.7.4-5.el9.x86_64.rpm                                                                                                                                          2.2 MB/s | 1.0 MB     00:00
(4/29): glibc-devel-2.34-231.0.1.el9_7.10.x86_64.rpm                                                                                                                          1.4 MB/s |  60 kB     00:00
(5/29): glibc-headers-2.34-231.0.1.el9_7.10.x86_64.rpm                                                                                                                        3.8 MB/s | 921 kB     00:00
(6/29): kernel-headers-5.14.0-611.47.1.el9_7.x86_64.rpm                                                                                                                       3.7 MB/s | 3.6 MB     00:00
(7/29): libicu-devel-67.1-10.el9_6.x86_64.rpm                                                                                                                                 1.6 MB/s | 1.3 MB     00:00
(8/29): libxcrypt-devel-4.4.18-3.el9.x86_64.rpm                                                                                                                               885 kB/s |  42 kB     00:00
(9/29): ncurses-c++-libs-6.2-10.20210508.el9.x86_64.rpm                                                                                                                       255 kB/s |  36 kB     00:00
(10/29): m4-1.4.19-1.el9.x86_64.rpm                                                                                                                                           1.9 MB/s | 333 kB     00:00
(11/29): ncurses-devel-6.2-10.20210508.el9.x86_64.rpm                                                                                                                         2.8 MB/s | 684 kB     00:00
(12/29): readline-devel-8.1-4.el9.x86_64.rpm                                                                                                                                  1.5 MB/s | 238 kB     00:00
(13/29): zlib-devel-1.2.11-40.el9.x86_64.rpm                                                                                                                                  425 kB/s |  51 kB     00:00
(14/29): glibc-2.34-231.0.1.el9_7.10.x86_64.rpm                                                                                                                               3.2 MB/s | 2.0 MB     00:00
(15/29): openssl-devel-3.5.1-7.0.1.el9_7.x86_64.rpm                                                                                                                           3.5 MB/s | 4.2 MB     00:01
(16/29): glibc-common-2.34-231.0.1.el9_7.10.x86_64.rpm                                                                                                                        1.9 MB/s | 330 kB     00:00
(17/29): glibc-gconv-extra-2.34-231.0.1.el9_7.10.x86_64.rpm                                                                                                                   3.0 MB/s | 1.8 MB     00:00
(18/29): glibc-langpack-en-2.34-231.0.1.el9_7.10.x86_64.rpm                                                                                                                   2.4 MB/s | 969 kB     00:00
(19/29): libgcc-11.5.0-11.0.2.el9.x86_64.rpm                                                                                                                                  921 kB/s |  94 kB     00:00
(20/29): libgomp-11.5.0-11.0.2.el9.x86_64.rpm                                                                                                                                 1.3 MB/s | 263 kB     00:00
(21/29): glibc-all-langpacks-2.34-231.0.1.el9_7.10.x86_64.rpm                                                                                                                 5.4 MB/s |  18 MB     00:03
(22/29): openssl-3.5.1-7.0.1.el9_7.x86_64.rpm                                                                                                                                 3.2 MB/s | 1.6 MB     00:00
(23/29): openssl-fips-provider-3.0.7-8.0.1.el9.x86_64.rpm                                                                                                                     273 kB/s | 8.3 kB     00:00
(24/29): libicu-67.1-10.el9_6.x86_64.rpm                                                                                                                                      3.9 MB/s | 9.6 MB     00:02
(25/29): openssl-fips-provider-so-3.0.7-8.0.1.el9.x86_64.rpm                                                                                                                  2.3 MB/s | 575 kB     00:00
(26/29): tar-1.34-9.el9_7.x86_64.rpm                                                                                                                                          3.7 MB/s | 927 kB     00:00
(27/29): openssl-libs-3.5.1-7.0.1.el9_7.x86_64.rpm                                                                                                                            3.6 MB/s | 2.3 MB     00:00
(28/29): cpp-11.5.0-11.0.2.el9.x86_64.rpm                                                                                                                                     5.4 MB/s |  11 MB     00:02
(29/29): gcc-11.5.0-11.0.2.el9.x86_64.rpm                                                                                                                                     3.5 MB/s |  33 MB     00:09
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                         9.8 MB/s |  95 MB     00:09
Oracle Linux 9 BaseOS Latest (x86_64)                                                                                                                                         3.9 MB/s | 6.2 kB     00:00
Importing GPG key 0x8D8B756F:
 Userid     : "Oracle Linux (release key 1) <secalert_us@oracle.com>"
 Fingerprint: 3E6D 826D 3FBA B389 C2F3 8E34 BC4D 06A0 8D8B 756F
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
Key imported successfully
Importing GPG key 0x8B4EFBE6:
 Userid     : "Oracle Linux (backup key 1) <secalert_us@oracle.com>"
 Fingerprint: 9822 3175 9C74 6706 5D0C E9B2 A7DD 0708 8B4E FBE6
 From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                                                      1/1
  Upgrading        : glibc-all-langpacks-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                    1/43
  Upgrading        : glibc-common-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                           2/43
  Upgrading        : glibc-gconv-extra-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                      3/43
  Running scriptlet: glibc-gconv-extra-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                      3/43
  Upgrading        : glibc-langpack-en-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                      4/43
  Upgrading        : libgcc-11.5.0-11.0.2.el9.x86_64                                                                                                                                                     5/43
  Running scriptlet: libgcc-11.5.0-11.0.2.el9.x86_64                                                                                                                                                     5/43
  Running scriptlet: glibc-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                                  6/43
  Upgrading        : glibc-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                                  6/43
  Running scriptlet: glibc-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                                  6/43
  Installing       : m4-1.4.19-1.el9.x86_64                                                                                                                                                              7/43
  Installing       : make-1:4.3-8.el9.x86_64                                                                                                                                                             8/43
  Installing       : glibc-headers-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                          9/43
  Installing       : ncurses-c++-libs-6.2-10.20210508.el9.x86_64                                                                                                                                        10/43
  Installing       : ncurses-devel-6.2-10.20210508.el9.x86_64                                                                                                                                           11/43
  Upgrading        : libgomp-11.5.0-11.0.2.el9.x86_64                                                                                                                                                   12/43
  Upgrading        : libicu-67.1-10.el9_6.x86_64                                                                                                                                                        13/43
  Upgrading        : openssl-fips-provider-so-3.0.7-8.0.1.el9.x86_64                                                                                                                                    14/43
  Upgrading        : openssl-fips-provider-3.0.7-8.0.1.el9.x86_64                                                                                                                                       15/43
  Upgrading        : openssl-libs-1:3.5.1-7.0.1.el9_7.x86_64                                                                                                                                            16/43
  Upgrading        : cpp-11.5.0-11.0.2.el9.x86_64                                                                                                                                                       17/43
  Installing       : kernel-headers-5.14.0-611.47.1.el9_7.x86_64                                                                                                                                        18/43
  Installing       : libxcrypt-devel-4.4.18-3.el9.x86_64                                                                                                                                                19/43
  Installing       : glibc-devel-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                           20/43
  Installing       : gcc-11.5.0-11.0.2.el9.x86_64                                                                                                                                                       21/43
  Installing       : openssl-devel-1:3.5.1-7.0.1.el9_7.x86_64                                                                                                                                           22/43
  Upgrading        : openssl-1:3.5.1-7.0.1.el9_7.x86_64                                                                                                                                                 23/43
  Installing       : libicu-devel-67.1-10.el9_6.x86_64                                                                                                                                                  24/43
  Installing       : readline-devel-8.1-4.el9.x86_64                                                                                                                                                    25/43
  Installing       : bison-3.7.4-5.el9.x86_64                                                                                                                                                           26/43
  Installing       : flex-2.6.4-9.el9.x86_64                                                                                                                                                            27/43
  Upgrading        : tar-2:1.34-9.el9_7.x86_64                                                                                                                                                          28/43
  Installing       : zlib-devel-1.2.11-40.el9.x86_64                                                                                                                                                    29/43
  Cleanup          : openssl-1:3.2.2-6.0.1.el9_5.1.x86_64                                                                                                                                               30/43
  Cleanup          : libicu-67.1-9.el9.x86_64                                                                                                                                                           31/43
  Cleanup          : openssl-libs-1:3.2.2-6.0.1.el9_5.1.x86_64                                                                                                                                          32/43
  Cleanup          : cpp-11.5.0-5.0.1.el9.x86_64                                                                                                                                                        33/43
  Cleanup          : tar-2:1.34-7.el9.x86_64                                                                                                                                                            34/43
  Cleanup          : libgomp-11.5.0-5.0.1.el9.x86_64                                                                                                                                                    35/43
  Cleanup          : openssl-fips-provider-3.0.7-6.0.1.el9_5.x86_64                                                                                                                                     36/43
  Cleanup          : openssl-fips-provider-so-3.0.7-6.0.1.el9_5.x86_64                                                                                                                                  37/43
  Cleanup          : glibc-all-langpacks-2.34-168.0.1.el9.x86_64                                                                                                                                        38/43
  Cleanup          : glibc-gconv-extra-2.34-168.0.1.el9.x86_64                                                                                                                                          39/43
  Running scriptlet: glibc-gconv-extra-2.34-168.0.1.el9.x86_64                                                                                                                                          39/43
  Cleanup          : glibc-common-2.34-168.0.1.el9.x86_64                                                                                                                                               40/43
  Cleanup          : glibc-langpack-en-2.34-168.0.1.el9.x86_64                                                                                                                                          41/43
  Cleanup          : glibc-2.34-168.0.1.el9.x86_64                                                                                                                                                      42/43
  Cleanup          : libgcc-11.5.0-5.0.1.el9.x86_64                                                                                                                                                     43/43
  Running scriptlet: libgcc-11.5.0-5.0.1.el9.x86_64                                                                                                                                                     43/43
  Running scriptlet: glibc-all-langpacks-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                   43/43
  Running scriptlet: libgcc-11.5.0-5.0.1.el9.x86_64                                                                                                                                                     43/43
  Verifying        : make-1:4.3-8.el9.x86_64                                                                                                                                                             1/43
  Verifying        : bison-3.7.4-5.el9.x86_64                                                                                                                                                            2/43
  Verifying        : flex-2.6.4-9.el9.x86_64                                                                                                                                                             3/43
  Verifying        : gcc-11.5.0-11.0.2.el9.x86_64                                                                                                                                                        4/43
  Verifying        : glibc-devel-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                            5/43
  Verifying        : glibc-headers-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                          6/43
  Verifying        : kernel-headers-5.14.0-611.47.1.el9_7.x86_64                                                                                                                                         7/43
  Verifying        : libicu-devel-67.1-10.el9_6.x86_64                                                                                                                                                   8/43
  Verifying        : libxcrypt-devel-4.4.18-3.el9.x86_64                                                                                                                                                 9/43
  Verifying        : m4-1.4.19-1.el9.x86_64                                                                                                                                                             10/43
  Verifying        : ncurses-c++-libs-6.2-10.20210508.el9.x86_64                                                                                                                                        11/43
  Verifying        : ncurses-devel-6.2-10.20210508.el9.x86_64                                                                                                                                           12/43
  Verifying        : openssl-devel-1:3.5.1-7.0.1.el9_7.x86_64                                                                                                                                           13/43
  Verifying        : readline-devel-8.1-4.el9.x86_64                                                                                                                                                    14/43
  Verifying        : zlib-devel-1.2.11-40.el9.x86_64                                                                                                                                                    15/43
  Verifying        : glibc-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                                 16/43
  Verifying        : glibc-2.34-168.0.1.el9.x86_64                                                                                                                                                      17/43
  Verifying        : glibc-all-langpacks-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                   18/43
  Verifying        : glibc-all-langpacks-2.34-168.0.1.el9.x86_64                                                                                                                                        19/43
  Verifying        : glibc-common-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                          20/43
  Verifying        : glibc-common-2.34-168.0.1.el9.x86_64                                                                                                                                               21/43
  Verifying        : glibc-gconv-extra-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                     22/43
  Verifying        : glibc-gconv-extra-2.34-168.0.1.el9.x86_64                                                                                                                                          23/43
  Verifying        : glibc-langpack-en-2.34-231.0.1.el9_7.10.x86_64                                                                                                                                     24/43
  Verifying        : glibc-langpack-en-2.34-168.0.1.el9.x86_64                                                                                                                                          25/43
  Verifying        : libgcc-11.5.0-11.0.2.el9.x86_64                                                                                                                                                    26/43
  Verifying        : libgcc-11.5.0-5.0.1.el9.x86_64                                                                                                                                                     27/43
  Verifying        : libgomp-11.5.0-11.0.2.el9.x86_64                                                                                                                                                   28/43
  Verifying        : libgomp-11.5.0-5.0.1.el9.x86_64                                                                                                                                                    29/43
  Verifying        : libicu-67.1-10.el9_6.x86_64                                                                                                                                                        30/43
  Verifying        : libicu-67.1-9.el9.x86_64                                                                                                                                                           31/43
  Verifying        : openssl-1:3.5.1-7.0.1.el9_7.x86_64                                                                                                                                                 32/43
  Verifying        : openssl-1:3.2.2-6.0.1.el9_5.1.x86_64                                                                                                                                               33/43
  Verifying        : openssl-fips-provider-3.0.7-8.0.1.el9.x86_64                                                                                                                                       34/43
  Verifying        : openssl-fips-provider-3.0.7-6.0.1.el9_5.x86_64                                                                                                                                     35/43
  Verifying        : openssl-fips-provider-so-3.0.7-8.0.1.el9.x86_64                                                                                                                                    36/43
  Verifying        : openssl-fips-provider-so-3.0.7-6.0.1.el9_5.x86_64                                                                                                                                  37/43
  Verifying        : openssl-libs-1:3.5.1-7.0.1.el9_7.x86_64                                                                                                                                            38/43
  Verifying        : openssl-libs-1:3.2.2-6.0.1.el9_5.1.x86_64                                                                                                                                          39/43
  Verifying        : tar-2:1.34-9.el9_7.x86_64                                                                                                                                                          40/43
  Verifying        : tar-2:1.34-7.el9.x86_64                                                                                                                                                            41/43
  Verifying        : cpp-11.5.0-11.0.2.el9.x86_64                                                                                                                                                       42/43
  Verifying        : cpp-11.5.0-5.0.1.el9.x86_64                                                                                                                                                        43/43

Upgraded:
  cpp-11.5.0-11.0.2.el9.x86_64                      glibc-2.34-231.0.1.el9_7.10.x86_64                glibc-all-langpacks-2.34-231.0.1.el9_7.10.x86_64    glibc-common-2.34-231.0.1.el9_7.10.x86_64
  glibc-gconv-extra-2.34-231.0.1.el9_7.10.x86_64    glibc-langpack-en-2.34-231.0.1.el9_7.10.x86_64    libgcc-11.5.0-11.0.2.el9.x86_64                     libgomp-11.5.0-11.0.2.el9.x86_64
  libicu-67.1-10.el9_6.x86_64                       openssl-1:3.5.1-7.0.1.el9_7.x86_64                openssl-fips-provider-3.0.7-8.0.1.el9.x86_64        openssl-fips-provider-so-3.0.7-8.0.1.el9.x86_64
  openssl-libs-1:3.5.1-7.0.1.el9_7.x86_64           tar-2:1.34-9.el9_7.x86_64
Installed:
  bison-3.7.4-5.el9.x86_64                           flex-2.6.4-9.el9.x86_64                             gcc-11.5.0-11.0.2.el9.x86_64                        glibc-devel-2.34-231.0.1.el9_7.10.x86_64
  glibc-headers-2.34-231.0.1.el9_7.10.x86_64         kernel-headers-5.14.0-611.47.1.el9_7.x86_64         libicu-devel-67.1-10.el9_6.x86_64                   libxcrypt-devel-4.4.18-3.el9.x86_64
  m4-1.4.19-1.el9.x86_64                             make-1:4.3-8.el9.x86_64                             ncurses-c++-libs-6.2-10.20210508.el9.x86_64         ncurses-devel-6.2-10.20210508.el9.x86_64
  openssl-devel-1:3.5.1-7.0.1.el9_7.x86_64           readline-devel-8.1-4.el9.x86_64                     zlib-devel-1.2.11-40.el9.x86_64

Complete!
[root@pgdb01 ~]#

3. Create postgres User

[root@pgdb01 ~]# useradd postgres
[root@pgdb01 ~]# passwd postgres
Changing password for user postgres.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
[root@pgdb01 ~]#

4. Download PostgreSQL Source

[root@pgdb01 ~]# mkdir -p /pg_Backup/stage

[root@pgdb01 ~]# cd /pg_Backup/stage
[root@pgdb01 stage]# wget https://ftp.postgresql.org/pub/source/v17.4/postgresql-17.4.tar.gz
--2026-04-21 20:22:48--  https://ftp.postgresql.org/pub/source/v17.4/postgresql-17.4.tar.gz
Resolving ftp.postgresql.org (ftp.postgresql.org)... 151.101.211.52, 2a04:4e42:31::820
Connecting to ftp.postgresql.org (ftp.postgresql.org)|151.101.211.52|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 28056622 (27M) [application/gzip]
Saving to: β€˜postgresql-17.4.tar.gz’

postgresql-17.4.tar.gz                              100%[=================================================================================================================>]  26.76M  10.2MB/s    in 2.6s

2026-04-21 20:22:51 (10.2 MB/s) - β€˜postgresql-17.4.tar.gz’ saved [28056622/28056622]

[root@pgdb01 stage]#

5. Extract Source

[root@pgdb01 stage]# tar -xvf postgresql-17.4.tar.gz
postgresql-17.4/
postgresql-17.4/.cirrus.star
postgresql-17.4/.cirrus.tasks.yml
..
..
postgresql-17.4/src/tutorial/funcs.source
postgresql-17.4/src/tutorial/syscat.source
[root@pgdb01 stage]#
[root@pgdb01 stage]# ls -ltr
total 27404
drwxrwxr-x. 6 root root     4096 Feb 18  2025 postgresql-17.4
-rw-r--r--. 1 root root 28056622 Feb 18  2025 postgresql-17.4.tar.gz
[root@pgdb01 stage]# cd postgresql-17.4
[root@pgdb01 postgresql-17.4]# pwd
/pg_Backup/stage/postgresql-17.4
[root@pgdb01 postgresql-17.4]#

6. Configure Build

[root@pgdb01 postgresql-17.4]# ls -ltr /pg_Backup/stage/postgresql-17.4/configure
-rwxrwxr-x. 1 root root 580836 Feb 18  2025 /pg_Backup/stage/postgresql-17.4/configure
[root@pgdb01 postgresql-17.4]#

Configure do only:

-- checks system dependencies
-- prepares Makefiles
-- stores your install path (/pgbin/pgsql/17.4) internally, it won't create bin directory.
-- It does NOT install anything yet


[root@pgdb01 postgresql-17.4]# ./configure --prefix=/pgbin/pgsql/17.4 --with-pgport=5432
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking which template to use... linux
checking whether NLS is wanted... no
checking for default port number... 5432
checking for block size... 8kB
checking for segment size... 1GB
checking for WAL block size... 8kB
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for gcc option to accept ISO C99... none needed
checking for g++... no
checking for c++... no
checking whether we are using the GNU C++ compiler... no
checking whether g++ accepts -g... no
checking for gawk... gawk
checking whether gcc supports -Wdeclaration-after-statement, for CFLAGS... yes
checking whether gcc supports -Werror=vla, for CFLAGS... yes
checking whether gcc supports -Werror=unguarded-availability-new, for CFLAGS... no
checking whether g++ supports -Werror=unguarded-availability-new, for CXXFLAGS... no
checking whether gcc supports -Wendif-labels, for CFLAGS... yes
checking whether g++ supports -Wendif-labels, for CXXFLAGS... no
checking whether gcc supports -Wmissing-format-attribute, for CFLAGS... yes
checking whether g++ supports -Wmissing-format-attribute, for CXXFLAGS... no
checking whether gcc supports -Wimplicit-fallthrough=3, for CFLAGS... yes
checking whether g++ supports -Wimplicit-fallthrough=3, for CXXFLAGS... no
checking whether gcc supports -Wcast-function-type, for CFLAGS... yes
checking whether g++ supports -Wcast-function-type, for CXXFLAGS... no
checking whether gcc supports -Wshadow=compatible-local, for CFLAGS... yes
checking whether g++ supports -Wshadow=compatible-local, for CXXFLAGS... no
checking whether gcc supports -Wformat-security, for CFLAGS... yes
checking whether g++ supports -Wformat-security, for CXXFLAGS... no
checking whether gcc supports -fno-strict-aliasing, for CFLAGS... yes
checking whether g++ supports -fno-strict-aliasing, for CXXFLAGS... no
checking whether gcc supports -fwrapv, for CFLAGS... yes
checking whether g++ supports -fwrapv, for CXXFLAGS... no
checking whether gcc supports -fexcess-precision=standard, for CFLAGS... yes
checking whether g++ supports -fexcess-precision=standard, for CXXFLAGS... no
checking whether gcc supports -funroll-loops, for CFLAGS_UNROLL_LOOPS... yes
checking whether gcc supports -ftree-vectorize, for CFLAGS_VECTORIZE... yes
checking whether gcc supports -Wunused-command-line-argument, for NOT_THE_CFLAGS... no
checking whether gcc supports -Wcompound-token-split-by-macro, for NOT_THE_CFLAGS... no
checking whether gcc supports -Wformat-truncation, for NOT_THE_CFLAGS... yes
checking whether gcc supports -Wstringop-truncation, for NOT_THE_CFLAGS... yes
checking whether gcc supports -Wcast-function-type-strict, for NOT_THE_CFLAGS... no
checking whether gcc supports -fvisibility=hidden, for CFLAGS_SL_MODULE... yes
checking whether g++ supports -fvisibility=hidden, for CXXFLAGS_SL_MODULE... no
checking whether g++ supports -fvisibility-inlines-hidden, for CXXFLAGS_SL_MODULE... no
checking whether the C compiler still works... yes
checking how to run the C preprocessor... gcc -E
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking whether to build with ICU support... yes
checking for icu-uc icu-i18n... yes
checking whether to build with Tcl... no
checking whether to build Perl modules... no
checking whether to build Python modules... no
checking whether to build with GSSAPI support... no
checking whether to build with PAM support... no
checking whether to build with BSD Authentication support... no
checking whether to build with LDAP support... no
checking whether to build with Bonjour support... no
checking whether to build with SELinux support... no
checking whether to build with systemd support... no
checking whether to build with XML support... no
checking whether to build with LZ4 support... no
checking whether to build with ZSTD support... no
checking for strip... strip
checking whether it is possible to strip libraries... yes
checking for ar... ar
checking for a BSD-compatible install... /usr/bin/install -c
checking for tar... /usr/bin/tar
checking whether ln -s works... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for bison... /usr/bin/bison
configure: using bison (GNU Bison) 3.7.4
checking for flex... /usr/bin/flex
configure: using flex 2.6.4
checking for perl... /usr/bin/perl
configure: using perl 5.32.1
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking whether gcc is Clang... no
checking whether pthreads work with -pthread... yes
checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE
checking whether more special flags are required for pthreads... no
checking for PTHREAD_PRIO_INHERIT... yes
checking pthread.h usability... yes
checking pthread.h presence... yes
checking for pthread.h... yes
checking for strerror_r... yes
checking whether strerror_r returns int... no
checking for main in -lm... yes
checking for library containing setproctitle... no
checking for library containing dlsym... none required
checking for library containing socket... none required
checking for library containing getopt_long... none required
checking for library containing shm_open... none required
checking for library containing shm_unlink... none required
checking for library containing clock_gettime... none required
checking for library containing shmget... none required
checking for library containing backtrace_symbols... none required
checking for library containing pthread_barrier_wait... none required
checking for library containing readline... -lreadline
checking for inflate in -lz... yes
checking atomic.h usability... no
checking atomic.h presence... no
checking for atomic.h... no
checking copyfile.h usability... no
checking copyfile.h presence... no
checking for copyfile.h... no
checking execinfo.h usability... yes
checking execinfo.h presence... yes
checking for execinfo.h... yes
checking getopt.h usability... yes
checking getopt.h presence... yes
checking for getopt.h... yes
checking ifaddrs.h usability... yes
checking ifaddrs.h presence... yes
checking for ifaddrs.h... yes
checking langinfo.h usability... yes
checking langinfo.h presence... yes
checking for langinfo.h... yes
checking mbarrier.h usability... no
checking mbarrier.h presence... no
checking for mbarrier.h... no
checking sys/epoll.h usability... yes
checking sys/epoll.h presence... yes
checking for sys/epoll.h... yes
checking sys/event.h usability... no
checking sys/event.h presence... no
checking for sys/event.h... no
checking sys/personality.h usability... yes
checking sys/personality.h presence... yes
checking for sys/personality.h... yes
checking sys/prctl.h usability... yes
checking sys/prctl.h presence... yes
checking for sys/prctl.h... yes
checking sys/procctl.h usability... no
checking sys/procctl.h presence... no
checking for sys/procctl.h... no
checking sys/signalfd.h usability... yes
checking sys/signalfd.h presence... yes
checking for sys/signalfd.h... yes
checking sys/ucred.h usability... no
checking sys/ucred.h presence... no
checking for sys/ucred.h... no
checking termios.h usability... yes
checking termios.h presence... yes
checking for termios.h... yes
checking ucred.h usability... no
checking ucred.h presence... no
checking for ucred.h... no
checking readline/readline.h usability... yes
checking readline/readline.h presence... yes
checking for readline/readline.h... yes
checking readline/history.h usability... yes
checking readline/history.h presence... yes
checking for readline/history.h... yes
checking zlib.h usability... yes
checking zlib.h presence... yes
checking for zlib.h... yes
checking for lz4... no
checking for zstd... no
checking for openssl... /usr/bin/openssl
configure: using openssl: OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025)
checking whether byte ordering is bigendian... no
checking for inline... inline
checking for printf format archetype... gnu_printf
checking for _Static_assert... yes
checking for typeof... typeof
checking for __builtin_types_compatible_p... yes
checking for __builtin_constant_p... yes
checking for __builtin_unreachable... yes
checking for computed goto support... yes
checking for struct tm.tm_zone... yes
checking for union semun... no
checking for socklen_t... yes
checking for struct sockaddr.sa_len... no
checking for locale_t... yes
checking for C/C++ restrict keyword... __restrict
checking for struct option... yes
checking whether assembler supports x86_64 popcntq... yes
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking size of off_t... 8
checking size of bool... 1
checking for int timezone... yes
checking for wcstombs_l declaration... no
checking for backtrace_symbols... yes
checking for copyfile... no
checking for copy_file_range... yes
checking for getifaddrs... yes
checking for getpeerucred... no
checking for inet_pton... yes
checking for kqueue... no
checking for mbstowcs_l... no
checking for memset_s... no
checking for posix_fallocate... yes
checking for ppoll... yes
checking for pthread_is_threaded_np... no
checking for setproctitle... no
checking for setproctitle_fast... no
checking for strchrnul... yes
checking for strsignal... yes
checking for syncfs... yes
checking for sync_file_range... yes
checking for uselocale... yes
checking for wcstombs_l... no
checking for __builtin_bswap16... yes
checking for __builtin_bswap32... yes
checking for __builtin_bswap64... yes
checking for __builtin_clz... yes
checking for __builtin_ctz... yes
checking for __builtin_popcount... yes
checking for __builtin_frame_address... yes
checking for _LARGEFILE_SOURCE value needed for large files... no
checking how gcc reports undeclared, standard C functions... error
checking for posix_fadvise... yes
checking whether posix_fadvise is declared... yes
checking whether fdatasync is declared... yes
checking whether strlcat is declared... no
checking whether strlcpy is declared... no
checking whether strnlen is declared... yes
checking whether preadv is declared... yes
checking whether pwritev is declared... yes
checking whether F_FULLFSYNC is declared... no
checking for explicit_bzero... yes
checking for getopt... yes
checking for getpeereid... no
checking for inet_aton... yes
checking for mkdtemp... yes
checking for strlcat... no
checking for strlcpy... no
checking for strnlen... yes
checking for pthread_barrier_wait... yes
checking for getopt_long... yes
checking for syslog... yes
checking syslog.h usability... yes
checking syslog.h presence... yes
checking for syslog.h... yes
checking for opterr... yes
checking for optreset... no
checking unicode/ucol.h usability... yes
checking unicode/ucol.h presence... yes
checking for unicode/ucol.h... yes
checking for rl_completion_suppress_quote... yes
checking for rl_filename_quote_characters... yes
checking for rl_filename_quoting_function... yes
checking for append_history... yes
checking for history_truncate_file... yes
checking for rl_completion_matches... yes
checking for rl_filename_completion_function... yes
checking for rl_reset_screen_size... yes
checking for rl_variable_bind... yes
checking test program... ok
checking whether long int is 64 bits... yes
checking for __builtin_mul_overflow... yes
checking size of void *... 8
checking size of size_t... 8
checking size of long... 8
checking alignment of short... 2
checking alignment of int... 4
checking alignment of long... 8
checking alignment of double... 8
checking for int8... no
checking for uint8... no
checking for int64... no
checking for uint64... no
checking for __int128... yes
checking for __int128 alignment bug... ok
checking alignment of PG_INT128_TYPE... 16
checking for builtin __sync char locking functions... yes
checking for builtin __sync int32 locking functions... yes
checking for builtin __sync int32 atomic operations... yes
checking for builtin __sync int64 atomic operations... yes
checking for builtin __atomic int32 atomic operations... yes
checking for builtin __atomic int64 atomic operations... yes
checking for __get_cpuid... yes
checking for __get_cpuid_count... yes
checking for __cpuid... no
checking for __cpuidex... no
checking for _xgetbv with CFLAGS=... no
checking for _xgetbv with CFLAGS=-mxsave... yes
checking for _mm512_popcnt_epi64 with CFLAGS=... no
checking for _mm512_popcnt_epi64 with CFLAGS=-mavx512vpopcntdq -mavx512bw... yes
checking for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=... yes
checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=... no
checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=-march=armv8-a+crc+simd... no
checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=-march=armv8-a+crc... no
checking for __builtin_loongarch_crcc_w_b_w, __builtin_loongarch_crcc_w_h_w, __builtin_loongarch_crcc_w_w_w and __builtin_loongarch_crcc_w_d_w... no
checking which CRC-32C implementation to use... SSE 4.2
checking for library containing sem_init... none required
checking which semaphore API to use... unnamed POSIX
checking which random number source to use... /dev/urandom
checking for /dev/urandom... yes
checking for xmllint... /usr/bin/xmllint
checking for xsltproc... /usr/bin/xsltproc
checking for fop... no
checking for dbtoepub... no
checking whether gcc supports -Wl,--as-needed, for LDFLAGS... yes
checking whether gcc supports -Wl,--export-dynamic, for LDFLAGS_EX_BE... yes
configure: using compiler=gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-11.0.2)
configure: using CFLAGS=-Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -O2
configure: using CPPFLAGS= -D_GNU_SOURCE
configure: using LDFLAGS=  -Wl,--as-needed
configure: creating ./config.status
config.status: creating GNUmakefile
config.status: creating src/Makefile.global
config.status: creating src/include/pg_config.h
config.status: creating src/include/pg_config_ext.h
config.status: creating src/interfaces/ecpg/include/ecpg_config.h
config.status: linking src/backend/port/tas/dummy.s to src/backend/port/tas.s
config.status: linking src/backend/port/posix_sema.c to src/backend/port/pg_sema.c
config.status: linking src/backend/port/sysv_shmem.c to src/backend/port/pg_shmem.c
config.status: linking src/include/port/linux.h to src/include/pg_config_os.h
config.status: linking src/makefiles/Makefile.linux to src/Makefile.port
[root@pgdb01 postgresql-17.4]#

7. Compile Source

A Makefile is a special text configuration file used by the make build automation tool to automatically compile and link C programs. Instead of manually typing long gcc compilation commands every time you modify your code, a Makefile lets you build your entire project by simply typing make into your terminal. make compiles source code into executable binary files, while make install copies those compiled files into your system directories so the program can be run from anywhere.
[root@pgdb01 postgresql-17.4]# which make
/usr/bin/make
[root@pgdb01 postgresql-17.4]#
[root@pgdb01 postgresql-17.4]# ls -ltr Makefile
-rw-rw-r--. 1 root root 1822 Feb 18  2025 Makefile
[root@pgdb01 postgresql-17.4]#

[root@pgdb01 postgresql-17.4]# make
make -C ./src/backend generated-headers
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/src/backend'
make -C ../include/catalog generated-headers
make[2]: Entering directory '/pg_Backup/stage/postgresql-17.4/src/include/catalog'
'/usr/bin/perl' ../../../src/backend/catalog/genbki.pl --include-path=../../../src/include/ \
        --set-version=17 ../../../src/include/catalog/pg_proc.h ../../../src/include/catalog/pg_type.h ../../../src/include/catalog/pg_attribute.h ../../../src/include/catalog/pg_class.h ../../../src/include/catalog/pg_attrdef.h ../../../src/include/catalog/pg_constraint.h ../../../src/include/catalog/pg_inherits.h ../../../src/include/catalog/pg_index.h ../../../src/include/catalog/pg_operator.h ../../../src/include/catalog/pg_opfamily.h ../../../src/include/catalog/pg_opclass.h ../../../src/include/catalog/pg_am.h ../../../src/include/catalog/pg_amop.h ../../../src/include/catalog/pg_amproc.h ../../../src/include/catalog/pg_language.h ../../../src/include/catalog/pg_largeobject_metadata.h ../../../src/include/catalog/pg_largeobject.h ../../../src/include/catalog/pg_aggregate.h ../../../src/include/catalog/pg_statistic.h ../../../src/include/catalog/pg_statistic_ext.h ../../../src/include/catalog/pg_statistic_ext_data.h ../../../src/include/catalog/pg_rewrite.h ../../../src/include/catalog/pg_trigger.h ../../../src/include/catalog/pg_event_trigger.h ../../../src/include/catalog/pg_description.h ../../../src/include/catalog/pg_cast.h ../../../src/include/catalog/pg_enum.h ../../../src/include/catalog/pg_namespace.h ../../../src/include/catalog/pg_conversion.h ../../../src/include/catalog/pg_depend.h ../../../src/include/catalog/pg_database.h ../../../src/include/catalog/pg_db_role_setting.h ../../../src/include/catalog/pg_tablespace.h ../../../src/include/catalog/pg_authid.h ../../../src/include/catalog/pg_auth_members.h ../../../src/include/catalog/pg_shdepend.h ../../../src/include/catalog/pg_shdescription.h ../../../src/include/catalog/pg_ts_config.h ../../../src/include/catalog/pg_ts_config_map.h ../../../src/include/catalog/pg_ts_dict.h ../../../src/include/catalog/pg_ts_parser.h ../../../src/include/catalog/pg_ts_template.h ../../../src/include/catalog/pg_extension.h ../../../src/include/catalog/pg_foreign_data_wrapper.h ../../../src/include/catalog/pg_foreign_server.h ../../../src/include/catalog/pg_user_mapping.h ../../../src/include/catalog/pg_foreign_table.h ../../../src/include/catalog/pg_policy.h ../../../src/include/catalog/pg_replication_origin.h ../../../src/include/catalog/pg_default_acl.h ../../../src/include/catalog/pg_init_privs.h ../../../src/include/catalog/pg_seclabel.h ../../../src/include/catalog/pg_shseclabel.h ../../../src/include/catalog/pg_collation.h ../../../src/include/catalog/pg_parameter_acl.h ../../../src/include/catalog/pg_partitioned_table.h ../../../src/include/catalog/pg_range.h ../../../src/include/catalog/pg_transform.h ../../../src/include/catalog/pg_sequence.h ../../../src/include/catalog/pg_publication.h ../../../src/include/catalog/pg_publication_namespace.h ../../../src/include/catalog/pg_publication_rel.h ../../../src/include/catalog/pg_subscription.h ../../../src/include/catalog/pg_subscription_rel.h
Can't locate FindBin.pm in @INC (you may need to install the FindBin module) (@INC contains: /usr/local/lib64/perl5/5.32 /usr/local/share/perl5/5.32 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5) at ../../../src/backend/catalog/genbki.pl line 20.
BEGIN failed--compilation aborted at ../../../src/backend/catalog/genbki.pl line 20.
make[2]: *** [Makefile:141: bki-stamp] Error 2
make[2]: Leaving directory '/pg_Backup/stage/postgresql-17.4/src/include/catalog'
make[1]: *** [Makefile:121: submake-catalog-headers] Error 2
make[1]: Leaving directory '/pg_Backup/stage/postgresql-17.4/src/backend'
make: *** [src/Makefile.global:384: submake-generated-headers] Error 2
[root@pgdb01 postgresql-17.4]#

*** The FindBin module is a core Perl library used to locate the absolute directory path of the currently executing script. It is primarily used in conjunction with the lib module to dynamically load local, relative modules without hardcoding paths. ****

[root@pgdb01 postgresql-17.4]# dnf install -y perl perl-core perl-ExtUtils-MakeMaker
Last metadata expiration check: 1:17:45 ago on Tue 21 Apr 2026 07:35:12 PM.
Dependencies resolved.
==============================================================================================================================================================================================================
 Package                                                    Architecture                         Version                                                Repository                                       Size
==============================================================================================================================================================================================================
Installing:
 perl                                                       x86_64                               4:5.32.1-481.1.el9_6                                   ol9_appstream                                    11 k
 perl-ExtUtils-MakeMaker                                    noarch                               2:7.60-3.el9                                           ol9_appstream                                   352 k
Upgrading:
 libstdc++                                                  x86_64                               11.5.0-11.0.2.el9                                      ol9_baseos_latest                               757 k
 perl-Errno                                                 x86_64                               1.30-481.1.el9_6                                       ol9_appstream                                    13 k
 perl-interpreter                                           x86_64                               4:5.32.1-481.1.el9_6                                   ol9_appstream                                    76 k
 perl-libs                                                  x86_64                               4:5.32.1-481.1.el9_6                                   ol9_appstream                                   2.7 M
Installing dependencies:
 annobin                                                    x86_64                               12.92-1.el9                                            ol9_appstream                                   1.1 M
 dwz                                                        x86_64                               0.16-1.el9                                             ol9_appstream                                   139 k
 efi-srpm-macros                                            noarch                               6-4.0.1.el9                                            ol9_appstream                                    26 k
 fonts-srpm-macros                                          noarch                               1:2.0.5-7.el9.1                                        ol9_appstream                                    32 k
 gcc-c++                                                    x86_64                               11.5.0-11.0.2.el9                                      ol9_appstream                                    13 M
 gcc-plugin-annobin                                         x86_64                               11.5.0-11.0.2.el9                                      ol9_appstream                                    38 k
 ghc-srpm-macros                                            noarch                               1.5.0-6.el9                                            ol9_appstream                                   8.7 k
 go-srpm-macros                                             noarch                               3.6.0-14.el9_7                                         ol9_appstream                                    31 k
 kernel-srpm-macros                                         noarch                               1.0-14.0.1.el9                                         ol9_appstream                                    20 k
 libstdc++-devel                                            x86_64                               11.5.0-11.0.2.el9                                      ol9_appstream                                   3.1 M
 lua-srpm-macros                                            noarch                               1-6.el9                                                ol9_appstream                                   9.4 k
 ocaml-srpm-macros                                          noarch                               6-6.el9                                                ol9_appstream                                   8.7 k
 openblas-srpm-macros                                       noarch                               2-11.el9                                               ol9_appstream                                   8.3 k
 perl-Algorithm-Diff                                        noarch                               1.2010-4.el9                                           ol9_appstream                                    58 k
 perl-Archive-Tar                                           noarch                               2.38-6.el9                                             ol9_appstream                                    85 k
 perl-Archive-Zip                                           noarch                               1.68-6.el9                                             ol9_appstream                                   144 k
 perl-Attribute-Handlers                                    noarch                               1.01-481.1.el9_6                                       ol9_appstream                                    26 k
 perl-AutoSplit                                             noarch                               5.74-481.1.el9_6                                       ol9_appstream                                    20 k
 perl-Benchmark                                             noarch                               1.23-481.1.el9_6                                       ol9_appstream                                    25 k
 perl-CPAN                                                  noarch                               2.29-5.el9_6                                           ol9_appstream                                   630 k
 perl-CPAN-Meta                                             noarch                               2.150010-460.el9                                       ol9_appstream                                   292 k
 perl-CPAN-Meta-Requirements                                noarch                               2.140-461.el9                                          ol9_appstream                                    38 k
 perl-CPAN-Meta-YAML                                        noarch                               0.018-461.el9                                          ol9_appstream                                    31 k
 perl-Compress-Bzip2                                        x86_64                               2.28-5.el9                                             ol9_appstream                                    78 k
 perl-Compress-Raw-Bzip2                                    x86_64                               2.101-5.el9                                            ol9_appstream                                    40 k
 perl-Compress-Raw-Lzma                                     x86_64                               2.101-3.el9                                            ol9_appstream                                    57 k
 perl-Compress-Raw-Zlib                                     x86_64                               2.101-5.el9                                            ol9_appstream                                    66 k
 perl-Config-Extensions                                     noarch                               0.03-481.1.el9_6                                       ol9_appstream                                    11 k
 perl-Config-Perl-V                                         noarch                               0.33-4.el9                                             ol9_appstream                                    28 k
 perl-DBM_Filter                                            noarch                               0.06-481.1.el9_6                                       ol9_appstream                                    43 k
 perl-DB_File                                               x86_64                               1.855-4.el9                                            ol9_appstream                                    87 k
 perl-Data-OptList                                          noarch                               0.110-17.el9                                           ol9_appstream                                    36 k
 perl-Data-Section                                          noarch                               0.200007-14.el9                                        ol9_appstream                                    30 k
 perl-Devel-PPPort                                          x86_64                               3.62-4.el9                                             ol9_appstream                                   220 k
 perl-Devel-Peek                                            x86_64                               1.28-481.1.el9_6                                       ol9_appstream                                    30 k
 perl-Devel-SelfStubber                                     noarch                               1.06-481.1.el9_6                                       ol9_appstream                                    13 k
 perl-Devel-Size                                            x86_64                               0.83-10.el9                                            ol9_appstream                                    32 k
 perl-Digest-SHA                                            x86_64                               1:6.02-461.el9                                         ol9_appstream                                    70 k
 perl-Digest-SHA1                                           x86_64                               2.13-34.el9                                            ol9_appstream                                    60 k
 perl-DirHandle                                             noarch                               1.05-481.1.el9_6                                       ol9_appstream                                    11 k
 perl-Dumpvalue                                             noarch                               2.27-481.1.el9_6                                       ol9_appstream                                    17 k
 perl-Encode-devel                                          x86_64                               4:3.08-462.el9                                         ol9_appstream                                    51 k
 perl-English                                               noarch                               1.11-481.1.el9_6                                       ol9_appstream                                    12 k
 perl-Env                                                   noarch                               1.04-460.el9                                           ol9_appstream                                    25 k
 perl-ExtUtils-CBuilder                                     noarch                               1:0.280236-4.el9                                       ol9_appstream                                    69 k
 perl-ExtUtils-Command                                      noarch                               2:7.60-3.el9                                           ol9_appstream                                    15 k
 perl-ExtUtils-Constant                                     noarch                               0.25-481.1.el9_6                                       ol9_appstream                                    55 k
 perl-ExtUtils-Embed                                        noarch                               1.35-481.1.el9_6                                       ol9_appstream                                    16 k
 perl-ExtUtils-Install                                      noarch                               2.20-4.el9                                             ol9_appstream                                    53 k
 perl-ExtUtils-MM-Utils                                     noarch                               2:7.60-3.el9                                           ol9_appstream                                    13 k
 perl-ExtUtils-Manifest                                     noarch                               1:1.73-4.el9                                           ol9_appstream                                    40 k
 perl-ExtUtils-Miniperl                                     noarch                               1.09-481.1.el9_6                                       ol9_appstream                                    14 k
 perl-ExtUtils-ParseXS                                      noarch                               1:3.40-460.el9                                         ol9_appstream                                   212 k
 perl-File-Compare                                          noarch                               1.100.600-481.1.el9_6                                  ol9_appstream                                    12 k
 perl-File-Copy                                             noarch                               2.34-481.1.el9_6                                       ol9_appstream                                    19 k
 perl-File-DosGlob                                          x86_64                               1.12-481.1.el9_6                                       ol9_appstream                                    18 k
 perl-File-Fetch                                            noarch                               1.00-4.el9                                             ol9_appstream                                    31 k
 perl-File-HomeDir                                          noarch                               1.006-4.el9                                            ol9_appstream                                    81 k
 perl-File-Which                                            noarch                               1.23-10.el9                                            ol9_appstream                                    22 k
 perl-FileCache                                             noarch                               1.10-481.1.el9_6                                       ol9_appstream                                    13 k
 perl-Filter                                                x86_64                               2:1.60-4.el9                                           ol9_appstream                                   121 k
 perl-Filter-Simple                                         noarch                               0.96-460.el9                                           ol9_appstream                                    28 k
 perl-FindBin                                               noarch                               1.51-481.1.el9_6                                       ol9_appstream                                    12 k
 perl-GDBM_File                                             x86_64                               1.18-481.1.el9_6                                       ol9_appstream                                    21 k
 perl-Hash-Util                                             x86_64                               0.23-481.1.el9_6                                       ol9_appstream                                    33 k
 perl-Hash-Util-FieldHash                                   x86_64                               1.20-481.1.el9_6                                       ol9_appstream                                    36 k
 perl-I18N-Collate                                          noarch                               1.02-481.1.el9_6                                       ol9_appstream                                    13 k
 perl-I18N-LangTags                                         noarch                               0.44-481.1.el9_6                                       ol9_appstream                                    59 k
 perl-I18N-Langinfo                                         x86_64                               0.19-481.1.el9_6                                       ol9_appstream                                    21 k
 perl-IO-Compress                                           noarch                               2.102-4.el9                                            ol9_appstream                                   321 k
 perl-IO-Compress-Lzma                                      noarch                               2.101-4.el9                                            ol9_appstream                                   101 k
 perl-IO-Zlib                                               noarch                               1:1.11-4.el9                                           ol9_appstream                                    20 k
 perl-IPC-Cmd                                               noarch                               2:1.04-461.el9                                         ol9_appstream                                    40 k
 perl-IPC-SysV                                              x86_64                               2.09-4.el9                                             ol9_appstream                                    55 k
 perl-IPC-System-Simple                                     noarch                               1.30-6.el9                                             ol9_appstream                                    46 k
 perl-Importer                                              noarch                               0.026-4.el9                                            ol9_appstream                                    45 k
 perl-JSON-PP                                               noarch                               1:4.06-4.el9                                           ol9_appstream                                    74 k
 perl-Locale-Maketext                                       noarch                               1.29-461.el9                                           ol9_appstream                                   108 k
 perl-Locale-Maketext-Simple                                noarch                               1:0.21-481.1.el9_6                                     ol9_appstream                                    16 k
 perl-MIME-Charset                                          noarch                               1.012.2-15.el9                                         ol9_appstream                                    60 k
 perl-MRO-Compat                                            noarch                               0.13-15.el9                                            ol9_appstream                                    27 k
 perl-Math-BigInt-FastCalc                                  x86_64                               0.500.900-460.el9                                      ol9_appstream                                    35 k
 perl-Math-BigRat                                           noarch                               0.2614-460.el9                                         ol9_appstream                                    46 k
 perl-Memoize                                               noarch                               1.03-481.1.el9_6                                       ol9_appstream                                    72 k
 perl-Module-Build                                          noarch                               2:0.42.31-9.el9                                        ol9_appstream                                   305 k
 perl-Module-CoreList                                       noarch                               1:5.20240609-1.el9                                     ol9_appstream                                    95 k
 perl-Module-CoreList-tools                                 noarch                               1:5.20240609-1.el9                                     ol9_appstream                                    16 k
 perl-Module-Load                                           noarch                               1:0.36-4.el9                                           ol9_appstream                                    18 k
 perl-Module-Load-Conditional                               noarch                               0.74-4.el9                                             ol9_appstream                                    23 k
 perl-Module-Loaded                                         noarch                               1:0.08-481.1.el9_6                                     ol9_appstream                                    12 k
 perl-Module-Metadata                                       noarch                               1.000037-460.el9                                       ol9_appstream                                    42 k
 perl-Module-Signature                                      noarch                               0.88-1.el9                                             ol9_appstream                                    95 k
 perl-NEXT                                                  noarch                               0.67-481.1.el9_6                                       ol9_appstream                                    19 k
 perl-Net                                                   noarch                               1.02-481.1.el9_6                                       ol9_appstream                                    33 k
 perl-Net-Ping                                              noarch                               2.74-5.el9                                             ol9_appstream                                    55 k
 perl-ODBM_File                                             x86_64                               1.16-481.1.el9_6                                       ol9_appstream                                    21 k
 perl-Object-HashBase                                       noarch                               0.009-7.el9                                            ol9_appstream                                    31 k
 perl-Opcode                                                x86_64                               1.48-481.1.el9_6                                       ol9_appstream                                    40 k
 perl-Package-Generator                                     noarch                               1.106-23.el9                                           ol9_appstream                                    31 k
 perl-Params-Check                                          noarch                               1:0.38-461.el9                                         ol9_appstream                                    23 k
 perl-Params-Util                                           x86_64                               1.102-5.el9                                            ol9_appstream                                    41 k
 perl-Perl-OSType                                           noarch                               1.010-461.el9                                          ol9_appstream                                    29 k
 perl-PerlIO-via-QuotedPrint                                noarch                               0.09-4.el9                                             ol9_appstream                                    29 k
 perl-Pod-Checker                                           noarch                               4:1.74-4.el9                                           ol9_appstream                                    38 k
 perl-Pod-Functions                                         noarch                               1.13-481.1.el9_6                                       ol9_appstream                                    12 k
 perl-Pod-Html                                              noarch                               1.25-481.1.el9_6                                       ol9_appstream                                    31 k
 perl-Safe                                                  noarch                               2.41-481.1.el9_6                                       ol9_appstream                                    23 k
 perl-Search-Dict                                           noarch                               1.07-481.1.el9_6                                       ol9_appstream                                    11 k
 perl-SelfLoader                                            noarch                               1.26-481.1.el9_6                                       ol9_appstream                                    20 k
 perl-Software-License                                      noarch                               0.103014-12.el9                                        ol9_appstream                                   196 k
 perl-Sub-Exporter                                          noarch                               0.987-27.el9                                           ol9_appstream                                   103 k
 perl-Sub-Install                                           noarch                               0.928-28.el9                                           ol9_appstream                                    28 k
 perl-Sys-Hostname                                          x86_64                               1.23-481.1.el9_6                                       ol9_appstream                                    15 k
 perl-Sys-Syslog                                            x86_64                               0.36-461.el9                                           ol9_appstream                                    54 k
 perl-Term-Complete                                         noarch                               1.403-481.1.el9_6                                      ol9_appstream                                    11 k
 perl-Term-ReadLine                                         noarch                               1.17-481.1.el9_6                                       ol9_appstream                                    17 k
 perl-Term-Size-Perl                                        x86_64                               0.031-12.el9                                           ol9_appstream                                    28 k
 perl-Term-Table                                            noarch                               0.015-8.el9                                            ol9_appstream                                    50 k
 perl-Test                                                  noarch                               1.31-481.1.el9_6                                       ol9_appstream                                    27 k
 perl-Test-Harness                                          noarch                               1:3.42-461.el9                                         ol9_appstream                                   387 k
 perl-Test-Simple                                           noarch                               3:1.302183-4.el9                                       ol9_appstream                                   949 k
 perl-Text-Abbrev                                           noarch                               1.02-481.1.el9_6                                       ol9_appstream                                    11 k
 perl-Text-Balanced                                         noarch                               2.04-4.el9                                             ol9_appstream                                    53 k
 perl-Text-Diff                                             noarch                               1.45-13.el9                                            ol9_appstream                                    50 k
 perl-Text-Glob                                             noarch                               0.11-15.el9                                            ol9_appstream                                    14 k
 perl-Text-Template                                         noarch                               1.59-5.el9                                             ol9_appstream                                    66 k
 perl-Thread                                                noarch                               3.05-481.1.el9_6                                       ol9_appstream                                    16 k
 perl-Thread-Queue                                          noarch                               3.14-460.el9                                           ol9_appstream                                    28 k
 perl-Thread-Semaphore                                      noarch                               2.13-481.1.el9_6                                       ol9_appstream                                    14 k
 perl-Tie                                                   noarch                               4.6-481.1.el9_6                                        ol9_appstream                                    41 k
 perl-Tie-File                                              noarch                               1.06-481.1.el9_6                                       ol9_appstream                                    42 k
 perl-Tie-Memoize                                           noarch                               1.1-481.1.el9_6                                        ol9_appstream                                    13 k
 perl-Tie-RefHash                                           noarch                               1.40-4.el9                                             ol9_appstream                                    29 k
 perl-Time                                                  noarch                               1.03-481.1.el9_6                                       ol9_appstream                                    24 k
 perl-Time-HiRes                                            x86_64                               4:1.9764-462.el9                                       ol9_appstream                                    64 k
 perl-Time-Piece                                            x86_64                               1.3401-481.1.el9_6                                     ol9_appstream                                    45 k
 perl-Unicode-Collate                                       x86_64                               1.29-4.el9                                             ol9_appstream                                   849 k
 perl-Unicode-Normalize                                     x86_64                               1.27-461.el9                                           ol9_appstream                                    96 k
 perl-Unicode-UCD                                           noarch                               0.75-481.1.el9_6                                       ol9_appstream                                    77 k
 perl-User-pwent                                            noarch                               1.03-481.1.el9_6                                       ol9_appstream                                    24 k
 perl-autodie                                               noarch                               2.34-4.el9                                             ol9_appstream                                   117 k
 perl-autouse                                               noarch                               1.11-481.1.el9_6                                       ol9_appstream                                    12 k
 perl-bignum                                                noarch                               0.51-460.el9                                           ol9_appstream                                    56 k
 perl-blib                                                  noarch                               1.07-481.1.el9_6                                       ol9_appstream                                    11 k
 perl-debugger                                              noarch                               1.56-481.1.el9_6                                       ol9_appstream                                   139 k
 perl-deprecate                                             noarch                               0.04-481.1.el9_6                                       ol9_appstream                                    13 k
 perl-devel                                                 x86_64                               4:5.32.1-481.1.el9_6                                   ol9_appstream                                   748 k
 perl-diagnostics                                           noarch                               1.37-481.1.el9_6                                       ol9_appstream                                   216 k
 perl-doc                                                   noarch                               5.32.1-481.1.el9_6                                     ol9_appstream                                   4.9 M
 perl-encoding                                              x86_64                               4:3.00-462.el9                                         ol9_appstream                                    68 k
 perl-encoding-warnings                                     noarch                               0.13-481.1.el9_6                                       ol9_appstream                                    15 k
 perl-experimental                                          noarch                               0.022-6.el9                                            ol9_appstream                                    27 k
 perl-fields                                                noarch                               2.27-481.1.el9_6                                       ol9_appstream                                    15 k
 perl-filetest                                              noarch                               1.03-481.1.el9_6                                       ol9_appstream                                    13 k
 perl-inc-latest                                            noarch                               2:0.500-20.el9                                         ol9_appstream                                    31 k
 perl-less                                                  noarch                               0.03-481.1.el9_6                                       ol9_appstream                                    12 k
 perl-lib                                                   x86_64                               0.65-481.1.el9_6                                       ol9_appstream                                    13 k
 perl-libnetcfg                                             noarch                               4:5.32.1-481.1.el9_6                                   ol9_appstream                                    15 k
 perl-local-lib                                             noarch                               2.000024-13.el9                                        ol9_appstream                                    76 k
 perl-macros                                                noarch                               4:5.32.1-481.1.el9_6                                   ol9_appstream                                   9.2 k
 perl-meta-notation                                         noarch                               5.32.1-481.1.el9_6                                     ol9_appstream                                   8.2 k
 perl-open                                                  noarch                               1.12-481.1.el9_6                                       ol9_appstream                                    15 k
 perl-perlfaq                                               noarch                               5.20210520-1.el9                                       ol9_appstream                                   399 k
 perl-ph                                                    x86_64                               5.32.1-481.1.el9_6                                     ol9_appstream                                    67 k
 perl-sigtrap                                               noarch                               1.09-481.1.el9_6                                       ol9_appstream                                    14 k
 perl-sort                                                  noarch                               2.04-481.1.el9_6                                       ol9_appstream                                    12 k
 perl-srpm-macros                                           noarch                               1-41.el9                                               ol9_appstream                                   9.1 k
 perl-threads                                               x86_64                               1:2.25-460.el9                                         ol9_appstream                                    65 k
 perl-threads-shared                                        x86_64                               1.61-460.el9                                           ol9_appstream                                    50 k
 perl-utils                                                 noarch                               5.32.1-481.1.el9_6                                     ol9_appstream                                    64 k
 perl-version                                               x86_64                               7:0.99.28-4.el9                                        ol9_appstream                                    74 k
 perl-vmsish                                                noarch                               1.04-481.1.el9_6                                       ol9_appstream                                    13 k
 pyproject-srpm-macros                                      noarch                               1.16.2-1.el9                                           ol9_appstream                                    13 k
 python-srpm-macros                                         noarch                               3.9-54.el9                                             ol9_appstream                                    16 k
 qt5-srpm-macros                                            noarch                               5.15.9-1.el9                                           ol9_appstream                                   7.7 k
 redhat-rpm-config                                          noarch                               210-1.0.1.el9                                          ol9_appstream                                   101 k
 rust-srpm-macros                                           noarch                               17-4.el9                                               ol9_appstream                                    10 k
 sombok                                                     x86_64                               2.4.0-16.el9                                           ol9_appstream                                    55 k
 systemtap-sdt-devel                                        x86_64                               5.3-3.0.1.el9                                          ol9_appstream                                    76 k
 systemtap-sdt-dtrace                                       x86_64                               5.3-3.0.1.el9                                          ol9_appstream                                    75 k
Installing weak dependencies:
 perl-CPAN-DistnameInfo                                     noarch                               0.12-23.el9                                            ol9_appstream                                    15 k
 perl-Encode-Locale                                         noarch                               1.05-21.el9                                            ol9_appstream                                    20 k
 perl-Term-Size-Any                                         noarch                               0.002-35.el9                                           ol9_appstream                                    19 k
 perl-TermReadKey                                           x86_64                               2.38-11.el9                                            ol9_appstream                                    42 k
 perl-Unicode-LineBreak                                     x86_64                               2019.001-11.el9                                        ol9_appstream                                   144 k

Transaction Summary
==============================================================================================================================================================================================================
Install  187 Packages
Upgrade    4 Packages

Total download size: 38 M
Downloading Packages:
(1/191): annobin-12.92-1.el9.x86_64.rpm                                                      2.9 MB/s | 1.1 MB     00:00
(2/191): fonts-srpm-macros-2.0.5-7.el9.1.noarch.rpm                                          849 kB/s |  32 kB     00:00
(3/191): efi-srpm-macros-6-4.0.1.el9.noarch.rpm                                               21 kB/s |  26 kB     00:01
(4/191): gcc-plugin-annobin-11.5.0-11.0.2.el9.x86_64.rpm                                     535 kB/s |  38 kB     00:00
(5/191): ghc-srpm-macros-1.5.0-6.el9.noarch.rpm                                              149 kB/s | 8.7 kB     00:00
(6/191): go-srpm-macros-3.6.0-14.el9_7.noarch.rpm                                            332 kB/s |  31 kB     00:00
(7/191): gcc-c++-11.5.0-11.0.2.el9.x86_64.rpm                                                9.7 MB/s |  13 MB     00:01
(8/191): libstdc++-devel-11.5.0-11.0.2.el9.x86_64.rpm                                        9.0 MB/s | 3.1 MB     00:00
(9/191): lua-srpm-macros-1-6.el9.noarch.rpm                                                  268 kB/s | 9.4 kB     00:00
(10/191): kernel-srpm-macros-1.0-14.0.1.el9.noarch.rpm                                        10 kB/s |  20 kB     00:01
(11/191): ocaml-srpm-macros-6-6.el9.noarch.rpm                                               4.7 kB/s | 8.7 kB     00:01
(12/191): perl-5.32.1-481.1.el9_6.x86_64.rpm                                                 316 kB/s |  11 kB     00:00
(13/191): perl-Algorithm-Diff-1.2010-4.el9.noarch.rpm                                                                                                                         229 kB/s |  58 kB     00:00
(14/191): perl-Archive-Tar-2.38-6.el9.noarch.rpm                                                                                                                              878 kB/s |  85 kB     00:00
(15/191): perl-Archive-Zip-1.68-6.el9.noarch.rpm                                                                                                                              2.3 MB/s | 144 kB     00:00
(16/191): perl-Attribute-Handlers-1.01-481.1.el9_6.noarch.rpm                                                                                                                 277 kB/s |  26 kB     00:00
(17/191): perl-AutoSplit-5.74-481.1.el9_6.noarch.rpm                                                                                                                          219 kB/s |  20 kB     00:00
(18/191): openblas-srpm-macros-2-11.el9.noarch.rpm                                                                                                                            4.4 kB/s | 8.3 kB     00:01
(19/191): perl-CPAN-2.29-5.el9_6.noarch.rpm                                                                                                                                   3.2 MB/s | 630 kB     00:00
(20/191): perl-Benchmark-1.23-481.1.el9_6.noarch.rpm                                                                                                                           13 kB/s |  25 kB     00:01
(21/191): dwz-0.16-1.el9.x86_64.rpm                                                                                                                                            21 kB/s | 139 kB     00:06
(22/191): perl-CPAN-Meta-Requirements-2.140-461.el9.noarch.rpm                                                                                                                370 kB/s |  38 kB     00:00
(23/191): perl-CPAN-Meta-YAML-0.018-461.el9.noarch.rpm                                                                                                                        326 kB/s |  31 kB     00:00
(24/191): perl-CPAN-Meta-2.150010-460.el9.noarch.rpm                                                                                                                          1.1 MB/s | 292 kB     00:00
(25/191): perl-Compress-Raw-Bzip2-2.101-5.el9.x86_64.rpm                                                                                                                      448 kB/s |  40 kB     00:00
(26/191): perl-Compress-Bzip2-2.28-5.el9.x86_64.rpm                                                                                                                           512 kB/s |  78 kB     00:00
(27/191): perl-Compress-Raw-Lzma-2.101-3.el9.x86_64.rpm                                                                                                                       1.2 MB/s |  57 kB     00:00
(28/191): perl-Config-Extensions-0.03-481.1.el9_6.noarch.rpm                                                                                                                  303 kB/s |  11 kB     00:00
(29/191): perl-Compress-Raw-Zlib-2.101-5.el9.x86_64.rpm                                                                                                                       604 kB/s |  66 kB     00:00
(30/191): perl-Config-Perl-V-0.33-4.el9.noarch.rpm                                                                                                                            275 kB/s |  28 kB     00:00
(31/191): perl-DB_File-1.855-4.el9.x86_64.rpm                                                                                                                                 1.5 MB/s |  87 kB     00:00
(32/191): perl-DBM_Filter-0.06-481.1.el9_6.noarch.rpm                                                                                                                         374 kB/s |  43 kB     00:00
(33/191): perl-Data-Section-0.200007-14.el9.noarch.rpm                                                                                                                        714 kB/s |  30 kB     00:00
(34/191): perl-Devel-PPPort-3.62-4.el9.x86_64.rpm                                                                                                                             3.1 MB/s | 220 kB     00:00
(35/191): perl-CPAN-DistnameInfo-0.12-23.el9.noarch.rpm                                                                                                                       8.0 kB/s |  15 kB     00:01
(36/191): perl-Devel-SelfStubber-1.06-481.1.el9_6.noarch.rpm                                                                                                                  336 kB/s |  13 kB     00:00
(37/191): perl-Devel-Size-0.83-10.el9.x86_64.rpm                                                                                                                              814 kB/s |  32 kB     00:00
(38/191): perl-Devel-Peek-1.28-481.1.el9_6.x86_64.rpm                                                                                                                         349 kB/s |  30 kB     00:00
(39/191): perl-Digest-SHA1-2.13-34.el9.x86_64.rpm                                                                                                                             1.3 MB/s |  60 kB     00:00
(40/191): perl-Digest-SHA-6.02-461.el9.x86_64.rpm                                                                                                                             852 kB/s |  70 kB     00:00
(41/191): perl-DirHandle-1.05-481.1.el9_6.noarch.rpm                                                                                                                          269 kB/s |  11 kB     00:00
(42/191): perl-Dumpvalue-2.27-481.1.el9_6.noarch.rpm                                                                                                                          446 kB/s |  17 kB     00:00
(43/191): perl-Encode-Locale-1.05-21.el9.noarch.rpm                                                                                                                           500 kB/s |  20 kB     00:00
(44/191): perl-English-1.11-481.1.el9_6.noarch.rpm                                                                                                                            422 kB/s |  12 kB     00:00
(45/191): perl-Encode-devel-3.08-462.el9.x86_64.rpm                                                                                                                           783 kB/s |  51 kB     00:00
(46/191): perl-Env-1.04-460.el9.noarch.rpm                                                                                                                                    606 kB/s |  25 kB     00:00
(47/191): perl-ExtUtils-CBuilder-0.280236-4.el9.noarch.rpm                                                                                                                    1.5 MB/s |  69 kB     00:00
(48/191): perl-ExtUtils-Command-7.60-3.el9.noarch.rpm                                                                                                                         374 kB/s |  15 kB     00:00
(49/191): perl-ExtUtils-Constant-0.25-481.1.el9_6.noarch.rpm                                                                                                                  1.2 MB/s |  55 kB     00:00
(50/191): perl-ExtUtils-Embed-1.35-481.1.el9_6.noarch.rpm                                                                                                                     433 kB/s |  16 kB     00:00
(51/191): perl-ExtUtils-Install-2.20-4.el9.noarch.rpm                                                                                                                         1.1 MB/s |  53 kB     00:00
(52/191): perl-ExtUtils-MakeMaker-7.60-3.el9.noarch.rpm                                                                                                                       1.7 MB/s | 352 kB     00:00
(53/191): perl-ExtUtils-Manifest-1.73-4.el9.noarch.rpm                                                                                                                        1.0 MB/s |  40 kB     00:00
(54/191): perl-ExtUtils-Miniperl-1.09-481.1.el9_6.noarch.rpm                                                                                                                  373 kB/s |  14 kB     00:00
(55/191): perl-ExtUtils-ParseXS-3.40-460.el9.noarch.rpm                                                                                                                       572 kB/s | 212 kB     00:00
(56/191): perl-File-Compare-1.100.600-481.1.el9_6.noarch.rpm                                                                                                                  139 kB/s |  12 kB     00:00
(57/191): perl-File-Copy-2.34-481.1.el9_6.noarch.rpm                                                                                                                          395 kB/s |  19 kB     00:00
(58/191): perl-File-DosGlob-1.12-481.1.el9_6.x86_64.rpm                                                                                                                       151 kB/s |  18 kB     00:00
(59/191): perl-File-Fetch-1.00-4.el9.noarch.rpm                                                                                                                               730 kB/s |  31 kB     00:00
(60/191): perl-File-HomeDir-1.006-4.el9.noarch.rpm                                                                                                                            1.8 MB/s |  81 kB     00:00
(61/191): perl-Data-OptList-0.110-17.el9.noarch.rpm                                                                                                                            19 kB/s |  36 kB     00:01
(62/191): perl-FileCache-1.10-481.1.el9_6.noarch.rpm                                                                                                                          365 kB/s |  13 kB     00:00
(63/191): perl-Filter-1.60-4.el9.x86_64.rpm                                                                                                                                   2.4 MB/s | 121 kB     00:00
(64/191): perl-Filter-Simple-0.96-460.el9.noarch.rpm                                                                                                                          200 kB/s |  28 kB     00:00
(65/191): perl-FindBin-1.51-481.1.el9_6.noarch.rpm                                                                                                                            111 kB/s |  12 kB     00:00
(66/191): perl-GDBM_File-1.18-481.1.el9_6.x86_64.rpm                                                                                                                          164 kB/s |  21 kB     00:00
(67/191): perl-ExtUtils-MM-Utils-7.60-3.el9.noarch.rpm                                                                                                                        6.9 kB/s |  13 kB     00:01
(68/191): perl-Hash-Util-0.23-481.1.el9_6.x86_64.rpm                                                                                                                          344 kB/s |  33 kB     00:00
(69/191): perl-I18N-Collate-1.02-481.1.el9_6.noarch.rpm                                                                                                                       287 kB/s |  13 kB     00:00
(70/191): perl-Hash-Util-FieldHash-1.20-481.1.el9_6.x86_64.rpm                                                                                                                275 kB/s |  36 kB     00:00
(71/191): perl-I18N-LangTags-0.44-481.1.el9_6.noarch.rpm                                                                                                                      1.3 MB/s |  59 kB     00:00
(72/191): perl-I18N-Langinfo-0.19-481.1.el9_6.x86_64.rpm                                                                                                                      475 kB/s |  21 kB     00:00
(73/191): perl-IO-Compress-Lzma-2.101-4.el9.noarch.rpm                                                                                                                        2.0 MB/s | 101 kB     00:00
(74/191): perl-IO-Zlib-1.11-4.el9.noarch.rpm                                                                                                                                  487 kB/s |  20 kB     00:00
(75/191): perl-IPC-Cmd-1.04-461.el9.noarch.rpm                                                                                                                                895 kB/s |  40 kB     00:00
(76/191): perl-IO-Compress-2.102-4.el9.noarch.rpm                                                                                                                             2.1 MB/s | 321 kB     00:00
(77/191): perl-IPC-SysV-2.09-4.el9.x86_64.rpm                                                                                                                                 625 kB/s |  55 kB     00:00
(78/191): perl-IPC-System-Simple-1.30-6.el9.noarch.rpm                                                                                                                        431 kB/s |  46 kB     00:00
(79/191): perl-Importer-0.026-4.el9.noarch.rpm                                                                                                                                475 kB/s |  45 kB     00:00
(80/191): perl-JSON-PP-4.06-4.el9.noarch.rpm                                                                                                                                  862 kB/s |  74 kB     00:00
(81/191): perl-Locale-Maketext-1.29-461.el9.noarch.rpm                                                                                                                        2.3 MB/s | 108 kB     00:00
(82/191): perl-Locale-Maketext-Simple-0.21-481.1.el9_6.noarch.rpm                                                                                                             237 kB/s |  16 kB     00:00
(83/191): perl-MRO-Compat-0.13-15.el9.noarch.rpm                                                                                                                              701 kB/s |  27 kB     00:00
(84/191): perl-MIME-Charset-1.012.2-15.el9.noarch.rpm                                                                                                                         679 kB/s |  60 kB     00:00
(85/191): perl-Math-BigRat-0.2614-460.el9.noarch.rpm                                                                                                                          743 kB/s |  46 kB     00:00
(86/191): perl-Math-BigInt-FastCalc-0.500.900-460.el9.x86_64.rpm                                                                                                              418 kB/s |  35 kB     00:00
(87/191): perl-Memoize-1.03-481.1.el9_6.noarch.rpm                                                                                                                            2.0 MB/s |  72 kB     00:00
(88/191): perl-Module-CoreList-5.20240609-1.el9.noarch.rpm                                                                                                                    802 kB/s |  95 kB     00:00
(89/191): perl-Module-Build-0.42.31-9.el9.noarch.rpm                                                                                                                          1.8 MB/s | 305 kB     00:00
(90/191): perl-Module-Load-0.36-4.el9.noarch.rpm                                                                                                                              495 kB/s |  18 kB     00:00
(91/191): perl-Module-CoreList-tools-5.20240609-1.el9.noarch.rpm                                                                                                              182 kB/s |  16 kB     00:00
(92/191): perl-Module-Loaded-0.08-481.1.el9_6.noarch.rpm                                                                                                                      305 kB/s |  12 kB     00:00
(93/191): perl-Module-Load-Conditional-0.74-4.el9.noarch.rpm                                                                                                                  229 kB/s |  23 kB     00:00
(94/191): perl-Module-Metadata-1.000037-460.el9.noarch.rpm                                                                                                                    461 kB/s |  42 kB     00:00
(95/191): perl-File-Which-1.23-10.el9.noarch.rpm                                                                                                                               12 kB/s |  22 kB     00:01
(96/191): perl-NEXT-0.67-481.1.el9_6.noarch.rpm                                                                                                                               473 kB/s |  19 kB     00:00
(97/191): perl-Net-1.02-481.1.el9_6.noarch.rpm                                                                                                                                796 kB/s |  33 kB     00:00
(98/191): perl-Module-Signature-0.88-1.el9.noarch.rpm                                                                                                                         706 kB/s |  95 kB     00:00
(99/191): perl-Object-HashBase-0.009-7.el9.noarch.rpm                                                                                                                         787 kB/s |  31 kB     00:00
(100/191): perl-Net-Ping-2.74-5.el9.noarch.rpm                                                                                                                                439 kB/s |  55 kB     00:00
(101/191): perl-ODBM_File-1.16-481.1.el9_6.x86_64.rpm                                                                                                                         175 kB/s |  21 kB     00:00
(102/191): perl-Params-Check-0.38-461.el9.noarch.rpm                                                                                                                          535 kB/s |  23 kB     00:00
(103/191): perl-Opcode-1.48-481.1.el9_6.x86_64.rpm                                                                                                                            353 kB/s |  40 kB     00:00
(104/191): perl-Package-Generator-1.106-23.el9.noarch.rpm                                                                                                                     253 kB/s |  31 kB     00:00
(105/191): perl-Perl-OSType-1.010-461.el9.noarch.rpm                                                                                                                          376 kB/s |  29 kB     00:00
(106/191): perl-Pod-Checker-1.74-4.el9.noarch.rpm                                                                                                                             961 kB/s |  38 kB     00:00
(107/191): perl-PerlIO-via-QuotedPrint-0.09-4.el9.noarch.rpm                                                                                                                  332 kB/s |  29 kB     00:00
(108/191): perl-Pod-Html-1.25-481.1.el9_6.noarch.rpm                                                                                                                          633 kB/s |  31 kB     00:00
(109/191): perl-Pod-Functions-1.13-481.1.el9_6.noarch.rpm                                                                                                                     148 kB/s |  12 kB     00:00
(110/191): perl-Search-Dict-1.07-481.1.el9_6.noarch.rpm                                                                                                                       307 kB/s |  11 kB     00:00
(111/191): perl-Safe-2.41-481.1.el9_6.noarch.rpm                                                                                                                              493 kB/s |  23 kB     00:00
(112/191): perl-SelfLoader-1.26-481.1.el9_6.noarch.rpm                                                                                                                        368 kB/s |  20 kB     00:00
(113/191): perl-Software-License-0.103014-12.el9.noarch.rpm                                                                                                                   2.9 MB/s | 196 kB     00:00
(114/191): perl-Sub-Install-0.928-28.el9.noarch.rpm                                                                                                                           556 kB/s |  28 kB     00:00
(115/191): perl-Sys-Hostname-1.23-481.1.el9_6.x86_64.rpm                                                                                                                      499 kB/s |  15 kB     00:00
(116/191): perl-Sub-Exporter-0.987-27.el9.noarch.rpm                                                                                                                          975 kB/s | 103 kB     00:00
(117/191): perl-Term-Complete-1.403-481.1.el9_6.noarch.rpm                                                                                                                    308 kB/s |  11 kB     00:00
(118/191): perl-Sys-Syslog-0.36-461.el9.x86_64.rpm                                                                                                                            1.0 MB/s |  54 kB     00:00
(119/191): perl-Term-ReadLine-1.17-481.1.el9_6.noarch.rpm                                                                                                                     465 kB/s |  17 kB     00:00
(120/191): perl-Term-Size-Perl-0.031-12.el9.x86_64.rpm                                                                                                                        573 kB/s |  28 kB     00:00
(121/191): perl-Params-Util-1.102-5.el9.x86_64.rpm                                                                                                                             22 kB/s |  41 kB     00:01
(122/191): perl-Term-Size-Any-0.002-35.el9.noarch.rpm                                                                                                                         9.7 kB/s |  19 kB     00:01
(123/191): perl-Test-1.31-481.1.el9_6.noarch.rpm                                                                                                                              702 kB/s |  27 kB     00:00
(124/191): perl-Term-Table-0.015-8.el9.noarch.rpm                                                                                                                              26 kB/s |  50 kB     00:01
(125/191): perl-Test-Harness-3.42-461.el9.noarch.rpm                                                                                                                          4.7 MB/s | 387 kB     00:00
(126/191): perl-Text-Abbrev-1.02-481.1.el9_6.noarch.rpm                                                                                                                       223 kB/s |  11 kB     00:00
(127/191): perl-Text-Balanced-2.04-4.el9.noarch.rpm                                                                                                                           548 kB/s |  53 kB     00:00
(128/191): perl-Test-Simple-1.302183-4.el9.noarch.rpm                                                                                                                         3.6 MB/s | 949 kB     00:00
(129/191): perl-Text-Diff-1.45-13.el9.noarch.rpm                                                                                                                              919 kB/s |  50 kB     00:00
(130/191): perl-Text-Template-1.59-5.el9.noarch.rpm                                                                                                                           1.0 MB/s |  66 kB     00:00
(131/191): perl-Text-Glob-0.11-15.el9.noarch.rpm                                                                                                                              167 kB/s |  14 kB     00:00
(132/191): perl-Thread-3.05-481.1.el9_6.noarch.rpm                                                                                                                            185 kB/s |  16 kB     00:00
(133/191): perl-Thread-Semaphore-2.13-481.1.el9_6.noarch.rpm                                                                                                                  201 kB/s |  14 kB     00:00
(134/191): perl-Tie-4.6-481.1.el9_6.noarch.rpm                                                                                                                                414 kB/s |  41 kB     00:00
(135/191): perl-Tie-File-1.06-481.1.el9_6.noarch.rpm                                                                                                                          903 kB/s |  42 kB     00:00
(136/191): perl-Tie-Memoize-1.1-481.1.el9_6.noarch.rpm                                                                                                                        133 kB/s |  13 kB     00:00
(137/191): perl-Tie-RefHash-1.40-4.el9.noarch.rpm                                                                                                                             737 kB/s |  29 kB     00:00
(138/191): perl-Time-1.03-481.1.el9_6.noarch.rpm                                                                                                                              804 kB/s |  24 kB     00:00
(139/191): perl-Time-HiRes-1.9764-462.el9.x86_64.rpm                                                                                                                          1.9 MB/s |  64 kB     00:00
(140/191): perl-Time-Piece-1.3401-481.1.el9_6.x86_64.rpm                                                                                                                      796 kB/s |  45 kB     00:00
(141/191): perl-Unicode-Collate-1.29-4.el9.x86_64.rpm                                                                                                                         6.8 MB/s | 849 kB     00:00
(142/191): perl-Unicode-LineBreak-2019.001-11.el9.x86_64.rpm                                                                                                                  1.5 MB/s | 144 kB     00:00
(143/191): perl-Unicode-Normalize-1.27-461.el9.x86_64.rpm                                                                                                                     683 kB/s |  96 kB     00:00
(144/191): perl-TermReadKey-2.38-11.el9.x86_64.rpm                                                                                                                             22 kB/s |  42 kB     00:01
(145/191): perl-Unicode-UCD-0.75-481.1.el9_6.noarch.rpm                                                                                                                       1.2 MB/s |  77 kB     00:00
(146/191): perl-User-pwent-1.03-481.1.el9_6.noarch.rpm                                                                                                                        242 kB/s |  24 kB     00:00
(147/191): perl-autodie-2.34-4.el9.noarch.rpm                                                                                                                                 1.1 MB/s | 117 kB     00:00
(148/191): perl-bignum-0.51-460.el9.noarch.rpm                                                                                                                                1.1 MB/s |  56 kB     00:00
(149/191): perl-blib-1.07-481.1.el9_6.noarch.rpm                                                                                                                              262 kB/s |  11 kB     00:00
(150/191): perl-autouse-1.11-481.1.el9_6.noarch.rpm                                                                                                                            70 kB/s |  12 kB     00:00
(151/191): perl-deprecate-0.04-481.1.el9_6.noarch.rpm                                                                                                                         163 kB/s |  13 kB     00:00
(152/191): perl-devel-5.32.1-481.1.el9_6.x86_64.rpm                                                                                                                           6.2 MB/s | 748 kB     00:00
(153/191): perl-diagnostics-1.37-481.1.el9_6.noarch.rpm                                                                                                                       1.9 MB/s | 216 kB     00:00
(154/191): perl-Thread-Queue-3.14-460.el9.noarch.rpm                                                                                                                           14 kB/s |  28 kB     00:01
(155/191): perl-doc-5.32.1-481.1.el9_6.noarch.rpm                                                                                                                             9.1 MB/s | 4.9 MB     00:00
(156/191): perl-encoding-3.00-462.el9.x86_64.rpm                                                                                                                              349 kB/s |  68 kB     00:00
(157/191): perl-encoding-warnings-0.13-481.1.el9_6.noarch.rpm                                                                                                                 374 kB/s |  15 kB     00:00
(158/191): perl-experimental-0.022-6.el9.noarch.rpm                                                                                                                           667 kB/s |  27 kB     00:00
(159/191): perl-filetest-1.03-481.1.el9_6.noarch.rpm                                                                                                                          352 kB/s |  13 kB     00:00
(160/191): perl-inc-latest-0.500-20.el9.noarch.rpm                                                                                                                            768 kB/s |  31 kB     00:00
(161/191): perl-fields-2.27-481.1.el9_6.noarch.rpm                                                                                                                            162 kB/s |  15 kB     00:00
(162/191): perl-less-0.03-481.1.el9_6.noarch.rpm                                                                                                                              307 kB/s |  12 kB     00:00
(163/191): perl-lib-0.65-481.1.el9_6.x86_64.rpm                                                                                                                               208 kB/s |  13 kB     00:00
(164/191): perl-libnetcfg-5.32.1-481.1.el9_6.noarch.rpm                                                                                                                       403 kB/s |  15 kB     00:00
(165/191): perl-macros-5.32.1-481.1.el9_6.noarch.rpm                                                                                                                          261 kB/s | 9.2 kB     00:00
(166/191): perl-local-lib-2.000024-13.el9.noarch.rpm                                                                                                                          839 kB/s |  76 kB     00:00
(167/191): perl-meta-notation-5.32.1-481.1.el9_6.noarch.rpm                                                                                                                   102 kB/s | 8.2 kB     00:00
(168/191): perl-open-1.12-481.1.el9_6.noarch.rpm                                                                                                                              369 kB/s |  15 kB     00:00
(169/191): perl-ph-5.32.1-481.1.el9_6.x86_64.rpm                                                                                                                              745 kB/s |  67 kB     00:00
(170/191): perl-perlfaq-5.20210520-1.el9.noarch.rpm                                                                                                                           2.7 MB/s | 399 kB     00:00
(171/191): perl-sigtrap-1.09-481.1.el9_6.noarch.rpm                                                                                                                           299 kB/s |  14 kB     00:00
(172/191): perl-srpm-macros-1-41.el9.noarch.rpm                                                                                                                               110 kB/s | 9.1 kB     00:00
(173/191): perl-sort-2.04-481.1.el9_6.noarch.rpm                                                                                                                               98 kB/s |  12 kB     00:00
(174/191): perl-threads-2.25-460.el9.x86_64.rpm                                                                                                                               698 kB/s |  65 kB     00:00
(175/191): perl-threads-shared-1.61-460.el9.x86_64.rpm                                                                                                                        589 kB/s |  50 kB     00:00
(176/191): perl-utils-5.32.1-481.1.el9_6.noarch.rpm                                                                                                                           1.4 MB/s |  64 kB     00:00
(177/191): perl-version-0.99.28-4.el9.x86_64.rpm                                                                                                                              1.6 MB/s |  74 kB     00:00
(178/191): pyproject-srpm-macros-1.16.2-1.el9.noarch.rpm                                                                                                                      353 kB/s |  13 kB     00:00
(179/191): perl-vmsish-1.04-481.1.el9_6.noarch.rpm                                                                                                                            132 kB/s |  13 kB     00:00
(180/191): qt5-srpm-macros-5.15.9-1.el9.noarch.rpm                                                                                                                            208 kB/s | 7.7 kB     00:00
(181/191): redhat-rpm-config-210-1.0.1.el9.noarch.rpm                                                                                                                         2.0 MB/s | 101 kB     00:00
(182/191): perl-debugger-1.56-481.1.el9_6.noarch.rpm                                                                                                                           75 kB/s | 139 kB     00:01
(183/191): sombok-2.4.0-16.el9.x86_64.rpm                                                                                                                                     1.3 MB/s |  55 kB     00:00
(184/191): rust-srpm-macros-17-4.el9.noarch.rpm                                                                                                                               107 kB/s |  10 kB     00:00
(185/191): python-srpm-macros-3.9-54.el9.noarch.rpm                                                                                                                           8.2 kB/s |  16 kB     00:02
(186/191): libstdc++-11.5.0-11.0.2.el9.x86_64.rpm                                                                                                                             6.4 MB/s | 757 kB     00:00
(187/191): systemtap-sdt-devel-5.3-3.0.1.el9.x86_64.rpm                                                                                                                        39 kB/s |  76 kB     00:01
(188/191): perl-Errno-1.30-481.1.el9_6.x86_64.rpm                                                                                                                             366 kB/s |  13 kB     00:00
(189/191): perl-interpreter-5.32.1-481.1.el9_6.x86_64.rpm                                                                                                                     858 kB/s |  76 kB     00:00
(190/191): perl-libs-5.32.1-481.1.el9_6.x86_64.rpm                                                                                                                            8.5 MB/s | 2.7 MB     00:00
(191/191): systemtap-sdt-dtrace-5.3-3.0.1.el9.x86_64.rpm                                                                                                                       22 kB/s |  75 kB     00:03
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                         1.9 MB/s |  38 MB     00:20
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
  Preparing        :                                                                                                                                                                                      1/1
  Upgrading        : libstdc++-11.5.0-11.0.2.el9.x86_64                                                                                                                                                 1/195
  Installing       : perl-GDBM_File-1.18-481.1.el9_6.x86_64                                                                                                                                             2/195
  Installing       : perl-ODBM_File-1.16-481.1.el9_6.x86_64                                                                                                                                             3/195
  Upgrading        : perl-libs-4:5.32.1-481.1.el9_6.x86_64                                                                                                                                              4/195
  Installing       : perl-DB_File-1.855-4.el9.x86_64                                                                                                                                                    5/195
  Installing       : perl-version-7:0.99.28-4.el9.x86_64                                                                                                                                                6/195
  Installing       : perl-File-Copy-2.34-481.1.el9_6.noarch                                                                                                                                             7/195
  Installing       : perl-ExtUtils-Manifest-1:1.73-4.el9.noarch                                                                                                                                         8/195
  Installing       : perl-Time-HiRes-4:1.9764-462.el9.x86_64                                                                                                                                            9/195
  Installing       : perl-CPAN-Meta-Requirements-2.140-461.el9.noarch                                                                                                                                  10/195
  Installing       : perl-Compress-Raw-Zlib-2.101-5.el9.x86_64                                                                                                                                         11/195
  Installing       : perl-File-Compare-1.100.600-481.1.el9_6.noarch                                                                                                                                    12/195
  Installing       : perl-lib-0.65-481.1.el9_6.x86_64                                                                                                                                                  13/195
  Installing       : perl-threads-1:2.25-460.el9.x86_64                                                                                                                                                14/195
  Installing       : perl-threads-shared-1.61-460.el9.x86_64                                                                                                                                           15/195
  Installing       : perl-Module-CoreList-1:5.20240609-1.el9.noarch                                                                                                                                    16/195
  Installing       : perl-Module-Metadata-1.000037-460.el9.noarch                                                                                                                                      17/195
  Installing       : perl-Devel-Peek-1.28-481.1.el9_6.x86_64                                                                                                                                           18/195
  Installing       : perl-Filter-2:1.60-4.el9.x86_64                                                                                                                                                   19/195
  Installing       : perl-Module-Load-1:0.36-4.el9.noarch                                                                                                                                              20/195
  Installing       : perl-Perl-OSType-1.010-461.el9.noarch                                                                                                                                             21/195
  Installing       : perl-Term-ReadLine-1.17-481.1.el9_6.noarch                                                                                                                                        22/195
  Installing       : perl-Tie-4.6-481.1.el9_6.noarch                                                                                                                                                   23/195
  Installing       : perl-Unicode-Normalize-1.27-461.el9.x86_64                                                                                                                                        24/195
  Installing       : perl-doc-5.32.1-481.1.el9_6.noarch                                                                                                                                                25/195
  Upgrading        : perl-interpreter-4:5.32.1-481.1.el9_6.x86_64                                                                                                                                      26/195
  Installing       : perl-ExtUtils-ParseXS-1:3.40-460.el9.noarch                                                                                                                                       27/195
  Installing       : perl-JSON-PP-1:4.06-4.el9.noarch                                                                                                                                                  28/195
  Installing       : perl-Digest-SHA-1:6.02-461.el9.x86_64                                                                                                                                             29/195
  Installing       : perl-meta-notation-5.32.1-481.1.el9_6.noarch                                                                                                                                      30/195
  Installing       : perl-Pod-Html-1.25-481.1.el9_6.noarch                                                                                                                                             31/195
  Installing       : perl-encoding-4:3.00-462.el9.x86_64                                                                                                                                               32/195
  Installing       : perl-Dumpvalue-2.27-481.1.el9_6.noarch                                                                                                                                            33/195
  Installing       : perl-Net-Ping-2.74-5.el9.noarch                                                                                                                                                   34/195
  Installing       : perl-ExtUtils-Command-2:7.60-3.el9.noarch                                                                                                                                         35/195
  Installing       : perl-AutoSplit-5.74-481.1.el9_6.noarch                                                                                                                                            36/195
  Installing       : perl-Benchmark-1.23-481.1.el9_6.noarch                                                                                                                                            37/195
  Installing       : perl-Test-Harness-1:3.42-461.el9.noarch                                                                                                                                           38/195
  Installing       : perl-CPAN-Meta-YAML-0.018-461.el9.noarch                                                                                                                                          39/195
  Installing       : perl-CPAN-Meta-2.150010-460.el9.noarch                                                                                                                                            40/195
  Installing       : perl-Compress-Raw-Bzip2-2.101-5.el9.x86_64                                                                                                                                        41/195
  Installing       : perl-IO-Compress-2.102-4.el9.noarch                                                                                                                                               42/195
  Installing       : perl-IO-Zlib-1:1.11-4.el9.noarch                                                                                                                                                  43/195
  Installing       : perl-Devel-PPPort-3.62-4.el9.x86_64                                                                                                                                               44/195
  Installing       : perl-DirHandle-1.05-481.1.el9_6.noarch                                                                                                                                            45/195
  Installing       : perl-ExtUtils-Constant-0.25-481.1.el9_6.noarch                                                                                                                                    46/195
  Installing       : perl-ExtUtils-MM-Utils-2:7.60-3.el9.noarch                                                                                                                                        47/195
  Installing       : perl-Hash-Util-FieldHash-1.20-481.1.el9_6.x86_64                                                                                                                                  48/195
  Installing       : perl-Hash-Util-0.23-481.1.el9_6.x86_64                                                                                                                                            49/195
  Installing       : perl-I18N-LangTags-0.44-481.1.el9_6.noarch                                                                                                                                        50/195
  Installing       : perl-Locale-Maketext-1.29-461.el9.noarch                                                                                                                                          51/195
  Installing       : perl-Locale-Maketext-Simple-1:0.21-481.1.el9_6.noarch                                                                                                                             52/195
  Installing       : perl-Params-Check-1:0.38-461.el9.noarch                                                                                                                                           53/195
  Installing       : perl-Module-Load-Conditional-0.74-4.el9.noarch                                                                                                                                    54/195
  Installing       : perl-IPC-Cmd-2:1.04-461.el9.noarch                                                                                                                                                55/195
  Installing       : perl-I18N-Langinfo-0.19-481.1.el9_6.x86_64                                                                                                                                        56/195
  Installing       : perl-Math-BigRat-0.2614-460.el9.noarch                                                                                                                                            57/195
  Installing       : perl-Opcode-1.48-481.1.el9_6.x86_64                                                                                                                                               58/195
  Installing       : perl-Safe-2.41-481.1.el9_6.noarch                                                                                                                                                 59/195
  Installing       : perl-Params-Util-1.102-5.el9.x86_64                                                                                                                                               60/195
  Installing       : perl-SelfLoader-1.26-481.1.el9_6.noarch                                                                                                                                           61/195
  Installing       : perl-Sub-Install-0.928-28.el9.noarch                                                                                                                                              62/195
  Installing       : perl-Sys-Hostname-1.23-481.1.el9_6.x86_64                                                                                                                                         63/195
  Installing       : perl-TermReadKey-2.38-11.el9.x86_64                                                                                                                                               64/195
  Installing       : perl-Text-Balanced-2.04-4.el9.noarch                                                                                                                                              65/195
  Installing       : perl-Tie-RefHash-1.40-4.el9.noarch                                                                                                                                                66/195
  Installing       : perl-User-pwent-1.03-481.1.el9_6.noarch                                                                                                                                           67/195
  Installing       : perl-autouse-1.11-481.1.el9_6.noarch                                                                                                                                              68/195
  Upgrading        : perl-Errno-1.30-481.1.el9_6.x86_64                                                                                                                                                69/195
  Installing       : perl-Filter-Simple-0.96-460.el9.noarch                                                                                                                                            70/195
  Installing       : perl-Data-OptList-0.110-17.el9.noarch                                                                                                                                             71/195
  Installing       : perl-Devel-SelfStubber-1.06-481.1.el9_6.noarch                                                                                                                                    72/195
  Installing       : perl-bignum-0.51-460.el9.noarch                                                                                                                                                   73/195
  Installing       : perl-Encode-Locale-1.05-21.el9.noarch                                                                                                                                             74/195
  Installing       : perl-File-Fetch-1.00-4.el9.noarch                                                                                                                                                 75/195
  Installing       : perl-fields-2.27-481.1.el9_6.noarch                                                                                                                                               76/195
  Installing       : perl-DBM_Filter-0.06-481.1.el9_6.noarch                                                                                                                                           77/195
  Installing       : perl-open-1.12-481.1.el9_6.noarch                                                                                                                                                 78/195
  Installing       : perl-debugger-1.56-481.1.el9_6.noarch                                                                                                                                             79/195
  Installing       : perl-sigtrap-1.09-481.1.el9_6.noarch                                                                                                                                              80/195
  Installing       : kernel-srpm-macros-1.0-14.0.1.el9.noarch                                                                                                                                          81/195
  Installing       : perl-Archive-Zip-1.68-6.el9.noarch                                                                                                                                                82/195
  Installing       : perl-Module-CoreList-tools-1:5.20240609-1.el9.noarch                                                                                                                              83/195
  Installing       : perl-Pod-Checker-4:1.74-4.el9.noarch                                                                                                                                              84/195
  Installing       : perl-diagnostics-1.37-481.1.el9_6.noarch                                                                                                                                          85/195
  Installing       : perl-macros-4:5.32.1-481.1.el9_6.noarch                                                                                                                                           86/195
  Installing       : perl-utils-5.32.1-481.1.el9_6.noarch                                                                                                                                              87/195
  Installing       : perl-Unicode-Collate-1.29-4.el9.x86_64                                                                                                                                            88/195
  Installing       : perl-Unicode-UCD-0.75-481.1.el9_6.noarch                                                                                                                                          89/195
  Installing       : perl-Env-1.04-460.el9.noarch                                                                                                                                                      90/195
  Installing       : perl-Thread-3.05-481.1.el9_6.noarch                                                                                                                                               91/195
  Installing       : perl-Thread-Queue-3.14-460.el9.noarch                                                                                                                                             92/195
  Installing       : perl-Thread-Semaphore-2.13-481.1.el9_6.noarch                                                                                                                                     93/195
  Installing       : perl-experimental-0.022-6.el9.noarch                                                                                                                                              94/195
  Installing       : perl-Algorithm-Diff-1.2010-4.el9.noarch                                                                                                                                           95/195
  Installing       : perl-Text-Diff-1.45-13.el9.noarch                                                                                                                                                 96/195
  Installing       : perl-Attribute-Handlers-1.01-481.1.el9_6.noarch                                                                                                                                   97/195
  Installing       : perl-CPAN-DistnameInfo-0.12-23.el9.noarch                                                                                                                                         98/195
  Installing       : perl-Compress-Bzip2-2.28-5.el9.x86_64                                                                                                                                             99/195
  Installing       : perl-Compress-Raw-Lzma-2.101-3.el9.x86_64                                                                                                                                        100/195
  Installing       : perl-IO-Compress-Lzma-2.101-4.el9.noarch                                                                                                                                         101/195
  Installing       : perl-Archive-Tar-2.38-6.el9.noarch                                                                                                                                               102/195
  Installing       : perl-Config-Extensions-0.03-481.1.el9_6.noarch                                                                                                                                   103/195
  Installing       : perl-Config-Perl-V-0.33-4.el9.noarch                                                                                                                                             104/195
  Installing       : perl-Devel-Size-0.83-10.el9.x86_64                                                                                                                                               105/195
  Installing       : perl-Digest-SHA1-2.13-34.el9.x86_64                                                                                                                                              106/195
  Installing       : perl-Module-Signature-0.88-1.el9.noarch                                                                                                                                          107/195
  Installing       : perl-English-1.11-481.1.el9_6.noarch                                                                                                                                             108/195
  Installing       : perl-File-DosGlob-1.12-481.1.el9_6.x86_64                                                                                                                                        109/195
  Installing       : perl-File-Which-1.23-10.el9.noarch                                                                                                                                               110/195
  Installing       : perl-File-HomeDir-1.006-4.el9.noarch                                                                                                                                             111/195
  Installing       : perl-FileCache-1.10-481.1.el9_6.noarch                                                                                                                                           112/195
  Installing       : perl-FindBin-1.51-481.1.el9_6.noarch                                                                                                                                             113/195
  Installing       : perl-I18N-Collate-1.02-481.1.el9_6.noarch                                                                                                                                        114/195
  Installing       : perl-IPC-SysV-2.09-4.el9.x86_64                                                                                                                                                  115/195
  Installing       : perl-IPC-System-Simple-1.30-6.el9.noarch                                                                                                                                         116/195
  Installing       : perl-autodie-2.34-4.el9.noarch                                                                                                                                                   117/195
  Installing       : perl-Importer-0.026-4.el9.noarch                                                                                                                                                 118/195
  Installing       : perl-MIME-Charset-1.012.2-15.el9.noarch                                                                                                                                          119/195
  Installing       : perl-MRO-Compat-0.13-15.el9.noarch                                                                                                                                               120/195
  Installing       : perl-Math-BigInt-FastCalc-0.500.900-460.el9.x86_64                                                                                                                               121/195
  Installing       : perl-Memoize-1.03-481.1.el9_6.noarch                                                                                                                                             122/195
  Installing       : perl-Module-Loaded-1:0.08-481.1.el9_6.noarch                                                                                                                                     123/195
  Installing       : perl-NEXT-0.67-481.1.el9_6.noarch                                                                                                                                                124/195
  Installing       : perl-Net-1.02-481.1.el9_6.noarch                                                                                                                                                 125/195
  Installing       : perl-Object-HashBase-0.009-7.el9.noarch                                                                                                                                          126/195
  Installing       : perl-Package-Generator-1.106-23.el9.noarch                                                                                                                                       127/195
  Installing       : perl-Sub-Exporter-0.987-27.el9.noarch                                                                                                                                            128/195
  Installing       : perl-Data-Section-0.200007-14.el9.noarch                                                                                                                                         129/195
  Installing       : perl-PerlIO-via-QuotedPrint-0.09-4.el9.noarch                                                                                                                                    130/195
  Installing       : perl-Pod-Functions-1.13-481.1.el9_6.noarch                                                                                                                                       131/195
  Installing       : perl-Search-Dict-1.07-481.1.el9_6.noarch                                                                                                                                         132/195
  Installing       : perl-Sys-Syslog-0.36-461.el9.x86_64                                                                                                                                              133/195
  Installing       : perl-Term-Complete-1.403-481.1.el9_6.noarch                                                                                                                                      134/195
  Installing       : perl-Term-Size-Perl-0.031-12.el9.x86_64                                                                                                                                          135/195
  Installing       : perl-Term-Size-Any-0.002-35.el9.noarch                                                                                                                                           136/195
  Installing       : perl-Test-1.31-481.1.el9_6.noarch                                                                                                                                                137/195
  Installing       : perl-Text-Abbrev-1.02-481.1.el9_6.noarch                                                                                                                                         138/195
  Installing       : perl-Text-Glob-0.11-15.el9.noarch                                                                                                                                                139/195
  Installing       : perl-Text-Template-1.59-5.el9.noarch                                                                                                                                             140/195
  Installing       : perl-Software-License-0.103014-12.el9.noarch                                                                                                                                     141/195
  Installing       : perl-Tie-File-1.06-481.1.el9_6.noarch                                                                                                                                            142/195
  Installing       : perl-Tie-Memoize-1.1-481.1.el9_6.noarch                                                                                                                                          143/195
  Installing       : perl-Time-1.03-481.1.el9_6.noarch                                                                                                                                                144/195
  Installing       : perl-Time-Piece-1.3401-481.1.el9_6.x86_64                                                                                                                                        145/195
  Installing       : perl-blib-1.07-481.1.el9_6.noarch                                                                                                                                                146/195
  Installing       : perl-deprecate-0.04-481.1.el9_6.noarch                                                                                                                                           147/195
  Installing       : perl-encoding-warnings-0.13-481.1.el9_6.noarch                                                                                                                                   148/195
  Installing       : perl-filetest-1.03-481.1.el9_6.noarch                                                                                                                                            149/195
  Installing       : perl-less-0.03-481.1.el9_6.noarch                                                                                                                                                150/195
  Installing       : perl-local-lib-2.000024-13.el9.noarch                                                                                                                                            151/195
  Installing       : perl-perlfaq-5.20210520-1.el9.noarch                                                                                                                                             152/195
  Installing       : perl-ph-5.32.1-481.1.el9_6.x86_64                                                                                                                                                153/195
  Installing       : perl-sort-2.04-481.1.el9_6.noarch                                                                                                                                                154/195
  Installing       : perl-vmsish-1.04-481.1.el9_6.noarch                                                                                                                                              155/195
  Installing       : annobin-12.92-1.el9.x86_64                                                                                                                                                       156/195
  Installing       : gcc-plugin-annobin-11.5.0-11.0.2.el9.x86_64                                                                                                                                      157/195
  Installing       : libstdc++-devel-11.5.0-11.0.2.el9.x86_64                                                                                                                                         158/195
  Installing       : gcc-c++-11.5.0-11.0.2.el9.x86_64                                                                                                                                                 159/195
  Installing       : systemtap-sdt-dtrace-5.3-3.0.1.el9.x86_64                                                                                                                                        160/195
  Installing       : systemtap-sdt-devel-5.3-3.0.1.el9.x86_64                                                                                                                                         161/195
  Installing       : sombok-2.4.0-16.el9.x86_64                                                                                                                                                       162/195
  Installing       : perl-Unicode-LineBreak-2019.001-11.el9.x86_64                                                                                                                                    163/195
  Installing       : perl-Term-Table-0.015-8.el9.noarch                                                                                                                                               164/195
  Installing       : perl-Test-Simple-3:1.302183-4.el9.noarch                                                                                                                                         165/195
  Installing       : rust-srpm-macros-17-4.el9.noarch                                                                                                                                                 166/195
  Installing       : qt5-srpm-macros-5.15.9-1.el9.noarch                                                                                                                                              167/195
  Installing       : pyproject-srpm-macros-1.16.2-1.el9.noarch                                                                                                                                        168/195
  Installing       : perl-srpm-macros-1-41.el9.noarch                                                                                                                                                 169/195
  Installing       : openblas-srpm-macros-2-11.el9.noarch                                                                                                                                             170/195
  Installing       : ocaml-srpm-macros-6-6.el9.noarch                                                                                                                                                 171/195
  Installing       : lua-srpm-macros-1-6.el9.noarch                                                                                                                                                   172/195
  Installing       : ghc-srpm-macros-1.5.0-6.el9.noarch                                                                                                                                               173/195
  Installing       : efi-srpm-macros-6-4.0.1.el9.noarch                                                                                                                                               174/195
  Installing       : dwz-0.16-1.el9.x86_64                                                                                                                                                            175/195
  Installing       : fonts-srpm-macros-1:2.0.5-7.el9.1.noarch                                                                                                                                         176/195
  Installing       : go-srpm-macros-3.6.0-14.el9_7.noarch                                                                                                                                             177/195
  Installing       : python-srpm-macros-3.9-54.el9.noarch                                                                                                                                             178/195
  Installing       : redhat-rpm-config-210-1.0.1.el9.noarch                                                                                                                                           179/195
  Running scriptlet: redhat-rpm-config-210-1.0.1.el9.noarch                                                                                                                                           179/195
  Installing       : perl-ExtUtils-Install-2.20-4.el9.noarch                                                                                                                                          180/195
  Installing       : perl-devel-4:5.32.1-481.1.el9_6.x86_64                                                                                                                                           181/195
  Installing       : perl-ExtUtils-MakeMaker-2:7.60-3.el9.noarch                                                                                                                                      182/195
  Installing       : perl-ExtUtils-CBuilder-1:0.280236-4.el9.noarch                                                                                                                                   183/195
  Installing       : perl-ExtUtils-Embed-1.35-481.1.el9_6.noarch                                                                                                                                      184/195
  Installing       : perl-ExtUtils-Miniperl-1.09-481.1.el9_6.noarch                                                                                                                                   185/195
  Installing       : perl-libnetcfg-4:5.32.1-481.1.el9_6.noarch                                                                                                                                       186/195
  Installing       : perl-Encode-devel-4:3.08-462.el9.x86_64                                                                                                                                          187/195
  Installing       : perl-inc-latest-2:0.500-20.el9.noarch                                                                                                                                            188/195
  Installing       : perl-Module-Build-2:0.42.31-9.el9.noarch                                                                                                                                         189/195
  Installing       : perl-CPAN-2.29-5.el9_6.noarch                                                                                                                                                    190/195
  Installing       : perl-4:5.32.1-481.1.el9_6.x86_64                                                                                                                                                 191/195
  Cleanup          : perl-Errno-1.30-481.el9.x86_64                                                                                                                                                   192/195
  Cleanup          : perl-interpreter-4:5.32.1-481.el9.x86_64                                                                                                                                         193/195
  Cleanup          : perl-libs-4:5.32.1-481.el9.x86_64                                                                                                                                                194/195
  Cleanup          : libstdc++-11.5.0-5.0.1.el9.x86_64                                                                                                                                                195/195
  Running scriptlet: libstdc++-11.5.0-5.0.1.el9.x86_64                                                                                                                                                195/195
  Verifying        : annobin-12.92-1.el9.x86_64                                                                                                                                                         1/195
  Verifying        : dwz-0.16-1.el9.x86_64                                                                                                                                                              2/195
  Verifying        : efi-srpm-macros-6-4.0.1.el9.noarch                                                                                                                                                 3/195
  Verifying        : fonts-srpm-macros-1:2.0.5-7.el9.1.noarch                                                                                                                                           4/195
  Verifying        : gcc-c++-11.5.0-11.0.2.el9.x86_64                                                                                                                                                   5/195
  Verifying        : gcc-plugin-annobin-11.5.0-11.0.2.el9.x86_64                                                                                                                                        6/195
  Verifying        : ghc-srpm-macros-1.5.0-6.el9.noarch                                                                                                                                                 7/195
  Verifying        : go-srpm-macros-3.6.0-14.el9_7.noarch                                                                                                                                               8/195
  Verifying        : kernel-srpm-macros-1.0-14.0.1.el9.noarch                                                                                                                                           9/195
  Verifying        : libstdc++-devel-11.5.0-11.0.2.el9.x86_64                                                                                                                                          10/195
  Verifying        : lua-srpm-macros-1-6.el9.noarch                                                                                                                                                    11/195
  Verifying        : ocaml-srpm-macros-6-6.el9.noarch                                                                                                                                                  12/195
  Verifying        : openblas-srpm-macros-2-11.el9.noarch                                                                                                                                              13/195
  Verifying        : perl-4:5.32.1-481.1.el9_6.x86_64                                                                                                                                                  14/195
  Verifying        : perl-Algorithm-Diff-1.2010-4.el9.noarch                                                                                                                                           15/195
  Verifying        : perl-Archive-Tar-2.38-6.el9.noarch                                                                                                                                                16/195
  Verifying        : perl-Archive-Zip-1.68-6.el9.noarch                                                                                                                                                17/195
  Verifying        : perl-Attribute-Handlers-1.01-481.1.el9_6.noarch                                                                                                                                   18/195
  Verifying        : perl-AutoSplit-5.74-481.1.el9_6.noarch                                                                                                                                            19/195
  Verifying        : perl-Benchmark-1.23-481.1.el9_6.noarch                                                                                                                                            20/195
  Verifying        : perl-CPAN-2.29-5.el9_6.noarch                                                                                                                                                     21/195
  Verifying        : perl-CPAN-DistnameInfo-0.12-23.el9.noarch                                                                                                                                         22/195
  Verifying        : perl-CPAN-Meta-2.150010-460.el9.noarch                                                                                                                                            23/195
  Verifying        : perl-CPAN-Meta-Requirements-2.140-461.el9.noarch                                                                                                                                  24/195
  Verifying        : perl-CPAN-Meta-YAML-0.018-461.el9.noarch                                                                                                                                          25/195
  Verifying        : perl-Compress-Bzip2-2.28-5.el9.x86_64                                                                                                                                             26/195
  Verifying        : perl-Compress-Raw-Bzip2-2.101-5.el9.x86_64                                                                                                                                        27/195
  Verifying        : perl-Compress-Raw-Lzma-2.101-3.el9.x86_64                                                                                                                                         28/195
  Verifying        : perl-Compress-Raw-Zlib-2.101-5.el9.x86_64                                                                                                                                         29/195
  Verifying        : perl-Config-Extensions-0.03-481.1.el9_6.noarch                                                                                                                                    30/195
  Verifying        : perl-Config-Perl-V-0.33-4.el9.noarch                                                                                                                                              31/195
  Verifying        : perl-DBM_Filter-0.06-481.1.el9_6.noarch                                                                                                                                           32/195
  Verifying        : perl-DB_File-1.855-4.el9.x86_64                                                                                                                                                   33/195
  Verifying        : perl-Data-OptList-0.110-17.el9.noarch                                                                                                                                             34/195
  Verifying        : perl-Data-Section-0.200007-14.el9.noarch                                                                                                                                          35/195
  Verifying        : perl-Devel-PPPort-3.62-4.el9.x86_64                                                                                                                                               36/195
  Verifying        : perl-Devel-Peek-1.28-481.1.el9_6.x86_64                                                                                                                                           37/195
  Verifying        : perl-Devel-SelfStubber-1.06-481.1.el9_6.noarch                                                                                                                                    38/195
  Verifying        : perl-Devel-Size-0.83-10.el9.x86_64                                                                                                                                                39/195
  Verifying        : perl-Digest-SHA-1:6.02-461.el9.x86_64                                                                                                                                             40/195
  Verifying        : perl-Digest-SHA1-2.13-34.el9.x86_64                                                                                                                                               41/195
  Verifying        : perl-DirHandle-1.05-481.1.el9_6.noarch                                                                                                                                            42/195
  Verifying        : perl-Dumpvalue-2.27-481.1.el9_6.noarch                                                                                                                                            43/195
  Verifying        : perl-Encode-Locale-1.05-21.el9.noarch                                                                                                                                             44/195
  Verifying        : perl-Encode-devel-4:3.08-462.el9.x86_64                                                                                                                                           45/195
  Verifying        : perl-English-1.11-481.1.el9_6.noarch                                                                                                                                              46/195
  Verifying        : perl-Env-1.04-460.el9.noarch                                                                                                                                                      47/195
  Verifying        : perl-ExtUtils-CBuilder-1:0.280236-4.el9.noarch                                                                                                                                    48/195
  Verifying        : perl-ExtUtils-Command-2:7.60-3.el9.noarch                                                                                                                                         49/195
  Verifying        : perl-ExtUtils-Constant-0.25-481.1.el9_6.noarch                                                                                                                                    50/195
  Verifying        : perl-ExtUtils-Embed-1.35-481.1.el9_6.noarch                                                                                                                                       51/195
  Verifying        : perl-ExtUtils-Install-2.20-4.el9.noarch                                                                                                                                           52/195
  Verifying        : perl-ExtUtils-MM-Utils-2:7.60-3.el9.noarch                                                                                                                                        53/195
  Verifying        : perl-ExtUtils-MakeMaker-2:7.60-3.el9.noarch                                                                                                                                       54/195
  Verifying        : perl-ExtUtils-Manifest-1:1.73-4.el9.noarch                                                                                                                                        55/195
  Verifying        : perl-ExtUtils-Miniperl-1.09-481.1.el9_6.noarch                                                                                                                                    56/195
  Verifying        : perl-ExtUtils-ParseXS-1:3.40-460.el9.noarch                                                                                                                                       57/195
  Verifying        : perl-File-Compare-1.100.600-481.1.el9_6.noarch                                                                                                                                    58/195
  Verifying        : perl-File-Copy-2.34-481.1.el9_6.noarch                                                                                                                                            59/195
  Verifying        : perl-File-DosGlob-1.12-481.1.el9_6.x86_64                                                                                                                                         60/195
  Verifying        : perl-File-Fetch-1.00-4.el9.noarch                                                                                                                                                 61/195
  Verifying        : perl-File-HomeDir-1.006-4.el9.noarch                                                                                                                                              62/195
  Verifying        : perl-File-Which-1.23-10.el9.noarch                                                                                                                                                63/195
  Verifying        : perl-FileCache-1.10-481.1.el9_6.noarch                                                                                                                                            64/195
  Verifying        : perl-Filter-2:1.60-4.el9.x86_64                                                                                                                                                   65/195
  Verifying        : perl-Filter-Simple-0.96-460.el9.noarch                                                                                                                                            66/195
  Verifying        : perl-FindBin-1.51-481.1.el9_6.noarch                                                                                                                                              67/195
  Verifying        : perl-GDBM_File-1.18-481.1.el9_6.x86_64                                                                                                                                            68/195
  Verifying        : perl-Hash-Util-0.23-481.1.el9_6.x86_64                                                                                                                                            69/195
  Verifying        : perl-Hash-Util-FieldHash-1.20-481.1.el9_6.x86_64                                                                                                                                  70/195
  Verifying        : perl-I18N-Collate-1.02-481.1.el9_6.noarch                                                                                                                                         71/195
  Verifying        : perl-I18N-LangTags-0.44-481.1.el9_6.noarch                                                                                                                                        72/195
  Verifying        : perl-I18N-Langinfo-0.19-481.1.el9_6.x86_64                                                                                                                                        73/195
  Verifying        : perl-IO-Compress-2.102-4.el9.noarch                                                                                                                                               74/195
  Verifying        : perl-IO-Compress-Lzma-2.101-4.el9.noarch                                                                                                                                          75/195
  Verifying        : perl-IO-Zlib-1:1.11-4.el9.noarch                                                                                                                                                  76/195
  Verifying        : perl-IPC-Cmd-2:1.04-461.el9.noarch                                                                                                                                                77/195
  Verifying        : perl-IPC-SysV-2.09-4.el9.x86_64                                                                                                                                                   78/195
  Verifying        : perl-IPC-System-Simple-1.30-6.el9.noarch                                                                                                                                          79/195
  Verifying        : perl-Importer-0.026-4.el9.noarch                                                                                                                                                  80/195
  Verifying        : perl-JSON-PP-1:4.06-4.el9.noarch                                                                                                                                                  81/195
  Verifying        : perl-Locale-Maketext-1.29-461.el9.noarch                                                                                                                                          82/195
  Verifying        : perl-Locale-Maketext-Simple-1:0.21-481.1.el9_6.noarch                                                                                                                             83/195
  Verifying        : perl-MIME-Charset-1.012.2-15.el9.noarch                                                                                                                                           84/195
  Verifying        : perl-MRO-Compat-0.13-15.el9.noarch                                                                                                                                                85/195
  Verifying        : perl-Math-BigInt-FastCalc-0.500.900-460.el9.x86_64                                                                                                                                86/195
  Verifying        : perl-Math-BigRat-0.2614-460.el9.noarch                                                                                                                                            87/195
  Verifying        : perl-Memoize-1.03-481.1.el9_6.noarch                                                                                                                                              88/195
  Verifying        : perl-Module-Build-2:0.42.31-9.el9.noarch                                                                                                                                          89/195
  Verifying        : perl-Module-CoreList-1:5.20240609-1.el9.noarch                                                                                                                                    90/195
  Verifying        : perl-Module-CoreList-tools-1:5.20240609-1.el9.noarch                                                                                                                              91/195
  Verifying        : perl-Module-Load-1:0.36-4.el9.noarch                                                                                                                                              92/195
  Verifying        : perl-Module-Load-Conditional-0.74-4.el9.noarch                                                                                                                                    93/195
  Verifying        : perl-Module-Loaded-1:0.08-481.1.el9_6.noarch                                                                                                                                      94/195
  Verifying        : perl-Module-Metadata-1.000037-460.el9.noarch                                                                                                                                      95/195
  Verifying        : perl-Module-Signature-0.88-1.el9.noarch                                                                                                                                           96/195
  Verifying        : perl-NEXT-0.67-481.1.el9_6.noarch                                                                                                                                                 97/195
  Verifying        : perl-Net-1.02-481.1.el9_6.noarch                                                                                                                                                  98/195
  Verifying        : perl-Net-Ping-2.74-5.el9.noarch                                                                                                                                                   99/195
  Verifying        : perl-ODBM_File-1.16-481.1.el9_6.x86_64                                                                                                                                           100/195
  Verifying        : perl-Object-HashBase-0.009-7.el9.noarch                                                                                                                                          101/195
  Verifying        : perl-Opcode-1.48-481.1.el9_6.x86_64                                                                                                                                              102/195
  Verifying        : perl-Package-Generator-1.106-23.el9.noarch                                                                                                                                       103/195
  Verifying        : perl-Params-Check-1:0.38-461.el9.noarch                                                                                                                                          104/195
  Verifying        : perl-Params-Util-1.102-5.el9.x86_64                                                                                                                                              105/195
  Verifying        : perl-Perl-OSType-1.010-461.el9.noarch                                                                                                                                            106/195
  Verifying        : perl-PerlIO-via-QuotedPrint-0.09-4.el9.noarch                                                                                                                                    107/195
  Verifying        : perl-Pod-Checker-4:1.74-4.el9.noarch                                                                                                                                             108/195
  Verifying        : perl-Pod-Functions-1.13-481.1.el9_6.noarch                                                                                                                                       109/195
  Verifying        : perl-Pod-Html-1.25-481.1.el9_6.noarch                                                                                                                                            110/195
  Verifying        : perl-Safe-2.41-481.1.el9_6.noarch                                                                                                                                                111/195
  Verifying        : perl-Search-Dict-1.07-481.1.el9_6.noarch                                                                                                                                         112/195
  Verifying        : perl-SelfLoader-1.26-481.1.el9_6.noarch                                                                                                                                          113/195
  Verifying        : perl-Software-License-0.103014-12.el9.noarch                                                                                                                                     114/195
  Verifying        : perl-Sub-Exporter-0.987-27.el9.noarch                                                                                                                                            115/195
  Verifying        : perl-Sub-Install-0.928-28.el9.noarch                                                                                                                                             116/195
  Verifying        : perl-Sys-Hostname-1.23-481.1.el9_6.x86_64                                                                                                                                        117/195
  Verifying        : perl-Sys-Syslog-0.36-461.el9.x86_64                                                                                                                                              118/195
  Verifying        : perl-Term-Complete-1.403-481.1.el9_6.noarch                                                                                                                                      119/195
  Verifying        : perl-Term-ReadLine-1.17-481.1.el9_6.noarch                                                                                                                                       120/195
  Verifying        : perl-Term-Size-Any-0.002-35.el9.noarch                                                                                                                                           121/195
  Verifying        : perl-Term-Size-Perl-0.031-12.el9.x86_64                                                                                                                                          122/195
  Verifying        : perl-Term-Table-0.015-8.el9.noarch                                                                                                                                               123/195
  Verifying        : perl-TermReadKey-2.38-11.el9.x86_64                                                                                                                                              124/195
  Verifying        : perl-Test-1.31-481.1.el9_6.noarch                                                                                                                                                125/195
  Verifying        : perl-Test-Harness-1:3.42-461.el9.noarch                                                                                                                                          126/195
  Verifying        : perl-Test-Simple-3:1.302183-4.el9.noarch                                                                                                                                         127/195
  Verifying        : perl-Text-Abbrev-1.02-481.1.el9_6.noarch                                                                                                                                         128/195
  Verifying        : perl-Text-Balanced-2.04-4.el9.noarch                                                                                                                                             129/195
  Verifying        : perl-Text-Diff-1.45-13.el9.noarch                                                                                                                                                130/195
  Verifying        : perl-Text-Glob-0.11-15.el9.noarch                                                                                                                                                131/195
  Verifying        : perl-Text-Template-1.59-5.el9.noarch                                                                                                                                             132/195
  Verifying        : perl-Thread-3.05-481.1.el9_6.noarch                                                                                                                                              133/195
  Verifying        : perl-Thread-Queue-3.14-460.el9.noarch                                                                                                                                            134/195
  Verifying        : perl-Thread-Semaphore-2.13-481.1.el9_6.noarch                                                                                                                                    135/195
  Verifying        : perl-Tie-4.6-481.1.el9_6.noarch                                                                                                                                                  136/195
  Verifying        : perl-Tie-File-1.06-481.1.el9_6.noarch                                                                                                                                            137/195
  Verifying        : perl-Tie-Memoize-1.1-481.1.el9_6.noarch                                                                                                                                          138/195
  Verifying        : perl-Tie-RefHash-1.40-4.el9.noarch                                                                                                                                               139/195
  Verifying        : perl-Time-1.03-481.1.el9_6.noarch                                                                                                                                                140/195
  Verifying        : perl-Time-HiRes-4:1.9764-462.el9.x86_64                                                                                                                                          141/195
  Verifying        : perl-Time-Piece-1.3401-481.1.el9_6.x86_64                                                                                                                                        142/195
  Verifying        : perl-Unicode-Collate-1.29-4.el9.x86_64                                                                                                                                           143/195
  Verifying        : perl-Unicode-LineBreak-2019.001-11.el9.x86_64                                                                                                                                    144/195
  Verifying        : perl-Unicode-Normalize-1.27-461.el9.x86_64                                                                                                                                       145/195
  Verifying        : perl-Unicode-UCD-0.75-481.1.el9_6.noarch                                                                                                                                         146/195
  Verifying        : perl-User-pwent-1.03-481.1.el9_6.noarch                                                                                                                                          147/195
  Verifying        : perl-autodie-2.34-4.el9.noarch                                                                                                                                                   148/195
  Verifying        : perl-autouse-1.11-481.1.el9_6.noarch                                                                                                                                             149/195
  Verifying        : perl-bignum-0.51-460.el9.noarch                                                                                                                                                  150/195
  Verifying        : perl-blib-1.07-481.1.el9_6.noarch                                                                                                                                                151/195
  Verifying        : perl-debugger-1.56-481.1.el9_6.noarch                                                                                                                                            152/195
  Verifying        : perl-deprecate-0.04-481.1.el9_6.noarch                                                                                                                                           153/195
  Verifying        : perl-devel-4:5.32.1-481.1.el9_6.x86_64                                                                                                                                           154/195
  Verifying        : perl-diagnostics-1.37-481.1.el9_6.noarch                                                                                                                                         155/195
  Verifying        : perl-doc-5.32.1-481.1.el9_6.noarch                                                                                                                                               156/195
  Verifying        : perl-encoding-4:3.00-462.el9.x86_64                                                                                                                                              157/195
  Verifying        : perl-encoding-warnings-0.13-481.1.el9_6.noarch                                                                                                                                   158/195
  Verifying        : perl-experimental-0.022-6.el9.noarch                                                                                                                                             159/195
  Verifying        : perl-fields-2.27-481.1.el9_6.noarch                                                                                                                                              160/195
  Verifying        : perl-filetest-1.03-481.1.el9_6.noarch                                                                                                                                            161/195
  Verifying        : perl-inc-latest-2:0.500-20.el9.noarch                                                                                                                                            162/195
  Verifying        : perl-less-0.03-481.1.el9_6.noarch                                                                                                                                                163/195
  Verifying        : perl-lib-0.65-481.1.el9_6.x86_64                                                                                                                                                 164/195
  Verifying        : perl-libnetcfg-4:5.32.1-481.1.el9_6.noarch                                                                                                                                       165/195
  Verifying        : perl-local-lib-2.000024-13.el9.noarch                                                                                                                                            166/195
  Verifying        : perl-macros-4:5.32.1-481.1.el9_6.noarch                                                                                                                                          167/195
  Verifying        : perl-meta-notation-5.32.1-481.1.el9_6.noarch                                                                                                                                     168/195
  Verifying        : perl-open-1.12-481.1.el9_6.noarch                                                                                                                                                169/195
  Verifying        : perl-perlfaq-5.20210520-1.el9.noarch                                                                                                                                             170/195
  Verifying        : perl-ph-5.32.1-481.1.el9_6.x86_64                                                                                                                                                171/195
  Verifying        : perl-sigtrap-1.09-481.1.el9_6.noarch                                                                                                                                             172/195
  Verifying        : perl-sort-2.04-481.1.el9_6.noarch                                                                                                                                                173/195
  Verifying        : perl-srpm-macros-1-41.el9.noarch                                                                                                                                                 174/195
  Verifying        : perl-threads-1:2.25-460.el9.x86_64                                                                                                                                               175/195
  Verifying        : perl-threads-shared-1.61-460.el9.x86_64                                                                                                                                          176/195
  Verifying        : perl-utils-5.32.1-481.1.el9_6.noarch                                                                                                                                             177/195
  Verifying        : perl-version-7:0.99.28-4.el9.x86_64                                                                                                                                              178/195
  Verifying        : perl-vmsish-1.04-481.1.el9_6.noarch                                                                                                                                              179/195
  Verifying        : pyproject-srpm-macros-1.16.2-1.el9.noarch                                                                                                                                        180/195
  Verifying        : python-srpm-macros-3.9-54.el9.noarch                                                                                                                                             181/195
  Verifying        : qt5-srpm-macros-5.15.9-1.el9.noarch                                                                                                                                              182/195
  Verifying        : redhat-rpm-config-210-1.0.1.el9.noarch                                                                                                                                           183/195
  Verifying        : rust-srpm-macros-17-4.el9.noarch                                                                                                                                                 184/195
  Verifying        : sombok-2.4.0-16.el9.x86_64                                                                                                                                                       185/195
  Verifying        : systemtap-sdt-devel-5.3-3.0.1.el9.x86_64                                                                                                                                         186/195
  Verifying        : systemtap-sdt-dtrace-5.3-3.0.1.el9.x86_64                                                                                                                                        187/195
  Verifying        : libstdc++-11.5.0-11.0.2.el9.x86_64                                                                                                                                               188/195
  Verifying        : libstdc++-11.5.0-5.0.1.el9.x86_64                                                                                                                                                189/195
  Verifying        : perl-Errno-1.30-481.1.el9_6.x86_64                                                                                                                                               190/195
  Verifying        : perl-Errno-1.30-481.el9.x86_64                                                                                                                                                   191/195
  Verifying        : perl-interpreter-4:5.32.1-481.1.el9_6.x86_64                                                                                                                                     192/195
  Verifying        : perl-interpreter-4:5.32.1-481.el9.x86_64                                                                                                                                         193/195
  Verifying        : perl-libs-4:5.32.1-481.1.el9_6.x86_64                                                                                                                                            194/195
  Verifying        : perl-libs-4:5.32.1-481.el9.x86_64                                                                                                                                                195/195

Upgraded:
  libstdc++-11.5.0-11.0.2.el9.x86_64              perl-Errno-1.30-481.1.el9_6.x86_64              perl-interpreter-4:5.32.1-481.1.el9_6.x86_64              perl-libs-4:5.32.1-481.1.el9_6.x86_64
Installed:
  annobin-12.92-1.el9.x86_64                      dwz-0.16-1.el9.x86_64                               efi-srpm-macros-6-4.0.1.el9.noarch                     fonts-srpm-macros-1:2.0.5-7.el9.1.noarch
  gcc-c++-11.5.0-11.0.2.el9.x86_64                gcc-plugin-annobin-11.5.0-11.0.2.el9.x86_64         ghc-srpm-macros-1.5.0-6.el9.noarch                     go-srpm-macros-3.6.0-14.el9_7.noarch
  kernel-srpm-macros-1.0-14.0.1.el9.noarch        libstdc++-devel-11.5.0-11.0.2.el9.x86_64            lua-srpm-macros-1-6.el9.noarch                         ocaml-srpm-macros-6-6.el9.noarch
  openblas-srpm-macros-2-11.el9.noarch            perl-4:5.32.1-481.1.el9_6.x86_64                    perl-Algorithm-Diff-1.2010-4.el9.noarch                perl-Archive-Tar-2.38-6.el9.noarch
  perl-Archive-Zip-1.68-6.el9.noarch              perl-Attribute-Handlers-1.01-481.1.el9_6.noarch     perl-AutoSplit-5.74-481.1.el9_6.noarch                 perl-Benchmark-1.23-481.1.el9_6.noarch
  perl-CPAN-2.29-5.el9_6.noarch                   perl-CPAN-DistnameInfo-0.12-23.el9.noarch           perl-CPAN-Meta-2.150010-460.el9.noarch                 perl-CPAN-Meta-Requirements-2.140-461.el9.noarch
  perl-CPAN-Meta-YAML-0.018-461.el9.noarch        perl-Compress-Bzip2-2.28-5.el9.x86_64               perl-Compress-Raw-Bzip2-2.101-5.el9.x86_64             perl-Compress-Raw-Lzma-2.101-3.el9.x86_64
  perl-Compress-Raw-Zlib-2.101-5.el9.x86_64       perl-Config-Extensions-0.03-481.1.el9_6.noarch      perl-Config-Perl-V-0.33-4.el9.noarch                   perl-DBM_Filter-0.06-481.1.el9_6.noarch
  perl-DB_File-1.855-4.el9.x86_64                 perl-Data-OptList-0.110-17.el9.noarch               perl-Data-Section-0.200007-14.el9.noarch               perl-Devel-PPPort-3.62-4.el9.x86_64
  perl-Devel-Peek-1.28-481.1.el9_6.x86_64         perl-Devel-SelfStubber-1.06-481.1.el9_6.noarch      perl-Devel-Size-0.83-10.el9.x86_64                     perl-Digest-SHA-1:6.02-461.el9.x86_64
  perl-Digest-SHA1-2.13-34.el9.x86_64             perl-DirHandle-1.05-481.1.el9_6.noarch              perl-Dumpvalue-2.27-481.1.el9_6.noarch                 perl-Encode-Locale-1.05-21.el9.noarch
  perl-Encode-devel-4:3.08-462.el9.x86_64         perl-English-1.11-481.1.el9_6.noarch                perl-Env-1.04-460.el9.noarch                           perl-ExtUtils-CBuilder-1:0.280236-4.el9.noarch
  perl-ExtUtils-Command-2:7.60-3.el9.noarch       perl-ExtUtils-Constant-0.25-481.1.el9_6.noarch      perl-ExtUtils-Embed-1.35-481.1.el9_6.noarch            perl-ExtUtils-Install-2.20-4.el9.noarch
  perl-ExtUtils-MM-Utils-2:7.60-3.el9.noarch      perl-ExtUtils-MakeMaker-2:7.60-3.el9.noarch         perl-ExtUtils-Manifest-1:1.73-4.el9.noarch             perl-ExtUtils-Miniperl-1.09-481.1.el9_6.noarch
  perl-ExtUtils-ParseXS-1:3.40-460.el9.noarch     perl-File-Compare-1.100.600-481.1.el9_6.noarch      perl-File-Copy-2.34-481.1.el9_6.noarch                 perl-File-DosGlob-1.12-481.1.el9_6.x86_64
  perl-File-Fetch-1.00-4.el9.noarch               perl-File-HomeDir-1.006-4.el9.noarch                perl-File-Which-1.23-10.el9.noarch                     perl-FileCache-1.10-481.1.el9_6.noarch
  perl-Filter-2:1.60-4.el9.x86_64                 perl-Filter-Simple-0.96-460.el9.noarch              perl-FindBin-1.51-481.1.el9_6.noarch                   perl-GDBM_File-1.18-481.1.el9_6.x86_64
  perl-Hash-Util-0.23-481.1.el9_6.x86_64          perl-Hash-Util-FieldHash-1.20-481.1.el9_6.x86_64    perl-I18N-Collate-1.02-481.1.el9_6.noarch              perl-I18N-LangTags-0.44-481.1.el9_6.noarch
  perl-I18N-Langinfo-0.19-481.1.el9_6.x86_64      perl-IO-Compress-2.102-4.el9.noarch                 perl-IO-Compress-Lzma-2.101-4.el9.noarch               perl-IO-Zlib-1:1.11-4.el9.noarch
  perl-IPC-Cmd-2:1.04-461.el9.noarch              perl-IPC-SysV-2.09-4.el9.x86_64                     perl-IPC-System-Simple-1.30-6.el9.noarch               perl-Importer-0.026-4.el9.noarch
  perl-JSON-PP-1:4.06-4.el9.noarch                perl-Locale-Maketext-1.29-461.el9.noarch            perl-Locale-Maketext-Simple-1:0.21-481.1.el9_6.noarch  perl-MIME-Charset-1.012.2-15.el9.noarch
  perl-MRO-Compat-0.13-15.el9.noarch              perl-Math-BigInt-FastCalc-0.500.900-460.el9.x86_64  perl-Math-BigRat-0.2614-460.el9.noarch                 perl-Memoize-1.03-481.1.el9_6.noarch
  perl-Module-Build-2:0.42.31-9.el9.noarch        perl-Module-CoreList-1:5.20240609-1.el9.noarch      perl-Module-CoreList-tools-1:5.20240609-1.el9.noarch   perl-Module-Load-1:0.36-4.el9.noarch
  perl-Module-Load-Conditional-0.74-4.el9.noarch  perl-Module-Loaded-1:0.08-481.1.el9_6.noarch        perl-Module-Metadata-1.000037-460.el9.noarch           perl-Module-Signature-0.88-1.el9.noarch
  perl-NEXT-0.67-481.1.el9_6.noarch               perl-Net-1.02-481.1.el9_6.noarch                    perl-Net-Ping-2.74-5.el9.noarch                        perl-ODBM_File-1.16-481.1.el9_6.x86_64
  perl-Object-HashBase-0.009-7.el9.noarch         perl-Opcode-1.48-481.1.el9_6.x86_64                 perl-Package-Generator-1.106-23.el9.noarch             perl-Params-Check-1:0.38-461.el9.noarch
  perl-Params-Util-1.102-5.el9.x86_64             perl-Perl-OSType-1.010-461.el9.noarch               perl-PerlIO-via-QuotedPrint-0.09-4.el9.noarch          perl-Pod-Checker-4:1.74-4.el9.noarch
  perl-Pod-Functions-1.13-481.1.el9_6.noarch      perl-Pod-Html-1.25-481.1.el9_6.noarch               perl-Safe-2.41-481.1.el9_6.noarch                      perl-Search-Dict-1.07-481.1.el9_6.noarch
  perl-SelfLoader-1.26-481.1.el9_6.noarch         perl-Software-License-0.103014-12.el9.noarch        perl-Sub-Exporter-0.987-27.el9.noarch                  perl-Sub-Install-0.928-28.el9.noarch
  perl-Sys-Hostname-1.23-481.1.el9_6.x86_64       perl-Sys-Syslog-0.36-461.el9.x86_64                 perl-Term-Complete-1.403-481.1.el9_6.noarch            perl-Term-ReadLine-1.17-481.1.el9_6.noarch
  perl-Term-Size-Any-0.002-35.el9.noarch          perl-Term-Size-Perl-0.031-12.el9.x86_64             perl-Term-Table-0.015-8.el9.noarch                     perl-TermReadKey-2.38-11.el9.x86_64
  perl-Test-1.31-481.1.el9_6.noarch               perl-Test-Harness-1:3.42-461.el9.noarch             perl-Test-Simple-3:1.302183-4.el9.noarch               perl-Text-Abbrev-1.02-481.1.el9_6.noarch
  perl-Text-Balanced-2.04-4.el9.noarch            perl-Text-Diff-1.45-13.el9.noarch                   perl-Text-Glob-0.11-15.el9.noarch                      perl-Text-Template-1.59-5.el9.noarch
  perl-Thread-3.05-481.1.el9_6.noarch             perl-Thread-Queue-3.14-460.el9.noarch               perl-Thread-Semaphore-2.13-481.1.el9_6.noarch          perl-Tie-4.6-481.1.el9_6.noarch
  perl-Tie-File-1.06-481.1.el9_6.noarch           perl-Tie-Memoize-1.1-481.1.el9_6.noarch             perl-Tie-RefHash-1.40-4.el9.noarch                     perl-Time-1.03-481.1.el9_6.noarch
  perl-Time-HiRes-4:1.9764-462.el9.x86_64         perl-Time-Piece-1.3401-481.1.el9_6.x86_64           perl-Unicode-Collate-1.29-4.el9.x86_64                 perl-Unicode-LineBreak-2019.001-11.el9.x86_64
  perl-Unicode-Normalize-1.27-461.el9.x86_64      perl-Unicode-UCD-0.75-481.1.el9_6.noarch            perl-User-pwent-1.03-481.1.el9_6.noarch                perl-autodie-2.34-4.el9.noarch
  perl-autouse-1.11-481.1.el9_6.noarch            perl-bignum-0.51-460.el9.noarch                     perl-blib-1.07-481.1.el9_6.noarch                      perl-debugger-1.56-481.1.el9_6.noarch
  perl-deprecate-0.04-481.1.el9_6.noarch          perl-devel-4:5.32.1-481.1.el9_6.x86_64              perl-diagnostics-1.37-481.1.el9_6.noarch               perl-doc-5.32.1-481.1.el9_6.noarch
  perl-encoding-4:3.00-462.el9.x86_64             perl-encoding-warnings-0.13-481.1.el9_6.noarch      perl-experimental-0.022-6.el9.noarch                   perl-fields-2.27-481.1.el9_6.noarch
  perl-filetest-1.03-481.1.el9_6.noarch           perl-inc-latest-2:0.500-20.el9.noarch               perl-less-0.03-481.1.el9_6.noarch                      perl-lib-0.65-481.1.el9_6.x86_64
  perl-libnetcfg-4:5.32.1-481.1.el9_6.noarch      perl-local-lib-2.000024-13.el9.noarch               perl-macros-4:5.32.1-481.1.el9_6.noarch                perl-meta-notation-5.32.1-481.1.el9_6.noarch
  perl-open-1.12-481.1.el9_6.noarch               perl-perlfaq-5.20210520-1.el9.noarch                perl-ph-5.32.1-481.1.el9_6.x86_64                      perl-sigtrap-1.09-481.1.el9_6.noarch
  perl-sort-2.04-481.1.el9_6.noarch               perl-srpm-macros-1-41.el9.noarch                    perl-threads-1:2.25-460.el9.x86_64                     perl-threads-shared-1.61-460.el9.x86_64
  perl-utils-5.32.1-481.1.el9_6.noarch            perl-version-7:0.99.28-4.el9.x86_64                 perl-vmsish-1.04-481.1.el9_6.noarch                    pyproject-srpm-macros-1.16.2-1.el9.noarch
  python-srpm-macros-3.9-54.el9.noarch            qt5-srpm-macros-5.15.9-1.el9.noarch                 redhat-rpm-config-210-1.0.1.el9.noarch                 rust-srpm-macros-17-4.el9.noarch
  sombok-2.4.0-16.el9.x86_64                      systemtap-sdt-devel-5.3-3.0.1.el9.x86_64            systemtap-sdt-dtrace-5.3-3.0.1.el9.x86_64

Complete!
[root@pgdb01 postgresql-17.4]#

[root@pgdb01 postgresql-17.4]# make clean   <--- Cleanup due to error out
make -C doc clean
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/doc'
make -C src clean
..
..
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/config'
make[1]: Nothing to be done for 'clean'.
make[1]: Leaving directory '/pg_Backup/stage/postgresql-17.4/config'
rm -rf tmp_install/ portlock/
[root@pgdb01 postgresql-17.4]#

# Rerun make command
[root@pgdb01 postgresql-17.4]# make
make -C ./src/backend generated-headers
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/src/backend'
make -C ../include/catalog generated-headers
make[2]: Entering directory '/pg_Backup/stage/postgresql-17.4/src/include/catalog'
..
..
port -L../../../src/common   -Wl,--as-needed -Wl,-rpath,'/pgbin/pgsql/17.4/lib',--enable-new-dtags  -lpgcommon -lpgport -lz -lreadline -lm  -o pg_isolation_regress
make[2]: Leaving directory '/pg_Backup/stage/postgresql-17.4/src/test/isolation'
make -C test/perl all
make[2]: Entering directory '/pg_Backup/stage/postgresql-17.4/src/test/perl'
make[2]: Nothing to be done for 'all'.
make[2]: Leaving directory '/pg_Backup/stage/postgresql-17.4/src/test/perl'
make[1]: Leaving directory '/pg_Backup/stage/postgresql-17.4/src'
make -C config all
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/config'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/pg_Backup/stage/postgresql-17.4/config'
[root@pgdb01 postgresql-17.4]#

8. Install PostgreSQL

# Bin directory /pgbin/pgsql/17.4/ will get created by make install command. 

[root@pgdb01 postgresql-17.4]# make install
make -C ./src/backend generated-headers
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/src/backend'
make -C ../include/catalog generated-headers
..
..
make -C config install
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/config'
/usr/bin/mkdir -p '/pgbin/pgsql/17.4/lib/pgxs/config'
/usr/bin/install -c -m 755 ./install-sh '/pgbin/pgsql/17.4/lib/pgxs/config/install-sh'
/usr/bin/install -c -m 755 ./missing '/pgbin/pgsql/17.4/lib/pgxs/config/missing'
make[1]: Leaving directory '/pg_Backup/stage/postgresql-17.4/config'
[root@pgdb01 postgresql-17.4]#

[root@pgdb01 postgresql-17.4]# cd /pgbin/pgsql/17.4/
[root@pgdb01 17.4]# ll
total 16
drwxr-xr-x. 2 root root 4096 Apr 21 21:06 bin
drwxr-xr-x. 6 root root 4096 Apr 21 21:06 include
drwxr-xr-x. 4 root root 4096 Apr 21 21:06 lib
drwxr-xr-x. 6 root root 4096 Apr 21 21:06 share
[root@pgdb01 17.4]#

9. Install PostgreSQL Contrib for extensions

#Install Contrib

cd /pg_Backup/stage/postgresql-17.4
make -C contrib install

--- OR ----

cd /pg_Backup/stage/postgresql-17.4/contrib
make
make install

[root@pgdb01 ~]# cd /pg_Backup/stage/postgresql-17.4/contrib
[root@pgdb01 contrib]# make
..
..
make -C vacuumlo all
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/contrib/vacuumlo'
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -O2 -I../../src/interfaces/libpq -I. -I. -I../../src/include  -D_GNU_SOURCE   -c -o vacuumlo.o vacuumlo.c
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -O2  vacuumlo.o -L../../src/interfaces/libpq -lpq -L../../src/port -L../../src/common   -Wl,--as-needed -Wl,-rpath,'/pgbin/pgsql/17.4/lib',--enable-new-dtags   -lpgcommon -lpgport -lz -lreadline -lm  -o vacuumlo
make[1]: Leaving directory '/pg_Backup/stage/postgresql-17.4/contrib/vacuumlo'
[root@pgdb01 contrib]#

[root@pgdb01 contrib]# make install
..
..
make -C unaccent install
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/contrib/unaccent'
/usr/bin/mkdir -p '/pgbin/pgsql/17.4/lib'
/usr/bin/mkdir -p '/pgbin/pgsql/17.4/share/extension'
/usr/bin/mkdir -p '/pgbin/pgsql/17.4/share/extension'
/usr/bin/mkdir -p '/pgbin/pgsql/17.4/share/tsearch_data'
/usr/bin/install -c -m 755  unaccent.so '/pgbin/pgsql/17.4/lib/unaccent.so'
/usr/bin/install -c -m 644 ./unaccent.control '/pgbin/pgsql/17.4/share/extension/'
/usr/bin/install -c -m 644 ./unaccent--1.1.sql ./unaccent--1.0--1.1.sql  '/pgbin/pgsql/17.4/share/extension/'
/usr/bin/install -c -m 644 ./unaccent.rules '/pgbin/pgsql/17.4/share/tsearch_data/'
make[1]: Leaving directory '/pg_Backup/stage/postgresql-17.4/contrib/unaccent'
make -C vacuumlo install
make[1]: Entering directory '/pg_Backup/stage/postgresql-17.4/contrib/vacuumlo'
/usr/bin/mkdir -p '/pgbin/pgsql/17.4/bin'
/usr/bin/install -c  vacuumlo '/pgbin/pgsql/17.4/bin'
make[1]: Leaving directory '/pg_Backup/stage/postgresql-17.4/contrib/vacuumlo'
[root@pgdb01 contrib]#

[root@pgdb01 contrib]# ls /pgbin/pgsql/17.4/share/extension
amcheck--1.0--1.1.sql     citext.control               hstore--1.5--1.6.sql       pageinspect--1.10--1.11.sql    pgrowlocks.control                  pg_visibility--1.0--1.1.sql
amcheck--1.0.sql          cube--1.0--1.1.sql           hstore--1.6--1.7.sql       pageinspect--1.11--1.12.sql    pg_stat_statements--1.0--1.1.sql    pg_visibility--1.1--1.2.sql
amcheck--1.1--1.2.sql     cube--1.1--1.2.sql           hstore--1.7--1.8.sql       pageinspect--1.1--1.2.sql      pg_stat_statements--1.10--1.11.sql  pg_visibility--1.1.sql
amcheck--1.2--1.3.sql     cube--1.2--1.3.sql           hstore.control             pageinspect--1.2--1.3.sql      pg_stat_statements--1.1--1.2.sql    pg_visibility.control
amcheck--1.3--1.4.sql     cube--1.2.sql                insert_username--1.0.sql   pageinspect--1.3--1.4.sql      pg_stat_statements--1.2--1.3.sql    pg_walinspect--1.0--1.1.sql
amcheck.control           cube--1.3--1.4.sql           insert_username.control    pageinspect--1.4--1.5.sql      pg_stat_statements--1.3--1.4.sql    pg_walinspect--1.0.sql
autoinc--1.0.sql          cube--1.4--1.5.sql           intagg--1.0--1.1.sql       pageinspect--1.5--1.6.sql      pg_stat_statements--1.4--1.5.sql    pg_walinspect.control
autoinc.control           cube.control                 intagg--1.1.sql            pageinspect--1.5.sql           pg_stat_statements--1.4.sql         plpgsql--1.0.sql
bloom--1.0.sql            dblink--1.0--1.1.sql         intagg.control             pageinspect--1.6--1.7.sql      pg_stat_statements--1.5--1.6.sql    plpgsql.control
bloom.control             dblink--1.1--1.2.sql         intarray--1.0--1.1.sql     pageinspect--1.7--1.8.sql      pg_stat_statements--1.6--1.7.sql    postgres_fdw--1.0--1.1.sql
btree_gin--1.0--1.1.sql   dblink--1.2.sql              intarray--1.1--1.2.sql     pageinspect--1.8--1.9.sql      pg_stat_statements--1.7--1.8.sql    postgres_fdw--1.0.sql
btree_gin--1.0.sql        dblink.control               intarray--1.2--1.3.sql     pageinspect--1.9--1.10.sql     pg_stat_statements--1.8--1.9.sql    postgres_fdw.control
btree_gin--1.1--1.2.sql   dict_int--1.0.sql            intarray--1.2.sql          pageinspect.control            pg_stat_statements--1.9--1.10.sql   refint--1.0.sql
btree_gin--1.2--1.3.sql   dict_int.control             intarray--1.3--1.4.sql     pg_buffercache--1.0--1.1.sql   pg_stat_statements.control          refint.control
btree_gin.control         dict_xsyn--1.0.sql           intarray--1.4--1.5.sql     pg_buffercache--1.1--1.2.sql   pgstattuple--1.0--1.1.sql           seg--1.0--1.1.sql
btree_gist--1.0--1.1.sql  dict_xsyn.control            intarray.control           pg_buffercache--1.2--1.3.sql   pgstattuple--1.1--1.2.sql           seg--1.1--1.2.sql
btree_gist--1.1--1.2.sql  earthdistance--1.0--1.1.sql  isn--1.0--1.1.sql          pg_buffercache--1.2.sql        pgstattuple--1.2--1.3.sql           seg--1.1.sql
btree_gist--1.2--1.3.sql  earthdistance--1.1--1.2.sql  isn--1.1--1.2.sql          pg_buffercache--1.3--1.4.sql   pgstattuple--1.3--1.4.sql           seg--1.2--1.3.sql
btree_gist--1.2.sql       earthdistance--1.1.sql       isn--1.1.sql               pg_buffercache--1.4--1.5.sql   pgstattuple--1.4--1.5.sql           seg--1.3--1.4.sql
btree_gist--1.3--1.4.sql  earthdistance.control        isn.control                pg_buffercache.control         pgstattuple--1.4.sql                seg.control
btree_gist--1.4--1.5.sql  file_fdw--1.0.sql            lo--1.0--1.1.sql           pg_freespacemap--1.0--1.1.sql  pgstattuple.control                 tablefunc--1.0.sql
btree_gist--1.5--1.6.sql  file_fdw.control             lo--1.1.sql                pg_freespacemap--1.1--1.2.sql  pg_surgery--1.0.sql                 tablefunc.control
btree_gist--1.6--1.7.sql  fuzzystrmatch--1.0--1.1.sql  lo.control                 pg_freespacemap--1.1.sql       pg_surgery.control                  tcn--1.0.sql
btree_gist.control        fuzzystrmatch--1.1--1.2.sql  ltree--1.0--1.1.sql        pg_freespacemap.control        pg_trgm--1.0--1.1.sql               tcn.control
citext--1.0--1.1.sql      fuzzystrmatch--1.1.sql       ltree--1.1--1.2.sql        pg_prewarm--1.0--1.1.sql       pg_trgm--1.1--1.2.sql               tsm_system_rows--1.0.sql
citext--1.1--1.2.sql      fuzzystrmatch.control        ltree--1.1.sql             pg_prewarm--1.1--1.2.sql       pg_trgm--1.2--1.3.sql               tsm_system_rows.control
citext--1.2--1.3.sql      hstore--1.1--1.2.sql         ltree--1.2--1.3.sql        pg_prewarm--1.1.sql            pg_trgm--1.3--1.4.sql               tsm_system_time--1.0.sql
citext--1.3--1.4.sql      hstore--1.2--1.3.sql         ltree.control              pg_prewarm.control             pg_trgm--1.3.sql                    tsm_system_time.control
citext--1.4--1.5.sql      hstore--1.3--1.4.sql         moddatetime--1.0.sql       pgrowlocks--1.0--1.1.sql       pg_trgm--1.4--1.5.sql               unaccent--1.0--1.1.sql
citext--1.4.sql           hstore--1.4--1.5.sql         moddatetime.control        pgrowlocks--1.1--1.2.sql       pg_trgm--1.5--1.6.sql               unaccent--1.1.sql
citext--1.5--1.6.sql      hstore--1.4.sql              pageinspect--1.0--1.1.sql  pgrowlocks--1.2.sql            pg_trgm.control                     unaccent.control
[root@pgdb01 contrib]# 

[root@pgdb01 contrib]# cd
[root@pgdb01 ~]# chown -R postgres:postgres /pgbin /pgData /pgWal /pgArch /pg_Backup
[root@pgdb01 ~]# chmod 700 /pgbin /pgData /pgWal /pgArch /pg_Backup
[root@pgdb01 ~]#

10. Set Environment Variables (As Postgres user)

# Switch to postgres user:

[root@pgdb01 17.4]# su - postgres
[postgres@pgdb01 ~]$

# Add below lines to .bash_profile and reload profile

export PGHOME=/pgbin/pgsql/17.4
export PATH=$PGHOME/bin:$PATH
export PGDATA=/pgData/pgsql/17.4

[postgres@pgdb01 ~]$ . .bash_profile
[postgres@pgdb01 ~]$
[postgres@pgdb01 ~]$ which psql
/pgbin/pgsql/17.4/bin/psql
[postgres@pgdb01 ~]$

11. Validation 1 (As Postgres user)

[postgres@pgdb01 ~]$ /pgbin/pgsql/17.4/bin/pg_config
BINDIR = /pgbin/pgsql/17.4/bin
DOCDIR = /pgbin/pgsql/17.4/share/doc
HTMLDIR = /pgbin/pgsql/17.4/share/doc
INCLUDEDIR = /pgbin/pgsql/17.4/include
PKGINCLUDEDIR = /pgbin/pgsql/17.4/include
INCLUDEDIR-SERVER = /pgbin/pgsql/17.4/include/server
LIBDIR = /pgbin/pgsql/17.4/lib
PKGLIBDIR = /pgbin/pgsql/17.4/lib
LOCALEDIR = /pgbin/pgsql/17.4/share/locale
MANDIR = /pgbin/pgsql/17.4/share/man
SHAREDIR = /pgbin/pgsql/17.4/share
SYSCONFDIR = /pgbin/pgsql/17.4/etc
PGXS = /pgbin/pgsql/17.4/lib/pgxs/src/makefiles/pgxs.mk
CONFIGURE =  '--prefix=/pgbin/pgsql/17.4' '--with-pgport=5432'
CC = gcc
CPPFLAGS = -D_GNU_SOURCE
CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wcast-function-type -Wshadow=compatible-local -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -O2
CFLAGS_SL = -fPIC
LDFLAGS = -Wl,--as-needed -Wl,-rpath,'/pgbin/pgsql/17.4/lib',--enable-new-dtags
LDFLAGS_EX =
LDFLAGS_SL =
LIBS = -lpgcommon -lpgport -lz -lreadline -lm
VERSION = PostgreSQL 17.4
[postgres@pgdb01 ~]$

12. Initialize Database (As Postgres user)

# Read more about initdb
https://www.br8dba.com/initdb-postgresql-cluster-initialization/

[postgres@pgdb01 ~]$ mkdir -p /pgData/pgsql/17.4 /pgWal/pgsql/17.4
[postgres@pgdb01 ~]$

[postgres@pgdb01 ~]$ /pgbin/pgsql/17.4/bin/initdb --pgdata=/pgData/pgsql/17.4 --waldir=/pgWal/pgsql/17.4 --wal-segsize=128
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_SG.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

fixing permissions on existing directory /pgData/pgsql/17.4 ... ok
fixing permissions on existing directory /pgWal/pgsql/17.4 ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... Asia/Singapore
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /pgbin/pgsql/17.4/bin/pg_ctl -D /pgData/pgsql/17.4 -l logfile start

[postgres@pgdb01 ~]$

13. Start Postgres Instance(As Postgres user)

[postgres@pgdb01 ~]$ /pgbin/pgsql/17.4/bin/pg_ctl -D /pgData/pgsql/17.4 -l logfile start
waiting for server to start.... done
server started
[postgres@pgdb01 ~]$

14. Validation (As Postgres user)

[postgres@pgdb01 ~]$ ps -ef | grep postgres
root       62627    3156  0 21:40 pts/0    00:00:00 su - postgres
postgres   62628   62627  0 21:40 pts/0    00:00:00 -bash
postgres 62707 1 0 21:50 ? 00:00:00 /pgbin/pgsql/17.4/bin/postgres -D /pgData/pgsql/17.4
postgres   62708   62707 0 21:50 ?        00:00:00 postgres: checkpointer
postgres   62709   62707 0 21:50 ?        00:00:00 postgres: background writer
postgres   62711   62707 0 21:50 ?        00:00:00 postgres: walwriter
postgres   62712   62707 0 21:50 ?        00:00:00 postgres: autovacuum launcher
postgres   62713   62707 0 21:50 ?        00:00:00 postgres: logical replication launcher
postgres   62715   62628 99 21:52 pts/0    00:00:00 ps -ef
postgres   62716   62628  0 21:52 pts/0    00:00:00 grep --color=auto postgres
[postgres@pgdb01 ~]$
[postgres@pgdb01 ~]$ psql -c "SELECT VERSION();"
                                                    version
---------------------------------------------------------------------------------------------------------------
 PostgreSQL 17.4 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-11.0.2), 64-bit
(1 row)

[postgres@pgdb01 ~]$
[postgres@pgdb01 ~]$ psql
psql (17.4)
Type "help" for help.

postgres=# \l
                                                     List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------
 postgres | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +
           |          |          |                 |             |             |        |           | postgres=CTc/postgres
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +
           |          |          |                 |             |             |        |           | postgres=CTc/postgres
(3 rows)

postgres=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 postgres | Superuser, Create role, Create DB, Replication, Bypass RLS

postgres=#
postgres=# \q
[postgres@pgdb01 ~]$

15. Create systemctl service for PostgreSQL (as root user) - OptionalΒ 

# As root user

cat > /etc/systemd/system/postgresql-17.service <<'EOF'
[Unit]
Description=PostgreSQL 17 Database Server
Documentation=https://www.postgresql.org/docs/17/
After=network.target

[Service]
Type=forking

User=postgres
Group=postgres

# PostgreSQL Data Directory
Environment=PGDATA=/pgData/pgsql/17.4

# Start PostgreSQL
ExecStart=/pgbin/pgsql/17.4/bin/pg_ctl start -D ${PGDATA} -l ${PGDATA}/logfile

# Stop PostgreSQL
ExecStop=/pgbin/pgsql/17.4/bin/pg_ctl stop -D ${PGDATA} -m fast

# Reload PostgreSQL
ExecReload=/pgbin/pgsql/17.4/bin/pg_ctl reload -D ${PGDATA}

Restart=always
RestartSec=5

TimeoutSec=300

[Install]
WantedBy=multi-user.target
EOF
# Stop PostgreSQL as Postgres user using pg_ctl if running
# As postgres user
[postgres@pgdb02 ~]$ pg_ctl stop
waiting for server to shut down.... done
server stopped
[postgres@pgdb02 ~]$

# As root user 
# Enable PostgreSQL service at boot
[root@pgdb02 ~]# systemctl enable postgresql-17
Created symlink /etc/systemd/system/multi-user.target.wants/postgresql-17.service β†’ /etc/systemd/system/postgresql-17.service.
[root@pgdb02 ~]#

# As root user
# Start PostgreSQL service
[root@pgdb02 ~]# systemctl start postgresql-17
[root@pgdb02 ~]#

# As root user
# Verify Status
[root@pgdb02 ~]# systemctl status postgresql-17
● postgresql-17.service - PostgreSQL 17 Database Server
     Loaded: loaded (/etc/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Sat 2026-06-20 16:08:44 +08; 16s ago
       Docs: https://www.postgresql.org/docs/17/
    Process: 3302 ExecStart=/pgbin/pgsql/17.4/bin/pg_ctl start -D ${PGDATA} -l ${PGDATA}/logfile (code=exited, status=0/SUCCESS)
   Main PID: 3305 (postgres)
      Tasks: 6 (limit: 15700)
     Memory: 21.4M
        CPU: 77ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€3305 /pgbin/pgsql/17.4/bin/postgres -D /pgData/pgsql/17.4
             β”œβ”€3306 "postgres: checkpointer "
             β”œβ”€3307 "postgres: background writer "
             β”œβ”€3310 "postgres: walwriter "
             β”œβ”€3311 "postgres: autovacuum launcher "
             └─3312 "postgres: logical replication launcher "

Jun 20 16:08:43 pgdb02 systemd[1]: Starting PostgreSQL 17 Database Server...
Jun 20 16:08:44 pgdb02 pg_ctl[3302]: waiting for server to start.... done
Jun 20 16:08:44 pgdb02 pg_ctl[3302]: server started
Jun 20 16:08:44 pgdb02 systemd[1]: Started PostgreSQL 17 Database Server.
[root@pgdb02 ~]#
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/

PostgreSQL Architecture

PostgreSQL Architecture Fundamentals

PostgreSQL Data Flow



PostgreSQL Startup Sequence


Introduction

To work effectively with PostgreSQL, it is important to understand how it is built and how its different parts work together.
  • PostgreSQL follows a process-per-user client/server model.
  • Every time a user connects to the database, PostgreSQL creates a separate process for that user.
  • This process stays active until the user disconnects.
  • PostgreSQL has a group of processes and memory structures called an instance.
  • Each instance has its own memory and background processes.
  • A single server can run multiple instances.
  • Each instance works independently, which means:
    • Memory cannot be shared between instances.
    • Processes cannot be shared between instances.
  • Client applications connect to a PostgreSQL instance to read or write data.
  • The default port number for PostgreSQL is 5432.
  • The port can be changed:
    • During installation
    • By editing the postgresql.conf configuration file
  • After changing the port, the PostgreSQL service must be restarted.

Process Architecture

Postmaster Process

TheΒ PostmasterΒ is theΒ first processΒ that starts when PostgreSQL starts. It plays a central role in managing the entire PostgreSQL instance. Key responsibilities:
  • Acts as aΒ supervisorΒ β€” monitors all other processes and restarts them if they crash or stop.
  • ListensΒ for new connection requests from clients on portΒ 5432.
  • HandlesΒ authentication and authorizationΒ β€” checks the user's credentials and IP address against the configuration files, and verifies whether the user has permission to access the requested database.
  • For each new client connection, it creates a new dedicated process called aΒ backend process (Postgres).
To check the status of Postmaster and other PostgreSQL processes:
[postgres@pgdb02 ~]$ ps -ef | grep postgres
root        4366    3019  0 20:50 pts/0    00:00:00 su - postgres
postgres    4367    4366  0 20:50 pts/0    00:00:00 -bash
postgres 4559 1 0 21:32 ? 00:00:00 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data
postgres    4560    4559  0 21:32 ?        00:00:00 postgres: logger
postgres    4561    4559  0 21:32 ?        00:00:00 postgres: checkpointer
postgres    4562    4559  0 21:32 ?        00:00:00 postgres: background writer
postgres    4564    4559  0 21:32 ?        00:00:00 postgres: walwriter
postgres    4565    4559  0 21:32 ?        00:00:00 postgres: autovacuum launcher
postgres    4566    4559  0 21:32 ?        00:00:00 postgres: logical replication launcher
postgres    4568    4367  0 21:33 pts/0    00:00:00 ps -ef
postgres    4569    4367  0 21:33 pts/0    00:00:00 grep --color=auto postgres
[postgres@pgdb02 ~]$
[postgres@pgdb02 ~]$ pstree -p 4559
postgres(4559)─┬─postgres(4560) ----- postgres: logger
               β”œβ”€postgres(4561) ----- postgres: checkpointer
               β”œβ”€postgres(4562) ----- postgres: background writer
               β”œβ”€postgres(4564) ----- postgres: walwriter
               β”œβ”€postgres(4565) ----- postgres: autovacuum launcher
               └─postgres(4566) ----- postgres: logical replication launcher
[postgres@pgdb02 ~]$

Dedicated Backend Process

When a client connects to PostgreSQL, the Postmaster creates aΒ dedicated backend processΒ for that connection. Key points:
  • There isΒ one backend process per client connection.
  • The backend process handles theΒ full lifecycleΒ of a session:
    • Parses the SQL query
    • Creates an execution plan
    • Executes the query
    • Returns results to the client
  • It can accessΒ shared memoryΒ but also has itsΒ own private memory.
  • The processΒ ends automaticallyΒ when the client disconnects.

PostgreSQL Background Processes

PostgreSQL runs several background processes to manage data, memory, logging, and maintenance.

1. Background Writer (bgwriter)

What it does: The Background Writer continuously writesΒ dirty buffersΒ (modified data pages in shared memory) to the actualΒ data files on disk. When it is triggered:
  • RunsΒ continuouslyΒ in the background.
  • Wakes up everyΒ bgwriter_delayΒ milliseconds (default:Β 200ms).
  • Gradually writes dirty pages to avoid sudden heavy disk activity.
  • Works ahead of time so that backend processes do not have to write data themselves.
  • At Checkpoint
Why it is needed:
  • Prevents sudden spikes in disk I/O.
  • Reduces delays for user queries.
  • Keeps free buffers available in shared memory for new data.

2. WAL Writer

What it does: WritesΒ WAL (Write-Ahead Log)Β records from WAL buffers in memory toΒ WAL files on disk. When it is triggered:
  • RunsΒ continuouslyΒ in the background.
  • Wakes up everyΒ wal_writer_delayΒ (default:Β 200ms).
  • Also triggered immediately when:
    • A transaction isΒ committed.
    • WAL buffers becomeΒ full.
    • A backend process forces aΒ WAL flushΒ for durability.
Why it is needed:
  • EnsuresΒ transaction durability.
  • WAL data must be safely written to disk before a commit is confirmed.
  • Follows the rule:Β "Write WAL first, then write data files."
CREATE TABLE wal_demo (
    id      SERIAL PRIMARY KEY,
    fname   TEXT
);

SHOW synchronous_commit;

SELECT pg_current_wal_lsn(), pg_walfile_name(pg_current_wal_lsn());



BEGIN;

INSERT INTO wal_demo (fname) VALUES ('RAJASEKHAR AMUDALA');


SELECT * FROM wal_demo;


SELECT pg_current_wal_lsn(), pg_walfile_name(pg_current_wal_lsn());

-- SELECT pg_switch_wal();


-- Open 2nd terminal 
strings walfile | grep -i "RAJASEKHAR"


-- Come back to the first terminal 

ROLLBACK;
SELECT * FROM wal_demo;


BEGIN;
INSERT INTO wal_demo (fname) VALUES ('RAJASEKHAR AMUDALA - COMMITTED COPY');
COMMIT;

SELECT pg_current_wal_lsn(), pg_walfile_name(pg_current_wal_lsn());

SELECT * FROM wal_demo;


strings  | grep -i "RAJASEKHAR"
xxd walfile | grep -i -B2 -A2 "raja"

3. Checkpointer

What it does: The Checkpointer performs the following steps to create a safe recovery point:
  1. Writes dirty pages to disk – All modified data pages (dirty buffers) in the shared buffer area are written to the data files on disk.
  2. Creates a checkpoint record in WAL – A special checkpoint record is written to the Write-Ahead Log (WAL).
  3. Updates the control file – The control file (pg_control) is updated with the location (theΒ LSN – Log Sequence Number) of the new checkpoint record.
This marks aΒ safe and consistent recovery point. If the database crashes, PostgreSQL reads the control file to find the last checkpoint, then replays the WAL from that point to recover all committed data. When it is triggered:
Checkpoint TriggerDescription
Time-basedAutomatically triggered every checkpoint_timeout (default: 5 minutes).
WAL Size LimitTriggered when the total WAL generated exceeds max_wal_size, allowing PostgreSQL to control WAL growth.
Manual CheckpointA DBA manually initiates a checkpoint using: CHECKPOINT;
Smart / Fast ShutdownDuring a normal server shutdown, PostgreSQL performs a checkpoint to ensure that all dirty buffers are written to disk, reducing recovery time during the next startup.
Immediate ShutdownNo checkpoint is performed. The server terminates immediately, requiring crash recovery during the next startup.
pg_basebackupBy default, pg_basebackup requests the primary server to perform a checkpoint before copying data files, ensuring a consistent physical backup. Checkpoint behavior can be controlled using: --checkpoint=fast - Completes as quickly as possible or --checkpoint=spread (Default) - Spreads writes over checkpoint_completion_target
Crash RecoveryAfter replaying all required WAL records following an unexpected shutdown, PostgreSQL automatically writes a new checkpoint before accepting client connections.
Point-in-Time Recovery (PITR)After recovery reaches the requested recovery target, PostgreSQL performs a checkpoint before opening the database for normal operation.
Standby PromotionWhen a standby server is promoted to become the new primary, PostgreSQL performs a checkpoint to establish a new recovery starting point.
Why it is needed:
  • ReducesΒ crash recovery time.
  • Ensures all committed data is safely written to disk.
  • Creates a known safe recovery point for the database.

4. Autovacuum

What it does:
  • RemovesΒ dead rowsΒ left behind by UPDATE and DELETE operations.
  • PreventsΒ table bloatΒ (tables growing unnecessarily large).
  • UpdatesΒ table statisticsΒ used by the query planner.
  • Freezes old transaction IDsΒ to prevent transaction ID wraparound.
When it is triggered: Autovacuum runs automatically when:
  • The number of dead rows in a table exceeds:
autovacuum_vacuum_threshold + (autovacuum_vacuum_scale_factor Γ— table_size)
  • A table needsΒ statistics update (ANALYZE).
  • To protect againstΒ transaction ID (XID) wraparoundΒ β€” a critical condition that can cause data corruption.
Why it is needed:
  • PostgreSQL usesΒ MVCC (Multi-Version Concurrency Control), which creates multiple versions of rows during updates and deletes.
  • Old row versions must be regularly cleaned up.
  • PreventsΒ database corruptionΒ from XID wraparound.

5.Β  Logger

What it does:
  • WritesΒ server messagesΒ and events to log files.
  • Logs include:
    • Errors and warnings
    • Checkpoint events
    • Connection and disconnection events
    • Slow queries (if enabled)
When it is triggered:
  • Triggered whenever aΒ loggable eventΒ occurs.
  • Controlled by configuration parameters:
    • log_min_messagesΒ β€” sets the minimum message level to log
    • log_min_duration_statementΒ β€” logs queries that take longer than a set time
    • logging_collectorΒ β€” enables or disables log collection
Why it is needed:
  • MonitoringΒ β€” tracks database activity
  • TroubleshootingΒ β€” helps find and fix errors
  • AuditingΒ β€” keeps a record of events for security and compliance

6. Archiver (Optional)

What it does: Copies completedΒ WAL segment filesΒ to a specified archive location for backup and recovery. When it is triggered:
  • Only active whenΒ archive_mode = onΒ inΒ postgresql.conf.
  • Triggered when aΒ WAL segment is completed.
  • Uses theΒ archive_commandΒ to copy the file to the archive location.
Example configuration:
archive_command = 'cp %p /archive/%f'
Why it is needed:
  • EnablesΒ Point-In-Time Recovery (PITR)Β β€” restoring the database to any specific moment.
  • Essential for aΒ continuous backup strategy.
  • Protects againstΒ data lossΒ in case of failure.

7. Stats Collector (Available till PostgreSQL v14 and older )

Note:Β In newer versions of PostgreSQL, statistics are stored directly inΒ shared memoryΒ instead of using a separate collector process.
What it does:
  • Collects statistics about:
    • Table usage
    • Index usage
    • Row counts
    • Query activity
  • Updates system catalog tables (pg_catalog).
When it is triggered:
  • RunsΒ continuously.
  • Updates statistics when:
    • Queries are executed
    • Tables are scanned
    • Rows are inserted, updated, or deleted
  • Information becomes visible after the query completes.
Why it is needed:
  • Helps theΒ Query PlannerΒ choose the best and most efficient execution plan.
  • Improves overall databaseΒ performance.

Background Process Summary

PostgreSQL ProcessWhen It Is Triggered
BgwriterRuns continuously (every bgwriter_delay)
WAL WriterEvery wal_writer_delay, on commit, or WAL buffer full
Checkpointer5 min interval, WAL limit reached, manual checkpoint, shutdown
AutovacuumDead row threshold, stats update, XID protection
Stats CollectorCollects query statistics (till PostgreSQL v14)
LoggerWhen a loggable event occurs
ArchiverWhen WAL segment completes (archive_mode ON)

Memory Architecture

PostgreSQL uses several memory areas to manage data efficiently.

Main Memory Areas

  • Shared Buffers
  • WAL Buffers
  • CLOG Buffers
  • Work Memory
  • Maintenance Work Memory
  • Temp Buffers

Shared Buffers

  • UsersΒ cannot directlyΒ read or write data files on disk.
  • All database operations (SELECT, INSERT, UPDATE, DELETE) go through theΒ shared buffer area.
  • When data is modified in memory, it is calledΒ dirty data.
  • Dirty data is later written to disk by theΒ Background WriterΒ process.
  • Parameter:Β shared_buffersΒ inΒ postgresql.conf
  • Default:Β 128 MB (can be increased based on system needs)

WAL Buffers (Write-Ahead Log Buffers)

  • Also calledΒ transaction log buffers.
  • WAL storesΒ metadata about changesΒ (not the actual data).
  • This metadata is enough toΒ rebuild dataΒ during crash recovery.
  • WAL data is written to physical files on disk calledΒ WAL segments.
  • Written from memory to disk by theΒ WAL WriterΒ process.
  • Parameter:Β wal_buffersΒ inΒ postgresql.conf
  • Default:Β -1Β (PostgreSQL automatically sets the size)

CLOG Buffers (Commit Log Buffers)

  • CLOGΒ stands forΒ Commit Log.
  • Stores theΒ commit statusΒ of every transaction.
  • Indicates whether a transaction has beenΒ committed or not.
  • CLOG buffers are kept inΒ system memory (RAM).

Work Memory

  • Used forΒ sorting and hash operationsΒ during query execution.
  • Examples: Queries withΒ ORDER BY,Β DISTINCT, hash joins, and merge joins.
  • AllocatedΒ per operation, not per user or database.
  • Parameter:Β work_memΒ inΒ postgresql.conf
  • Default:Β 4 MB

Maintenance Work Memory

  • Reserved forΒ maintenance operationsΒ such as:
    • VACUUM
    • Index rebuild
    • ANALYZE
  • Parameter:Β maintenance_work_memΒ inΒ postgresql.conf
  • Default:Β 64 MB (or system-defined)

Temp Buffers

  • Used for accessingΒ temporary tablesΒ during a user session.
  • Also used duringΒ large sort and hash operations.
  • Parameter:Β temp_buffersΒ inΒ postgresql.conf
  • Default:Β 8 MB

Physical Files in PostgreSQL

PostgreSQL stores data and logs in several types of physical files on disk.

Data Files

  • Store theΒ actual database dataΒ β€” tables, indexes, and other objects.
  • DoΒ notΒ contain any code or executable instructions.
  • These are the core storage files of the database.

WAL Files (Write-Ahead Log Files)

  • StoreΒ committed transaction recordsΒ before they are written to data files.
  • EnsuresΒ data safetyΒ β€” if the server crashes, WAL files are used to recover unsaved data.
  • Follows the rule:Β "Write the log first, then write the data."

Log Files

  • Store allΒ server messages and events.
  • Types of log output:
    • stderrΒ β€” Error messages
    • csvlogΒ β€” Logs in CSV format (easy to import and analyze)
    • syslogΒ β€” System-level log messages
  • Useful forΒ debugging, monitoring, and troubleshooting.

Archive Logs (Optional)

  • WhenΒ archive mode is enabled, completed WAL files are copied to a separateΒ archive directory.
  • Used forΒ backup and point-in-time recovery.
  • Allows restoring the database toΒ any specific point in time.
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

PostgreSQL DBA Interview Questions

1. PostgreSQL DBA Beginner LevelΒ  Interview QuestionsΒ 

2. PostgreSQL DBA IntermediateΒ  Level Interview QuestionsΒ 

3. PostgreSQL DBA Advanced Level Β Interview QuestionsΒ 

PostgreSQL Advanced DBA Interview Questions

PostgreSQL Advanced DBA Interview Questions – 25 Expert Q&A | Bright DBA
●●● Advanced Level
25
Interview Preparation Series Β· Part 3 of 3

PostgreSQL
Advanced
DBA Interview

Expert-level questions covering query planner internals, JIT compilation, logical decoding & CDC, Citus sharding, custom extensions, WAL internals, parallel query, and Oracle-to-PostgreSQL migration strategy.

25Questions
7Categories
●●●Expert Level
v17PostgreSQL
Planner Internals JIT Compilation Logical Decoding / CDC Citus Sharding Parallel Query WAL Internals Custom Extensions Oracle β†’ PostgreSQL Migration pg_stat_activity Deep Dive Write Amplification
01
Query Planner & Execution Engine
Planner internals, cost model, JIT, parallel query, statistics
Q01 – Q05
01/ 25
How does the PostgreSQL query planner work internally? Walk through the stages from SQL text to execution plan.
Planner+

The PostgreSQL query planner uses a cost-based optimizer (CBO). It processes a query through five stages:

  • Parse β€” SQL text β†’ parse tree (syntax check via gram.y). Produces an abstract syntax tree.
  • Analyze/Rewrite β€” Semantic validation, name resolution, rule rewriting (views expand here). Produces a query tree.
  • Plan/Optimize β€” Generates candidate execution plans, estimates their cost using pg_statistic data, selects the cheapest plan.
  • Execute β€” The executor walks the plan tree, calling each node's Init/Next/End functions.

The planner estimates cost using three components: seq_page_cost, random_page_cost, and cpu_tuple_cost. Row count estimates come from pg_statistic (populated by ANALYZE). The planner uses a dynamic programming algorithm for join ordering up to join_collapse_limit tables; beyond that it switches to a genetic algorithm (GEQO).

SQL β€” Inspect Planner Internals
-- See full plan with cost breakdown
EXPLAIN (ANALYZE, BUFFERS, SETTINGS, WAL, FORMAT JSON)
SELECT * FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE o.status = 'ACTIVE';

-- Tune planner cost constants
SET random_page_cost = 1.1;   -- SSD (default 4.0 for HDD)
SET seq_page_cost    = 1.0;   -- default
SET cpu_tuple_cost   = 0.01;  -- default

-- Check statistics on a column
SELECT * FROM pg_statistic
WHERE starelid = 'orders'::regclass;
Oracle DBA Note
PostgreSQL's CBO β‰ˆ Oracle's CBO (introduced in Oracle 7). Key difference: PostgreSQL does not have SQL profiles, SQL plan baselines, or adaptive query optimization natively. Use pg_hint_plan extension for query hints.
02/ 25
What is JIT compilation in PostgreSQL and when does it help (or hurt) performance?
JIT+

JIT (Just-In-Time) compilation uses LLVM to compile portions of an execution plan into native machine code at query runtime, rather than interpreting them through PostgreSQL's generic executor. It was introduced in PostgreSQL 11.

  • What gets JIT-compiled: expression evaluation, tuple deforming, aggregate functions, projections.
  • When it helps: CPU-intensive analytical queries with complex WHERE clauses, large aggregations, or many columns β€” typically OLAP workloads.
  • When it hurts: OLTP queries with low row counts. JIT compilation has ~20–100ms overhead. For short queries this overhead exceeds any gain.
SQL β€” JIT Configuration
-- Check if JIT is enabled
SHOW jit;
SHOW jit_above_cost;         -- default: 100000
SHOW jit_inline_above_cost;  -- default: 500000
SHOW jit_optimize_above_cost;-- default: 500000

-- Disable JIT for OLTP workloads (set in postgresql.conf)
jit = off

-- Check if JIT was used in a plan
EXPLAIN (ANALYZE, FORMAT TEXT)
SELECT SUM(amount * discount * tax_rate)
FROM orders WHERE year = 2025;
-- Look for: JIT: Functions: N, Options: Inlining true...
⚠ Tuning Tip
If your OLTP workload is slower after upgrading to PostgreSQL 11+, check if JIT is being triggered on short queries. The fix: raise jit_above_cost or disable JIT globally and enable it only for specific analytical sessions.
03/ 25
Explain parallel query in PostgreSQL β€” how does it work and what are its limitations?
Parallel+

PostgreSQL can execute certain queries using multiple CPU cores via parallel workers (background processes). The leader process divides work among parallel workers using Parallel Seq Scan, Parallel Index Scan, Parallel Hash Join, and Parallel Aggregate.

postgresql.conf β€” Parallel Query Settings
max_parallel_workers              = 8   # total parallel workers
max_parallel_workers_per_gather   = 4   # per query
max_parallel_maintenance_workers  = 4   # for CREATE INDEX
parallel_setup_cost               = 1000
parallel_tuple_cost               = 0.1
min_parallel_table_scan_size      = '8MB'

-- Force parallel for testing
SET max_parallel_workers_per_gather = 4;
SET parallel_setup_cost = 0;
EXPLAIN ANALYZE SELECT COUNT(*) FROM large_table;

Limitations:

  • Parallel query is NOT used inside transactions with SERIALIZABLE isolation level.
  • Queries with FOR UPDATE/SHARE, CURSOR, or LIMIT (in some cases) don't parallelize.
  • Functions marked PARALLEL UNSAFE (default for user functions) prevent parallelism.
  • Small tables: the planner's parallel_setup_cost threshold prevents parallel overhead on tiny scans.
  • Worker spawning has overhead β€” not beneficial for queries under ~100ms.
04/ 25
What are extended statistics in PostgreSQL and when do you need them?
Planner+

By default, PostgreSQL collects statistics on each column independently. When columns are correlated (e.g., city + zip_code), the planner severely underestimates row counts for multi-column predicates. Extended statistics capture cross-column correlations.

SQL
-- Problem: city and zip_code are correlated
-- Planner underestimates: rows = 5 (actual: 500)
EXPLAIN ANALYZE SELECT * FROM addresses
WHERE city = 'London' AND zip_code = 'EC1A';

-- Solution: create extended statistics on correlated columns
CREATE STATISTICS stat_city_zip (dependencies)
    ON city, zip_code FROM addresses;

ANALYZE addresses;

-- Now rerun EXPLAIN β€” row estimate dramatically improves

-- Types of extended statistics:
-- dependencies: functional dependency (A determines B)
-- ndistinct: number of distinct value combinations
-- mcv: most common value combinations (PostgreSQL 12+)
CREATE STATISTICS stat_full (dependencies, ndistinct, mcv)
    ON city, state, zip_code FROM addresses;
Oracle DBA Note
Extended statistics β‰ˆ Oracle's column group statistics. In Oracle: DBMS_STATS.CREATE_EXTENDED_STATS. In PostgreSQL: CREATE STATISTICS. Both solve the same correlated-column row estimation problem.
05/ 25
What is the difference between Hash Join, Nested Loop, and Merge Join? When does PostgreSQL choose each?
Planner+
Join TypeAlgorithmMemoryBest When
Nested LoopFor each outer row, scan inner table/indexLowSmall inner table, index available on join key, OLTP
Hash JoinBuild hash table from smaller relation, probe with largerHigh (work_mem)Large tables, no useful index, OLAP aggregations
Merge JoinSort both sides, merge-scan sorted resultsMedium (sort memory)Both sides already sorted or have btree index on join key
SQL β€” Force / Diagnose Join Types
-- Diagnose which join is being chosen
EXPLAIN (ANALYZE, FORMAT TEXT)
SELECT * FROM orders o JOIN customers c ON o.cid = c.id;

-- Force specific join types for testing
SET enable_hashjoin     = off;
SET enable_nestloop     = off;
SET enable_mergejoin    = off;

-- Hash join spills to disk if work_mem is too low
-- Look for: Batches: N (if N > 1, it spilled to disk)
SET work_mem = '256MB'; -- raise per session for large joins
⚠ Expert Tip
When you see Hash Batches: 8 in EXPLAIN output, the hash join spilled to disk 8 times. Increasing work_mem for that session can collapse it to 1 batch (in-memory) and cut the query time dramatically.
02
WAL Internals & Checkpoints
WAL format, LSN, checkpoints, write amplification, WAL compression
Q06 – Q09
06/ 25
Explain the internal structure of a WAL record and how LSN (Log Sequence Number) works.
WAL+

Every change in PostgreSQL generates a WAL record β€” a binary log entry describing exactly what changed. WAL records are appended sequentially to WAL segment files (16MB each by default).

A WAL record contains: header (total length, resource manager ID, CRC32), data (the actual change: block number, offset, new data), and optionally a full-page image (FPI) β€” a complete copy of the 8KB block written on the first modification after a checkpoint.

  • LSN (Log Sequence Number) β€” A 64-bit byte offset into the WAL stream. Format: 0/A1B2C3D4. Monotonically increasing. Used to identify a precise WAL position for replication lag, PITR, and crash recovery.
  • Full-Page Images (FPI) β€” Written to survive partial write scenarios (torn pages). Controlled by full_page_writes = on (default). This is the main driver of WAL write amplification.
  • WAL compression β€” wal_compression = on compresses FPIs with LZ4/zstd, dramatically reducing WAL volume with minimal CPU overhead.
SQL β€” WAL Inspection
-- Current WAL write position (LSN)
SELECT pg_current_wal_lsn();

-- WAL generated between two points (bytes)
SELECT pg_wal_lsn_diff(
    pg_current_wal_lsn(),
    '0/A1B2C3D4'
);

-- Decode WAL records (pg_walinspect extension - PG 14+)
CREATE EXTENSION pg_walinspect;
SELECT * FROM pg_get_wal_records_info(
    '0/A1000000', '0/A2000000'
) LIMIT 20;

-- Check WAL statistics
SELECT * FROM pg_stat_wal;
Oracle DBA Note
WAL LSN β‰ˆ Oracle SCN (System Change Number). Both are monotonically increasing numbers identifying a precise point in the redo log stream. WAL segment files β‰ˆ Oracle online redo log members.
07/ 25
What is write amplification in PostgreSQL and how do you diagnose and reduce it?
WAL+

Write amplification is when PostgreSQL writes significantly more data to disk than the logical data change size. The primary sources are full-page images (FPIs) in WAL and autovacuum rewrites.

  • FPI amplification: After every checkpoint, the first write to each page generates a full 8KB FPI in WAL β€” even if only 10 bytes changed. A table doing many random updates can generate 100x WAL volume vs actual data changes.
  • Heap amplification: MVCC means every UPDATE writes a new row version β€” the old version stays until vacuumed. High-update tables swell in size.
  • Index amplification: Every row version change requires an index entry update. Partial indexes and HOT (Heap-Only Tuple) updates help.
SQL + Config β€” Diagnose & Reduce
-- Measure WAL generation rate per statement
EXPLAIN (ANALYZE, WAL) UPDATE orders
SET status = 'CLOSED' WHERE id = 42;
-- Output shows: WAL Records: N, WAL Bytes: N

-- Reduce write amplification
-- 1. Enable WAL compression (huge win for FPIs)
wal_compression = lz4       # or zstd (PG 15+)

-- 2. Increase checkpoint_timeout (fewer FPI triggers)
checkpoint_timeout = '30min'

-- 3. Use HOT updates (no index key change needed)
-- HOT = Heap Only Tuple: no index update needed
-- Requires: update only non-indexed columns
--           sufficient fillfactor on table
ALTER TABLE orders SET (fillfactor = 80);
08/ 25
What happens during a PostgreSQL checkpoint and how do you tune checkpoint behavior?
WAL+

A checkpoint is a point where PostgreSQL guarantees all dirty (modified) shared_buffer pages have been flushed to disk. After a crash, recovery only needs to replay WAL from the last checkpoint β€” reducing recovery time.

  • Triggers: checkpoint_timeout elapsed, max_wal_size exceeded, or explicit CHECKPOINT command.
  • The checkpointer process writes dirty pages spread across the checkpoint window β€” controlled by checkpoint_completion_target.
  • Checkpoints cause I/O spikes if they complete too quickly. Setting checkpoint_completion_target = 0.9 spreads the writes over 90% of the checkpoint interval.
postgresql.conf β€” Checkpoint Tuning
checkpoint_timeout           = '15min'  # default 5min β€” longer = less WAL
max_wal_size                 = '4GB'    # default 1GB
min_wal_size                 = '1GB'
checkpoint_completion_target = 0.9     # spread I/O over 90% of interval

-- Monitor checkpoint frequency
SELECT checkpoints_timed, checkpoints_req,
       buffers_checkpoint, buffers_clean,
       round(buffers_checkpoint /
           NULLIF(checkpoints_timed + checkpoints_req, 0)) AS avg_bufs
FROM pg_stat_bgwriter;
-- High checkpoints_req = max_wal_size too small
⚠ Key Signal
If checkpoints_req is much higher than checkpoints_timed, your max_wal_size is too small and checkpoints are being forced by WAL volume, not by time. Increase max_wal_size.
09/ 25
What is the difference between synchronous_commit = on/off/remote_write/remote_apply?
WAL+

synchronous_commit controls when PostgreSQL considers a transaction committed relative to WAL durability. It is a per-transaction setting β€” no restart required.

ValueWAL Written to DiskStandby ReceivedStandby AppliedRisk
on (default)βœ… Before COMMIT returnsβ€”β€”None (fully durable)
off❌ Async (up to 3x wal_writer_delay later)β€”β€”Last ~600Β΅s of commits on crash
remote_writeβœ…βœ… Written to OS bufferβ€”Small: standby OS crash
remote_applyβœ…βœ…βœ… Applied to standbyNone β€” reads from standby guaranteed fresh
localβœ… Primary onlyβ€”β€”Standby may lag
⚑
Expert Usage
synchronous_commit = off is safe for non-critical workloads (logging, analytics inserts) and can give 3–10x write throughput improvement with only a very small durability window. The database will never corrupt β€” you only risk losing the last ~600Β΅s of commits on a hard crash.
03
Logical Decoding & Change Data Capture
Decoding plugins, Debezium, wal2json, replication slots, CDC pipelines
Q10 – Q12
10/ 25
What is logical decoding in PostgreSQL and how is it used for CDC pipelines?
CDC+

Logical decoding interprets WAL records and emits them as a logical stream of row-level changes (INSERT/UPDATE/DELETE) using a pluggable output plugin. This powers Change Data Capture (CDC) without application code changes.

  • Output plugins: pgoutput (built-in, used by logical replication), wal2json (JSON output), test_decoding (text, for debugging).
  • Requires wal_level = logical and a logical replication slot to track consumer position.
  • Debezium is the most popular CDC framework β€” it connects to PostgreSQL's logical decoding API and streams changes to Kafka.
SQL β€” Logical Decoding Manually
-- Create a logical decoding slot with wal2json
SELECT pg_create_logical_replication_slot(
    'my_cdc_slot', 'wal2json'
);

-- Peek at changes (non-consuming)
SELECT * FROM pg_logical_slot_peek_changes(
    'my_cdc_slot', NULL, NULL
);

-- Consume changes (advances slot position)
SELECT * FROM pg_logical_slot_get_changes(
    'my_cdc_slot', NULL, NULL,
    'pretty-print', '1'
);

-- Always monitor slot lag!
SELECT slot_name, active,
    pg_size_pretty(pg_wal_lsn_diff(
        pg_current_wal_lsn(), confirmed_flush_lsn)) AS lag
FROM pg_replication_slots;
Oracle DBA Note
PostgreSQL logical decoding β‰ˆ Oracle LogMiner + GoldenGate extract. Debezium/Kafka pipeline β‰ˆ Oracle GoldenGate replicat to Kafka. Key advantage: PostgreSQL's built-in logical decoding is free; Oracle LogMiner is built-in but GoldenGate requires expensive licensing.
11/ 25
How do you build a CDC pipeline from PostgreSQL to a data warehouse using Debezium?
CDC+

A production CDC pipeline from PostgreSQL to a data warehouse (Snowflake, BigQuery, Redshift) typically uses: PostgreSQL β†’ Debezium β†’ Apache Kafka β†’ Kafka Connect sink.

  • Step 1 β€” PostgreSQL config: Set wal_level = logical, create a dedicated replication user, add pg_hba.conf entry.
  • Step 2 β€” Debezium PostgreSQL connector: Creates a replication slot (pgoutput plugin), reads WAL changes, publishes to Kafka topics per table.
  • Step 3 β€” Kafka topics: Each table gets a topic (e.g., pg.public.orders). Payload contains before/after row images in Avro or JSON.
  • Step 4 β€” Sink connector: Kafka Connect sink writes to target (Snowflake Kafka Connector, BigQuery Connector).
JSON β€” Debezium Connector Config
{
  "connector.class": "io.debezium.connector.postgresql.PostgresConnector",
  "database.hostname": "192.168.1.51",
  "database.port": "5432",
  "database.user": "repl_user",
  "database.password": "secret",
  "database.dbname": "mydb",
  "database.server.name": "pg",
  "plugin.name": "pgoutput",
  "slot.name": "debezium_slot",
  "publication.name": "dbz_publication",
  "table.include.list": "public.orders,public.customers",
  "snapshot.mode": "initial"
}
⚠ Operational Risk
The Debezium replication slot MUST be monitored. If Kafka is down for an extended period, the slot accumulates WAL indefinitely. Set max_slot_wal_keep_size = 10GB as a safety valve β€” but note: if exceeded, the slot is invalidated and you must re-snapshot.
12/ 25
What is REPLICA IDENTITY in PostgreSQL and why is it critical for logical replication?
CDC+

REPLICA IDENTITY controls what column data is included in the WAL record for UPDATE and DELETE operations. Without sufficient identity columns, subscribers cannot identify which row to update or delete.

SettingOLD Row Data in WALUse When
DEFAULTPrimary key columns onlyTable has a primary key (recommended)
FULLAll columns (before image)No PK β€” but doubles WAL volume!
NOTHINGNoneOnly INSERT replication needed
USING INDEXSpecified unique index columnsNo PK but has unique index
SQL
-- Check current replica identity
SELECT relname, relreplident
FROM pg_class WHERE relname = 'orders';
-- d=DEFAULT, f=FULL, n=NOTHING, i=INDEX

-- Set FULL for tables without PK (CDC requirement)
ALTER TABLE orders_legacy REPLICA IDENTITY FULL;

-- Use index instead (less WAL overhead than FULL)
ALTER TABLE orders REPLICA IDENTITY USING INDEX idx_orders_uuid;
04
Citus & Horizontal Sharding
Distributed PostgreSQL, shard placement, colocation, distributed queries
Q13 – Q15
13/ 25
How does Citus extend PostgreSQL for horizontal sharding? Explain the architecture.
Citus+

Citus is a PostgreSQL extension (now open-source by Microsoft) that transforms a single PostgreSQL instance into a distributed database by adding a coordinator node and multiple worker nodes.

  • Coordinator node: Receives all queries. Parses and plans them. Routes shard-specific parts to workers. Merges results.
  • Worker nodes: Each holds a subset of shards. Executes pushed-down query fragments in parallel.
  • Distribution column: A column used to hash rows across shards. Choose carefully β€” cross-shard JOINs are expensive.
  • Shard count: Default 32 shards per table. Shards are regular PostgreSQL tables on workers.
SQL β€” Citus Setup
-- On coordinator: add worker nodes
SELECT citus_add_node('worker1', 5432);
SELECT citus_add_node('worker2', 5432);

-- Distribute a table by tenant_id
SELECT create_distributed_table('orders', 'tenant_id');

-- Colocate related tables (JOIN-friendly)
SELECT create_distributed_table('order_items', 'tenant_id',
    colocate_with := 'orders');

-- Reference table (replicated to all workers)
SELECT create_reference_table('countries');

-- Check shard placement
SELECT * FROM citus_shards;
SELECT * FROM pg_dist_placement;
⚑
Expert Tip
Choose the distribution column carefully β€” it should be the most common JOIN key in your queries. For multi-tenant SaaS apps, tenant_id is ideal: all tenant data goes to the same shard, enabling efficient local JOINs without cross-node network hops.
14/ 25
What is table colocation in Citus and why is it important for query performance?
Citus+

Table colocation ensures that related tables (e.g., orders and order_items) that share the same distribution key have their corresponding shards placed on the same worker node. This allows JOINs between them to be executed locally on each worker β€” no network hops between workers.

SQL
-- Without colocation: JOIN requires cross-node data transfer
-- With colocation: JOIN runs locally on each worker (parallel)

SELECT create_distributed_table('orders',      'tenant_id');
SELECT create_distributed_table('order_items', 'tenant_id',
    colocate_with := 'orders');

-- This JOIN now executes locally on workers (fast)
SELECT o.id, SUM(oi.amount)
FROM orders o
JOIN order_items oi ON o.id = oi.order_id
  AND o.tenant_id = oi.tenant_id
WHERE o.tenant_id = 42
GROUP BY o.id;

-- Verify colocation group assignment
SELECT logicalrelid, colocationid
FROM pg_dist_partition
WHERE logicalrelid::text IN ('orders', 'order_items');
15/ 25
What are the limitations of Citus that a senior DBA must know before adopting it?
Citus+
  • No cross-shard transactions with full ACID: Multi-shard writes use 2-phase commit (2PC) which is slower and can leave transactions in an uncertain state if coordinator crashes.
  • Changing distribution column: Once a table is distributed, you cannot easily change the distribution column without redistributing all data.
  • Cross-shard JOINs on non-distribution key: If you JOIN on a column other than the distribution key, Citus must repartition data on the fly β€” expensive and slow.
  • Sequences: Citus uses sharded sequences that may produce gaps. Standard SERIAL sequences may not be globally unique across workers.
  • DDL limitations: Some DDL operations require quorum across all nodes. Schema changes must be applied carefully.
  • Aggregation pushdown: Only certain aggregates (SUM, COUNT, AVG, MIN, MAX) can be pushed down. Complex aggregates may pull data to coordinator.
⚠ Adoption Advice
Citus is an excellent choice for multi-tenant SaaS and time-series analytics at scale. However, it is a significant architectural commitment. Evaluate whether PostgreSQL native partitioning + read replicas solves your problem first β€” it often does up to several TBs with less complexity.
05
Custom Extensions & Deep Monitoring
Writing extensions, pg_stat_activity internals, wait events, bgworkers
Q16 – Q19
16/ 25
What are PostgreSQL background workers and how are they used in custom extensions?
Extensions+

Background workers (BGW) are custom processes that run inside the PostgreSQL server process tree β€” started at server startup or dynamically. They are used by extensions to run periodic tasks, listen to events, or implement custom replication.

  • pg_cron β€” Uses a BGW to wake up every minute and check the cron schedule.
  • pg_logical β€” Uses BGWs per subscription to stream WAL changes.
  • Patroni β€” Not a BGW, but Patroni watches PostgreSQL as an external agent.
  • BGWs run as normal postgres backend processes β€” they can execute SQL, access shared memory, and use background worker APIs.
C β€” Minimal BGW Registration (Extension)
/* In your extension's _PG_init() function */
void _PG_init(void) {
    BackgroundWorker worker;
    MemSet(&worker, 0, sizeof(worker));
    worker.bgw_flags      = BGWORKER_SHMEM_ACCESS |
                            BGWORKER_BACKEND_DATABASE_CONNECTION;
    worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
    worker.bgw_restart_time = 10; /* restart after 10s on crash */
    snprintf(worker.bgw_name, BGW_MAXLEN, "my_extension worker");
    worker.bgw_main_arg  = (Datum) 0;
    RegisterBackgroundWorker(&worker);
}

/* Worker main function: runs in its own process */
void my_worker_main(Datum arg) {
    BackgroundWorkerInitializeConnection("mydb", NULL, 0);
    while (!ShutdownRequestPending()) {
        /* do work every 5 seconds */
        WaitLatch(MyLatch, WL_LATCH_SET | WL_TIMEOUT, 5000, ...);
    }
}
17/ 25
Explain PostgreSQL wait events β€” what are the most important ones and how do you diagnose them?
Monitoring+

Wait events in pg_stat_activity tell you exactly what a session is waiting for β€” the single most important diagnostic tool for PostgreSQL performance problems.

SQL β€” Wait Event Analysis
-- Real-time wait event summary (run repeatedly)
SELECT
    wait_event_type,
    wait_event,
    COUNT(*) AS sessions
FROM pg_stat_activity
WHERE state != 'idle'
GROUP BY wait_event_type, wait_event
ORDER BY sessions DESC;
Wait EventTypeMeaning & Action
Lock:relationLockTable-level lock contention. Find blocker with pg_blocking_pids().
Lock:tupleLockRow-level lock contention. Typical in high-concurrency OLTP.
IO:DataFileReadIOReading data pages from disk. shared_buffers too small or missing indexes.
IO:WALWriteIOWAL writes slow. Check disk I/O, consider wal_compression.
CPUCPUQuery is running. Normal β€” unless it never finishes. Check for full table scans.
Client:ClientReadClientWaiting for client to send next command. Idle connection pooling issue.
Lock:advisoryLockApplication-level advisory lock contention.
LWLock:WALInsertLWLockContention on WAL insertion. Very high write concurrency.
Oracle DBA Note
PostgreSQL wait events β‰ˆ Oracle V$SESSION.WAIT_CLASS + V$SESSION.EVENT. Oracle has hundreds of named wait events; PostgreSQL has a similar taxonomy through wait_event_type + wait_event pairs.
18/ 25
How do you implement sampling-based ASH (Active Session History) equivalent in PostgreSQL?
Monitoring+

PostgreSQL has no built-in ASH equivalent, but you can build one by periodically sampling pg_stat_activity into a history table. Extensions like pg_activity, pgBadger, and Percona Monitoring and Management (PMM) provide this.

SQL β€” Build a Simple ASH Table
-- Create ASH history table
CREATE TABLE ash_history (
    sample_time   TIMESTAMPTZ DEFAULT NOW(),
    pid           INT,
    usename       TEXT,
    datname       TEXT,
    state         TEXT,
    wait_event_type TEXT,
    wait_event    TEXT,
    query         TEXT
);

-- Schedule sampling every 1 second via pg_cron
SELECT cron.schedule('ash-sample', '* * * * *', $$
    INSERT INTO ash_history
    SELECT NOW(), pid, usename, datname, state,
           wait_event_type, wait_event, left(query,200)
    FROM pg_stat_activity
    WHERE state != 'idle' AND pid != pg_backend_pid();
$$);

-- Query ASH: top wait events in last hour
SELECT wait_event_type, wait_event, COUNT(*) AS samples
FROM ash_history
WHERE sample_time > NOW() - interval '1 hour'
GROUP BY 1,2 ORDER BY 3 DESC;
Oracle DBA Note
Oracle ASH samples v$session every 1 second into v$active_session_history (in-memory) and DBA_HIST_ACTIVE_SESS_HISTORY (persisted). This PostgreSQL approach replicates that pattern. Commercial tools like pganalyze provide a polished ASH equivalent.
19/ 25
How do you write a custom PostgreSQL extension in C? What are the key components?
Extensions+

A PostgreSQL extension packages custom SQL objects (functions, types, operators, views) with C or PL/pgSQL code. The minimum files are: a control file, an SQL script, and optionally a C shared library.

Shell / C β€” Minimal Extension Structure
## Directory structure
my_extension/
β”œβ”€β”€ my_extension.control        # extension metadata
β”œβ”€β”€ my_extension--1.0.sql       # SQL definitions
β”œβ”€β”€ my_extension.c              # C implementation
└── Makefile

## my_extension.control
comment   = 'My custom extension'
default_version = '1.0'
relocatable = true
module_pathname = '$libdir/my_extension'

## my_extension--1.0.sql
CREATE FUNCTION my_add(a INT, b INT)
    RETURNS INT
    AS 'MODULE_PATHNAME', 'my_add'
    LANGUAGE C STRICT;

/* my_extension.c */
#include "postgres.h"
#include "fmgr.h"
PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(my_add);
Datum my_add(PG_FUNCTION_ARGS) {
    int32 a = PG_GETARG_INT32(0);
    int32 b = PG_GETARG_INT32(1);
    PG_RETURN_INT32(a + b);
}

## Install
make install
psql -c "CREATE EXTENSION my_extension;"
06
Oracle β†’ PostgreSQL Migration
Key differences, incompatibilities, migration tools, and strategy
Q20 – Q22
20/ 25
What are the most critical incompatibilities between Oracle and PostgreSQL that affect migration?
Migration+
FeatureOraclePostgreSQL Equivalent
Empty string vs NULL'' = NULL (same!)'' β‰  NULL β€” critical behavioural difference
ROWNUM / ROWIDROWNUM, ROWIDLIMIT/OFFSET, ctid (internal, not stable)
PackagesCREATE PACKAGE (state + code)No direct equivalent β€” use schemas + functions
CONNECT BY (hierarchical)CONNECT BY PRIORWITH RECURSIVE (standard SQL)
DECODE / NVLDECODE(), NVL()CASE WHEN, COALESCE()
SequencesNEXTVAL on sequence objectSERIAL / IDENTITY columns or explicit sequences
SYSDATE / SYSTIMESTAMPSYSDATENOW(), CURRENT_TIMESTAMP, CURRENT_DATE
VARCHAR2VARCHAR2(n BYTE/CHAR)VARCHAR(n) β€” always character-based
DUAL tableSELECT 1 FROM DUALSELECT 1 (no FROM needed)
Outer join syntaxWHERE a.id = b.id(+)Standard ANSI: LEFT JOIN ... ON
⚑
Critical Difference
The NULL vs empty string difference is the #1 most commonly missed incompatibility. In Oracle, WHERE col = '' is equivalent to WHERE col IS NULL. In PostgreSQL they are completely different. Applications that store '' in Oracle to mean "no value" will break silently if migrated without code audit.
21/ 25
What tools and approach do you use for a large-scale Oracle to PostgreSQL migration?
Migration+
  • ora2pg β€” Open-source tool that exports Oracle schema, data, and PL/SQL to PostgreSQL-compatible SQL. Best for schema conversion and data export. Handles tables, indexes, sequences, views, functions, triggers.
  • AWS Schema Conversion Tool (SCT) β€” GUI tool, good for assessing migration complexity and converting stored procedures.
  • AWS Database Migration Service (DMS) β€” For ongoing data replication from Oracle to PostgreSQL during cutover period.
  • Striim / GoldenGate β€” For zero-downtime migration using CDC from Oracle to PostgreSQL.
Shell β€” ora2pg Migration Workflow
# Step 1: Assess migration complexity
ora2pg --type SHOW_REPORT --estimate_cost \
    --oracle_dsn "dbi:Oracle:host=ora-server;sid=ORCL"

# Step 2: Export schema only (no data)
ora2pg --type TABLE   -o tables.sql
ora2pg --type INDEX   -o indexes.sql
ora2pg --type PACKAGE -o packages.sql  # converts to PL/pgSQL

# Step 3: Export data in COPY format (fast)
ora2pg --type COPY --table ORDERS \
    -o orders_data.sql

# Step 4: Load into PostgreSQL
psql -d targetdb -f tables.sql
psql -d targetdb -f orders_data.sql
⚠ Strategy Advice
Never do a "big bang" cutover on a large Oracle database. Use CDC (DMS/GoldenGate) to keep PostgreSQL in sync with Oracle for weeks, run full regression testing, then perform a planned maintenance window switchover with minimal downtime.
22/ 25
How do you convert Oracle PL/SQL packages to PostgreSQL? What are the main challenges?
Migration+

Oracle PL/SQL packages (package spec + body with global state) have no direct equivalent in PostgreSQL. The conversion strategy depends on what the package does:

  • Package as namespace: Create a PostgreSQL schema with the package name. Put all functions inside that schema.
  • Package global variables: No equivalent. Use a session-local temporary table, a custom GUC parameter, or pass state explicitly as function parameters.
  • Package initialization code: Use a function called explicitly on session start, or a SET LOCAL in a transaction.
  • EXECUTE IMMEDIATE: Convert to PostgreSQL EXECUTE format(...) in PL/pgSQL.
  • Autonomous transactions: PostgreSQL 14+ has limited support via dblink or the pg_background extension.
PL/pgSQL β€” Package Simulation
-- Oracle package β†’ PostgreSQL schema approach

-- Oracle: CREATE PACKAGE emp_pkg AS ...
-- PostgreSQL equivalent:
CREATE SCHEMA emp_pkg;

CREATE OR REPLACE FUNCTION emp_pkg.get_salary(p_id INT)
RETURNS NUMERIC AS $$
BEGIN
    RETURN (SELECT salary FROM employees WHERE id = p_id);
END;
$$ LANGUAGE plpgsql;

-- Oracle global package variable β†’ custom GUC
-- In C extension: DefineCustomIntVariable('myapp.user_id', ...)
-- Then in PL/pgSQL:
SELECT current_setting('myapp.user_id')::INT;
PERFORM SET_CONFIG('myapp.user_id', 42::text, true);
07
Security, Row-Level Security & Advanced Admin
RLS, pgAudit, SSL, column encryption, security best practices
Q23 – Q25
23/ 25
What is Row-Level Security (RLS) in PostgreSQL and how do you implement a multi-tenant security model with it?
Security+

Row-Level Security (RLS) allows you to define policies that restrict which rows a user can see or modify. The database enforces these policies transparently β€” the application doesn't need to add WHERE clauses.

SQL β€” Multi-Tenant RLS Implementation
-- Step 1: Enable RLS on the table
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- Step 2: Create isolation policy (tenants see only their data)
CREATE POLICY tenant_isolation ON orders
    USING (tenant_id = current_setting('app.current_tenant')::INT);

-- Step 3: Application sets tenant context on connection
SET app.current_tenant = '42';

-- Now tenant 42 only sees their own rows
SELECT * FROM orders;  -- automatically filtered!

-- Step 4: Superusers bypass RLS by default
-- Force RLS even for table owner:
ALTER TABLE orders FORCE ROW LEVEL SECURITY;

-- Separate policies for SELECT vs INSERT vs UPDATE
CREATE POLICY select_policy ON orders FOR SELECT
    USING (tenant_id = current_setting('app.current_tenant')::INT);

CREATE POLICY insert_policy ON orders FOR INSERT
    WITH CHECK (tenant_id = current_setting('app.current_tenant')::INT);
Oracle DBA Note
RLS β‰ˆ Oracle Virtual Private Database (VPD) / Fine-Grained Access Control (FGAC). Oracle VPD requires DBMS_RLS package and applies a predicate dynamically. PostgreSQL RLS is the native equivalent β€” simpler syntax, same security model.
24/ 25
How do you implement database activity auditing in PostgreSQL using pgAudit?
Security+

pgAudit is the standard PostgreSQL extension for detailed audit logging. It extends PostgreSQL's standard log_statement to provide fine-grained control over which operations are logged β€” required for SOX, PCI-DSS, HIPAA compliance.

postgresql.conf + SQL β€” pgAudit Setup
## postgresql.conf
shared_preload_libraries = 'pgaudit'

## Session-level audit (all DDL + DML)
pgaudit.log = 'ddl, write, role'
## Options: read, write, function, role, ddl, misc, all

## Object-level audit (specific tables)
pgaudit.log_level    = log
pgaudit.log_relation = on
pgaudit.log_parameter= on

-- Enable extension
CREATE EXTENSION pgaudit;

-- Audit specific role
ALTER ROLE sensitive_user SET pgaudit.log = 'all';

-- Audit specific table (object-level)
ALTER ROLE auditor SET pgaudit.log = 'read';
-- then grant privileges β€” pgaudit tracks access

-- Log format (in PostgreSQL log file):
-- AUDIT: SESSION,1,1,DDL,CREATE TABLE,,,CREATE TABLE secret_data...
Oracle DBA Note
pgAudit β‰ˆ Oracle Database Vault + Unified Auditing. Oracle's unified auditing is more feature-rich (fine-grained audit conditions, audit vault). pgAudit is simpler but covers all compliance requirements for most use cases.
25/ 25
How would you design a PostgreSQL architecture for a 50TB OLTP database with 99.999% availability requirements?
Architecture+

This is a capstone architecture question. A 50TB OLTP database with five-nines availability (~5 minutes downtime/year) requires layered redundancy across every tier.

  • HA Layer: Patroni cluster (1 primary + 2 synchronous replicas + 1 async replica in DR region). etcd 3-node cluster for leader election. HAProxy + Keepalived for VIP failover. Target RTO: <30 seconds automatic.
  • Synchronous replication: synchronous_standby_names = 'FIRST 1 (replica1, replica2)' β€” RPO = 0 (zero data loss) for primary datacenter failure.
  • Storage: NVMe SSDs with hardware RAID-10 or all-flash SAN. random_page_cost = 1.1, wal_compression = lz4.
  • Connection pooling: PgBouncer tier (2+ instances behind load balancer) in transaction mode. Target: 2000 app connections β†’ 200 PostgreSQL connections.
  • Partitioning: Range-partition large tables by date. Detach old partitions for archival without locking.
  • Backup: pgBackRest with WAL archiving to S3/object storage. Daily base backups, continuous WAL archiving. RPO target: 5 minutes. Monthly restore drills.
  • Monitoring: Prometheus + postgres_exporter + Grafana. Alert on: replication lag >5s, XID age >1.5B, dead tuple ratio >10%, connection usage >80%, checkpoint frequency, WAL retention of replication slots.
  • Maintenance: pg_repack for online bloat removal. REINDEX CONCURRENTLY for index maintenance. Patch upgrades via logical replication-based rolling upgrade.
⚑
Expert Note
99.999% availability means ~5 minutes downtime per year. Patroni automated failover typically takes 10–30 seconds. To achieve five-nines you also need zero-downtime deployments, online schema changes (pg_repack, CREATE INDEX CONCURRENTLY), and a rigorous runbook for all failure modes. Plan for the unexpected: test your failover monthly, not just on paper.

PostgreSQL Intermediate DBA Interview Questions

PostgreSQL Interview Questions for DBAs – 25 Intermediate Q&A | Bright DBA
Interview Preparation Series Β· Part 2

PostgreSQL DBA
Intermediate Interview
Questions & Answers

25 carefully crafted intermediate-level questions covering table partitioning, logical replication, autovacuum tuning, connection pooling, Patroni HA, query optimization, and real-world DBA scenarios.

Partitioning Logical Replication Autovacuum Tuning PgBouncer Patroni HA Query Optimization pg_stat_statements Extensions
25
Questions
6
Categories
●●○
Intermediate
v17
PostgreSQL
01
Partitioning & Storage Architecture
Table partitioning, bloat, TOAST, tablespaces
Q1 – Q5
01Q
What is table partitioning in PostgreSQL? What types are supported?
Partitioning +

Table partitioning divides a large logical table into smaller physical pieces called partitions, while queries still work against the parent table. PostgreSQL has supported declarative partitioning since version 10.

PostgreSQL supports three partition types:

  • Range Partitioning β€” Rows are distributed based on a range of values (e.g., date ranges). Best for time-series data.
  • List Partitioning β€” Rows are distributed based on a discrete list of values (e.g., country code, region).
  • Hash Partitioning β€” Rows are distributed using a hash function for even distribution when no natural range/list exists.
SQL β€” Range Partitioning Example
-- Create partitioned parent table
CREATE TABLE orders (
    order_id   BIGSERIAL,
    order_date DATE NOT NULL,
    amount     NUMERIC
) PARTITION BY RANGE (order_date);

-- Create partitions
CREATE TABLE orders_2024 PARTITION OF orders
    FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');

CREATE TABLE orders_2025 PARTITION OF orders
    FOR VALUES FROM ('2025-01-01') TO ('2026-01-01');

-- Query works on parent β€” partition pruning happens automatically
SELECT * FROM orders WHERE order_date = '2025-06-01';
πŸ’‘
Oracle DBA Note
PostgreSQL declarative partitioning β‰ˆ Oracle interval/range partitioning. However, in PostgreSQL, indexes and constraints must be created on each partition separately (or use ONLY on parent). There is no global index equivalent.
02Q
What is partition pruning and how does PostgreSQL use it?
Partitioning +

Partition pruning is PostgreSQL's optimizer feature that skips scanning partitions which cannot contain rows matching the query's WHERE clause. This dramatically reduces I/O on large partitioned tables.

  • Static pruning β€” Happens at plan time when the WHERE clause uses constant values.
  • Dynamic pruning β€” Happens at execution time when values are not known until runtime (e.g., parameterized queries). Controlled by enable_partition_pruning = on (default).
SQL
-- Check if partition pruning is working
EXPLAIN SELECT * FROM orders
WHERE order_date = '2025-03-15';

-- Good output: only orders_2025 scanned
-- Bad output: all partitions scanned β†’ no pruning

-- Ensure partition pruning is enabled
SHOW enable_partition_pruning;
SET enable_partition_pruning = on;
⚠ Common Mistake
Partition pruning will NOT work if you cast the column: WHERE order_date::TEXT = '2025-03-15'. Always query the partition key in its native type.
03Q
What is table bloat in PostgreSQL and how do you measure and fix it?
Storage +

Table bloat occurs when dead tuples (from MVCC updates/deletes) accumulate faster than autovacuum can clean them, causing tables and indexes to consume more disk space than necessary and slowing queries.

SQL β€” Detect Bloat
-- Find tables with high dead tuple ratio
SELECT
    schemaname,
    relname AS table_name,
    n_live_tup,
    n_dead_tup,
    round(n_dead_tup::numeric /
        NULLIF(n_live_tup + n_dead_tup, 0) * 100, 1) AS dead_pct,
    last_autovacuum,
    last_vacuum
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC
LIMIT 15;

-- Fix 1: Standard VACUUM (no lock, space reusable)
VACUUM VERBOSE mytable;

-- Fix 2: VACUUM FULL (reclaims disk, takes EXCLUSIVE LOCK!)
VACUUM FULL mytable;

-- Fix 3: pg_repack (online defrag β€” no exclusive lock)
-- pg_repack -d mydb -t mytable
  • A dead_pct above 10–15% indicates a table needing immediate attention.
  • Prefer pg_repack over VACUUM FULL in production β€” it rebuilds the table without long locks.
  • Index bloat is separate β€” use REINDEX CONCURRENTLY for bloated indexes.
04Q
What is TOAST in PostgreSQL and how does it work?
Storage +

TOAST (The Oversized-Attribute Storage Technique) is PostgreSQL's mechanism for storing large column values that exceed the 8KB page size. PostgreSQL automatically stores large values in a separate TOAST table linked to the main table.

  • TOAST kicks in when a row exceeds roughly 2KB (the TOAST_TUPLE_THRESHOLD).
  • TOAST can compress and/or move out-of-line large values (TEXT, BYTEA, JSONB, arrays).
  • Four storage strategies: PLAIN, EXTENDED (default), EXTERNAL, MAIN.
  • Each table with TOAST-able columns has a corresponding pg_toast.pg_toast_NNNN table.
SQL
-- Check TOAST strategy for each column
SELECT attname, attstorage
FROM pg_attribute
WHERE attrelid = 'mytable'::regclass
  AND attnum > 0;

-- Change storage strategy for a column
ALTER TABLE mytable
  ALTER COLUMN doc_content SET STORAGE EXTERNAL;
-- EXTERNAL = no compression, fast access
05Q
What is Transaction ID (XID) wraparound and how do you prevent it?
Critical +

PostgreSQL uses a 32-bit transaction ID (XID) counter. After ~2.1 billion transactions, the XID wraps around. Without preventive action, PostgreSQL will shut down the database to prevent data loss β€” this is one of the most critical operational risks in PostgreSQL.

SQL β€” Monitor XID Age
-- Check XID age per database (alert if > 1.5 billion)
SELECT
    datname,
    age(datfrozenxid) AS xid_age,
    round(age(datfrozenxid)::numeric / 2100000000 * 100, 1) AS pct_used
FROM pg_database
ORDER BY xid_age DESC;

-- Check per-table (find which table is holding old XID)
SELECT relname, age(relfrozenxid) AS table_xid_age
FROM pg_class
WHERE relkind = 'r'
ORDER BY age(relfrozenxid) DESC
LIMIT 10;

-- Force freeze old XIDs
VACUUM FREEZE mytable;
  • PostgreSQL automatically triggers anti-wraparound autovacuum when XID age exceeds autovacuum_freeze_max_age (default: 200M).
  • Monitor and alert when XID age exceeds 1.5 billion.
  • Root cause is often a long-running idle transaction holding back the oldest XID β€” check pg_stat_activity.
⚠ Production Risk
If XID age reaches autovacuum_freeze_max_age (200M by default), PostgreSQL forces VACUUM even on busy tables. If it reaches 2.1B with no freeze done, PostgreSQL shuts down with "database is not accepting commands to avoid wraparound data loss."
02
Autovacuum Tuning
Configuring autovacuum for high-transaction environments
Q6 – Q9
06Q
How do you tune autovacuum for a high-transaction PostgreSQL database?
Autovacuum +

Default autovacuum settings are too conservative for high-write databases. The key is to make autovacuum trigger more frequently and work faster, especially for large tables.

postgresql.conf β€” Tuned Autovacuum
── Global tuning (postgresql.conf) ──────────────────

# More workers for concurrent vacuuming
autovacuum_max_workers        = 6      # default: 3

# Check tables more frequently
autovacuum_naptime            = '30s'  # default: 1min

# Trigger vacuum when 5% rows are dead (not 20%)
autovacuum_vacuum_scale_factor = 0.05  # default: 0.2

# Allow autovacuum to work faster
autovacuum_vacuum_cost_limit  = 1000  # default: 200
autovacuum_vacuum_cost_delay  = '2ms' # default: 20ms

── Per-table override for very large/hot tables ──────
ALTER TABLE orders SET (
    autovacuum_vacuum_scale_factor = 0.01,
    autovacuum_vacuum_threshold    = 1000
);
  • For a 100M-row table, the default 20% scale factor waits for 20M dead tuples β€” far too late.
  • Use per-table overrides via ALTER TABLE ... SET for your hottest tables.
  • Monitor with SELECT * FROM pg_stat_user_tables ORDER BY n_dead_tup DESC;
07Q
What is autovacuum cost-based delay and why does it matter?
Autovacuum +

Cost-based delay throttles autovacuum's I/O by making it sleep when it exceeds a cost threshold, preventing it from overwhelming the disk subsystem on production systems.

postgresql.conf
# Cost assigned per vacuum I/O operation
vacuum_cost_page_hit    = 1    # buffer cache hit
vacuum_cost_page_miss   = 10   # disk read
vacuum_cost_page_dirty  = 20   # dirty page write

# When accumulated cost hits limit, sleep for delay duration
autovacuum_vacuum_cost_limit  = 200   # default
autovacuum_vacuum_cost_delay  = '20ms' # default

# For NVMe/fast storage β€” let autovacuum run at full speed
autovacuum_vacuum_cost_limit  = 2000
autovacuum_vacuum_cost_delay  = '0ms'
  • High cost_delay with low cost_limit = slow autovacuum = bloat accumulation.
  • On fast NVMe storage, set cost_delay = 0 and raise cost_limit significantly.
  • On shared/spinning disk environments, keep cost_delay higher to avoid I/O saturation.
08Q
How do you find which sessions are blocking autovacuum?
Autovacuum +

Long-running transactions and idle-in-transaction sessions prevent autovacuum from cleaning dead tuples because it cannot advance the oldest XID past the blocking transaction.

SQL
-- Find sessions blocking autovacuum (idle-in-transaction)
SELECT
    pid,
    usename,
    state,
    wait_event_type,
    wait_event,
    now() - xact_start AS xact_duration,
    left(query, 80) AS query
FROM pg_stat_activity
WHERE state IN ('idle in transaction', 'idle in transaction (aborted)')
ORDER BY xact_start;

-- Find oldest running transaction (the XID bottleneck)
SELECT pid, usename, state,
    now() - xact_start AS age,
    backend_xmin
FROM pg_stat_activity
WHERE backend_xmin IS NOT NULL
ORDER BY backend_xmin;

-- Terminate the blocker
SELECT pg_terminate_backend(pid);
⚠ Best Practice
Set idle_in_transaction_session_timeout = '10min' in postgresql.conf to automatically terminate sessions that hold open transactions too long.
09Q
What is pg_repack and when should you use it instead of VACUUM FULL?
Maintenance +

pg_repack is a PostgreSQL extension that removes bloat from tables and indexes online β€” without holding an exclusive lock for the full duration. It is the production-safe alternative to VACUUM FULL.

FeatureVACUUM FULLpg_repack
Table LockExclusive (full duration)Brief lock at start/end only
Production Safe❌ Blocks all reads/writesβœ… Online operation
Reclaims Diskβœ… Yesβœ… Yes
Rebuilds Indexesβœ… Yesβœ… Yes
Requires ExtensionNoYes (pg_repack)
Shell
# Install pg_repack
yum install pg_repack17

# Repack a specific table online
pg_repack -d mydb -t orders --no-superuser-check

# Repack all tables in a database
pg_repack -d mydb
03
Logical Replication
Publish-subscribe model, selective replication, cross-version
Q10 – Q13
10Q
What is logical replication and how does it differ from streaming replication?
Replication +
FeatureStreaming ReplicationLogical Replication
LevelPhysical (block/byte level)Logical (row level)
Selective Tables❌ Entire clusterβœ… Per table
Cross-Version❌ Same major versionβœ… Different versions
Cross-Platform❌ Same OS/archβœ… Flexible
DDL Replicationβœ… Automatic❌ Manual
wal_level neededreplicalogical
Standby writable❌ Read-onlyβœ… Yes
πŸ’‘
Oracle DBA Note
Logical replication β‰ˆ Oracle GoldenGate (selective, row-level, cross-version). Streaming replication β‰ˆ Oracle Data Guard Physical Standby.
11Q
How do you set up logical replication between two PostgreSQL databases?
Replication +
SQL β€” Publisher (Source DB)
-- Step 1: Set wal_level = logical in postgresql.conf
-- wal_level = logical

-- Step 2: Create a replication user
CREATE ROLE repl_user WITH REPLICATION LOGIN PASSWORD 'secret';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO repl_user;

-- Step 3: Create publication for specific tables
CREATE PUBLICATION pub_orders
    FOR TABLE orders, order_items;

-- Or publish ALL tables
CREATE PUBLICATION pub_all FOR ALL TABLES;
SQL β€” Subscriber (Target DB)
-- Step 4: Tables must exist on subscriber first
CREATE TABLE orders ( ... );

-- Step 5: Create subscription
CREATE SUBSCRIPTION sub_orders
    CONNECTION 'host=192.168.1.51 port=5432 dbname=mydb user=repl_user password=secret'
    PUBLICATION pub_orders;

-- Step 6: Monitor subscription status
SELECT * FROM pg_stat_subscription;
SELECT * FROM pg_replication_slots;  -- on publisher
12Q
What is a replication slot and what are the risks of leaving them unused?
Critical +

A replication slot is a durable state tracker that ensures WAL files needed by a subscriber or standby are NOT deleted β€” even if the consumer disconnects β€” until those WAL files have been confirmed consumed.

SQL
-- List all replication slots and WAL retained
SELECT
    slot_name,
    active,
    restart_lsn,
    confirmed_flush_lsn,
    pg_size_pretty(pg_wal_lsn_diff(
        pg_current_wal_lsn(), restart_lsn)) AS wal_retained
FROM pg_replication_slots;

-- Drop an inactive/stale replication slot
SELECT pg_drop_replication_slot('stale_slot_name');
⚠ Production Risk
An inactive replication slot retains ALL WAL files since the slot's last confirmed LSN. This can fill up your pg_wal directory and crash the database. Always monitor slot WAL retention and drop stale slots. Set max_slot_wal_keep_size in PostgreSQL 13+ as a safety limit.
13Q
How do you use logical replication for a zero-downtime major version upgrade?
Replication +

Logical replication allows replication between different major PostgreSQL versions, making it ideal for near-zero downtime upgrades (e.g., PG 15 β†’ PG 17).

  • Step 1 β€” Install new PostgreSQL 17 on a new server and initialize a cluster.
  • Step 2 β€” Dump schema only from old cluster: pg_dump --schema-only -d mydb | psql -d mydb_new
  • Step 3 β€” Set up logical replication: create publication on PG15, subscription on PG17.
  • Step 4 β€” Wait for initial data copy to complete and replication to catch up (monitor lag).
  • Step 5 β€” During maintenance window: stop application writes, let replication catch up fully, switchover application to PG17.
  • Step 6 β€” Drop subscription, sequences need to be reset manually.
πŸ’‘
Oracle DBA Note
This approach is very similar to Oracle GoldenGate-based migration between versions. The key difference is PostgreSQL's native logical replication is free, while GoldenGate requires licensing.
04
Connection Pooling & Query Performance
PgBouncer, pg_stat_statements, EXPLAIN, indexes
Q14 – Q18
14Q
What is PgBouncer and what are its three pooling modes?
Pooling +

PgBouncer is a lightweight connection pooler for PostgreSQL. Since PostgreSQL spawns a new OS process per client connection (expensive), PgBouncer maintains a pool of server connections and multiplexes client connections onto them.

ModeServer Connection ReleasedBest For
Session ModeWhen client disconnectsLegacy apps, safe default
Transaction ModeAfter each transaction endsMost web apps β€” best efficiency
Statement ModeAfter each SQL statementRarely used β€” breaks multi-statement logic
pgbouncer.ini β€” Key Config
[databases]
mydb = host=127.0.0.1 port=5432 dbname=mydb

[pgbouncer]
listen_port         = 6432
listen_addr         = *
auth_type           = scram-sha-256
pool_mode           = transaction      # recommended
max_client_conn     = 1000
default_pool_size   = 25
server_idle_timeout = 600
⚠ Transaction Mode Limitation
Transaction pooling mode breaks features that depend on session-level state: SET LOCAL, prepared statements (without protocol-level support), advisory locks, and LISTEN/NOTIFY.
15Q
How do you use pg_stat_statements to find the top slow queries?
Performance +

pg_stat_statements is a PostgreSQL extension that tracks execution statistics for every SQL statement. It is the equivalent of Oracle's V$SQL β€” your first stop for query performance analysis.

SQL
-- Enable in postgresql.conf (requires restart)
-- shared_preload_libraries = 'pg_stat_statements'

-- Enable the extension
CREATE EXTENSION pg_stat_statements;

-- Top 10 queries by total execution time
SELECT
    round(total_exec_time::numeric, 2) AS total_ms,
    calls,
    round(mean_exec_time::numeric, 2)  AS avg_ms,
    round(stddev_exec_time::numeric, 2) AS stddev_ms,
    rows,
    left(query, 80) AS query_snippet
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

-- Reset statistics
SELECT pg_stat_statements_reset();
πŸ’‘
Oracle DBA Note
pg_stat_statements β‰ˆ Oracle V$SQL + V$SQLSTATS. total_exec_time β‰ˆ ELAPSED_TIME. calls β‰ˆ EXECUTIONS. mean_exec_time β‰ˆ ELAPSED_TIME/EXECUTIONS.
16Q
What is a partial index and a covering index in PostgreSQL?
Performance +

Partial Index β€” An index built on a subset of rows defined by a WHERE clause. Much smaller than a full index, making it faster and cheaper to maintain.

SQL
-- Partial index: only index active orders (not all 50M rows)
CREATE INDEX idx_active_orders
    ON orders(customer_id)
    WHERE status = 'ACTIVE';

-- Covering index: include extra columns to avoid table fetch
-- (Index-Only Scan becomes possible)
CREATE INDEX idx_orders_covering
    ON orders(customer_id)
    INCLUDE (order_date, amount);

-- Query that can use covering index (Index-Only Scan)
SELECT customer_id, order_date, amount
FROM orders
WHERE customer_id = 12345;
  • Covering indexes using INCLUDE allow Index-Only Scans β€” no table heap access needed, dramatically faster.
  • Partial indexes shine on tables with a small percentage of frequently-queried rows.
17Q
What causes the PostgreSQL planner to choose a Seq Scan over an Index Scan?
Performance +
  • Stale statistics β€” The planner estimates too many or too few rows. Fix: ANALYZE tablename;
  • Low selectivity β€” Query returns a large % of rows (e.g., >10-20%). Seq Scan is cheaper than many random I/Os.
  • Small table β€” If the entire table fits in a few pages, a Seq Scan is faster than index lookup overhead.
  • No index on the column β€” Index simply doesn't exist.
  • Data type mismatch / implicit cast β€” WHERE id = '123' when id is INTEGER prevents index use.
  • Function on indexed column β€” WHERE LOWER(email) = 'x' bypasses index unless a functional index exists.
  • Low effective_cache_size β€” Planner underestimates OS cache, making index scans seem more expensive.
SQL β€” Diagnose
-- Force index scan for testing only
SET enable_seqscan = off;
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 99;
SET enable_seqscan = on; -- always reset after testing

-- Update statistics
ANALYZE orders;
18Q
What is the difference between EXPLAIN and EXPLAIN ANALYZE BUFFERS?
Performance +
SQL
-- EXPLAIN: plan only, no execution, no actual timings
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;

-- EXPLAIN ANALYZE: executes the query + actual timings
EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id = 42;

-- EXPLAIN (ANALYZE, BUFFERS): shows buffer hits/misses
-- Shared hit = from shared_buffers (fast)
-- Shared read = from disk (slow)
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM orders WHERE customer_id = 42;

-- EXPLAIN (ANALYZE, BUFFERS, SETTINGS, WAL, FORMAT JSON)
-- Full diagnostic output for pgBadger / explain.dalibo.com
EXPLAIN (ANALYZE, BUFFERS, SETTINGS, WAL, FORMAT JSON)
SELECT * FROM orders WHERE customer_id = 42;
  • Shared hit β€” Pages served from shared_buffers (no I/O). Good.
  • Shared read β€” Pages read from disk. High value means cache miss β€” consider increasing shared_buffers.
  • Use explain.dalibo.com to visualise the JSON output as a graphical plan.
05
High Availability & Patroni
Patroni, repmgr, failover automation, etcd
Q19 – Q22
19Q
What is Patroni and how does it provide automatic failover for PostgreSQL?
HA +

Patroni is an open-source HA solution that uses a distributed configuration store (etcd, ZooKeeper, or Consul) to manage leader election and automatic failover for PostgreSQL clusters.

  • Patroni runs as a daemon on every node and monitors the local PostgreSQL instance.
  • The current primary holds a leader lock in etcd (with TTL). If the primary fails, the lock expires.
  • Replicas race to acquire the leader lock. The winner promotes itself to primary.
  • HAProxy or Keepalived (VIP) routes application traffic to the current primary automatically.
  • Full cluster configuration is stored in etcd β€” making it consistent across all nodes.
Shell β€” Patroni Stack Components
# Typical Patroni HA stack
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  App β†’ HAProxy (VIP via Keepalived)          β”‚
β”‚         ↓               ↓                   β”‚
β”‚  PostgreSQL Primary   PostgreSQL Replica     β”‚
β”‚  + Patroni            + Patroni             β”‚
β”‚         ↓               ↓                   β”‚
β”‚         └── etcd cluster (3 nodes) β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

# Check cluster status
patronictl -c /etc/patroni/patroni.yml list

# Manual switchover
patronictl -c /etc/patroni/patroni.yml switchover
πŸ’‘
Oracle DBA Note
Patroni β‰ˆ Oracle RAC / Data Guard Fast-Start Failover. The etcd cluster plays the role of Oracle Clusterware / Grid Infrastructure for distributed coordination.
20Q
What is the difference between Patroni and repmgr?
HA +
FeaturePatronirepmgr
Auto Failoverβœ… Native, consensus-based⚠ Requires repmgrd + extra setup
Split-brain Protectionβœ… etcd/ZK consensus prevents it⚠ Risk without fencing
ComplexityHigher (needs etcd cluster)Lower (simpler setup)
DCS Dependencyetcd / ZooKeeper / ConsulPostgreSQL itself
Cluster Managementpatronictl (full REST API)repmgr CLI
Industry AdoptionWidely used in enterpriseCommon for simpler setups

For production enterprise environments, Patroni is the recommended choice due to its reliable consensus-based failover and split-brain prevention.

21Q
What is split-brain in PostgreSQL HA and how does Patroni prevent it?
Critical +

Split-brain occurs when two PostgreSQL nodes both believe they are the primary and accept writes simultaneously β€” leading to data divergence and corruption.

  • Patroni prevents split-brain using a distributed lock in etcd. Only the node holding the leader key can act as primary.
  • The leader key has a TTL (Time-To-Live). The primary must renew it continuously. If the primary cannot reach etcd, it loses the key and demotes itself.
  • Replicas will only promote if they successfully acquire the leader key β€” guaranteed by etcd's atomic compare-and-swap.
  • Network partitions where a primary cannot reach etcd will cause self-demotion, never split-brain.
⚠ Without Patroni
Manual or repmgr-based HA without distributed consensus is vulnerable to split-brain if network partitions occur. This is why a production HA stack MUST include a DCS (distributed consensus store) like etcd.
22Q
How do you monitor replication lag and what are acceptable thresholds?
HA +
SQL β€” Comprehensive Lag Monitoring
-- On PRIMARY: lag per standby (bytes and estimated time)
SELECT
    application_name,
    client_addr,
    state,
    sync_state,
    pg_size_pretty(sent_lsn - replay_lsn)  AS replay_lag_bytes,
    write_lag,
    flush_lag,
    replay_lag
FROM pg_stat_replication;

-- On STANDBY: how far behind in seconds
SELECT
    now() - pg_last_xact_replay_timestamp() AS replication_delay,
    pg_is_in_recovery()                     AS is_standby,
    pg_last_wal_receive_lsn()               AS received_lsn,
    pg_last_wal_replay_lsn()                AS replayed_lsn;
  • < 1 second β€” Excellent. Standard for healthy async replication on LAN.
  • 1–30 seconds β€” Acceptable for most OLTP workloads.
  • > 60 seconds β€” Alert: investigate I/O bottleneck on standby, network issues, or standby under load.
  • High lag + network failure = data loss window. Size your recovery point objective (RPO) accordingly.
06
Extensions & Real-World Administration
pg_cron, pgAudit, pg_upgrade, common troubleshooting
Q23 – Q25
23Q
How do you upgrade PostgreSQL major versions using pg_upgrade?
Upgrade +

pg_upgrade upgrades a PostgreSQL cluster to a new major version in-place, by copying only the catalog files and hard-linking or copying the data files β€” much faster than a dump/restore for large databases.

Shell β€” pg_upgrade from PG15 to PG17
# Step 1: Install new PostgreSQL 17 binaries (don't init cluster)
yum install postgresql17-server

# Step 2: Initialize new cluster (empty)
/usr/pgsql-17/bin/initdb -D /pgdata/pgsql17/data

# Step 3: Stop old cluster
systemctl stop postgresql-15

# Step 4: Run pg_upgrade check first (dry run)
/usr/pgsql-17/bin/pg_upgrade \
    -b /usr/pgsql-15/bin \
    -B /usr/pgsql-17/bin \
    -d /pgdata/pgsql15/data \
    -D /pgdata/pgsql17/data \
    --check

# Step 5: Run actual upgrade (--link = hard-link, no copy)
/usr/pgsql-17/bin/pg_upgrade \
    -b /usr/pgsql-15/bin \
    -B /usr/pgsql-17/bin \
    -d /pgdata/pgsql15/data \
    -D /pgdata/pgsql17/data \
    --link

# Step 6: Start new cluster and run post-upgrade tasks
systemctl start postgresql-17
./analyze_new_cluster.sh  # generated by pg_upgrade
πŸ’‘
Oracle DBA Note
pg_upgrade β‰ˆ Oracle DBUA (Database Upgrade Assistant). The --link option makes it extremely fast (seconds for TB databases) because it uses OS hard-links rather than copying data files.
24Q
What is pg_cron and how do you schedule jobs in PostgreSQL?
Extensions +

pg_cron is a PostgreSQL extension that enables scheduling of SQL queries or stored procedures using cron syntax β€” directly inside the database, without needing external OS cron jobs.

SQL
-- Enable in postgresql.conf (requires restart)
-- shared_preload_libraries = 'pg_cron'
-- cron.database_name = 'mydb'

CREATE EXTENSION pg_cron;

-- Schedule a job: delete old logs every day at 3 AM
SELECT cron.schedule(
    'cleanup-old-logs',
    '0 3 * * *',
    $$DELETE FROM app_logs WHERE created_at < NOW() - INTERVAL '90 days'$$
);

-- Schedule a job every 5 minutes
SELECT cron.schedule('refresh-stats', '*/5 * * * *',
    $$CALL refresh_materialized_views()$$);

-- List all scheduled jobs
SELECT * FROM cron.job;

-- View execution history
SELECT * FROM cron.job_run_details ORDER BY start_time DESC LIMIT 10;
πŸ’‘
Oracle DBA Note
pg_cron β‰ˆ Oracle DBMS_SCHEDULER. Both allow scheduling SQL/PL jobs directly in the database. pg_cron uses familiar Unix cron syntax.
25Q
How do you troubleshoot a PostgreSQL database that is running out of connections?
Troubleshooting +

A FATAL: remaining connection slots are reserved for non-replication superuser connections error means max_connections is exhausted. Here is a systematic approach to diagnose and resolve it:

SQL β€” Diagnose Connection Exhaustion
-- Step 1: Check current connection usage
SELECT
    max_conn,
    used_conn,
    superuser_reserved,
    max_conn - used_conn AS free_conn
FROM (
    SELECT
        current_setting('max_connections')::int AS max_conn,
        COUNT(*) AS used_conn,
        current_setting('superuser_reserved_connections')::int AS superuser_reserved
    FROM pg_stat_activity
) t;

-- Step 2: Find connection counts per user/database
SELECT usename, datname, state, COUNT(*)
FROM pg_stat_activity
GROUP BY usename, datname, state
ORDER BY COUNT(*) DESC;

-- Step 3: Find idle/idle-in-transaction sessions to terminate
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle in transaction'
  AND now() - xact_start > interval '30 minutes';
  • Immediate fix β€” Terminate idle/stale sessions as shown above.
  • Short-term fix β€” Temporarily raise max_connections (requires restart). Note: each connection uses ~5–10MB RAM.
  • Permanent fix β€” Deploy PgBouncer in transaction pooling mode to dramatically reduce the number of actual PostgreSQL connections needed.
  • Set idle_in_transaction_session_timeout to auto-kill stuck transactions.
  • Set CONNECTION LIMIT per role to prevent any single user from exhausting connections.

PostgreSQL Interview Questions for DBAs

PostgreSQL Interview Questions for DBAs – 25 Beginner Q&A | Bright DBA
Interview Preparation Guide

PostgreSQL Interview Questions
for Beginner DBAs

25 essential questions every beginner PostgreSQL DBA must know β€” with clear, practical answers. Ideal for Oracle DBAs transitioning to PostgreSQL.

25Questions
5Categories
⭐Beginner Level
Architecture MVCC & WAL Backup & Recovery Replication Administration Performance
πŸ—οΈ
Architecture & Basics
Core concepts every PostgreSQL DBA must understand
Q1 – Q7
Q1 What is PostgreSQL, and how is it different from other databases like Oracle or MySQL?
Architecture +

PostgreSQL is a free, open-source object-relational database management system (ORDBMS) that has been actively developed for over 35 years. It is known for its reliability, standards compliance (SQL:2016), and powerful extensibility.

  • Open Source & Free β€” No licensing cost, unlike Oracle which requires expensive licenses.
  • ACID Compliant β€” Full support for Atomicity, Consistency, Isolation, and Durability.
  • Extensible β€” You can define custom data types, operators, functions, and index methods.
  • JSON Support β€” Supports both relational (SQL) and non-relational (JSONB) querying.
  • Cross-Platform β€” Runs on Linux, Windows, and macOS.
πŸ’‘
Oracle DBA Note
PostgreSQL is the closest open-source equivalent to Oracle. Features like sequences, schemas, tablespaces, WAL (similar to redo logs), and MVCC are all present in PostgreSQL.
Q2 Explain the architecture of PostgreSQL.
Architecture +

PostgreSQL follows a client-server, multi-process architecture. The main components are:

  • Postmaster Process β€” The master daemon that listens on port 5432, accepts connections, and spawns backend processes.
  • Backend Process β€” A dedicated server process is spawned for each client connection to handle queries.
  • Shared Buffers β€” Shared memory pool for caching data pages (like Oracle's SGA Buffer Cache).
  • WAL Writer β€” Writes transaction logs (WAL) to disk for durability.
  • Checkpointer β€” Flushes dirty pages from shared buffers to data files at regular intervals.
  • Autovacuum Daemon β€” Cleans dead tuples and updates statistics automatically.
  • Background Writer β€” Proactively writes dirty buffers to disk to reduce I/O spikes at checkpoints.
  • WAL Archiver β€” Archives WAL files when continuous archiving is enabled.
  • Stats Collector β€” Gathers activity statistics stored in pg_stat_* views.
πŸ’‘
Oracle DBA Note
The Postmaster β‰ˆ Oracle Listener + PMON. Shared Buffers β‰ˆ SGA Buffer Cache. WAL β‰ˆ Online Redo Logs. Checkpointer β‰ˆ CKPT process. Autovacuum β‰ˆ SMON cleanup.
Q3 What is MVCC (Multi-Version Concurrency Control) in PostgreSQL?
Architecture +

MVCC is the mechanism PostgreSQL uses to allow multiple transactions to read and write data concurrently without blocking each other. Instead of locking rows, PostgreSQL creates new versions of rows for each update or delete.

  • When a row is updated, the old version is marked as dead and a new version is created.
  • When a row is deleted, it is just marked as dead β€” not physically removed immediately.
  • Each transaction sees a consistent snapshot of the data as of the transaction start time.
  • Dead row versions are later cleaned up by the VACUUM process.
  • This eliminates read-write conflicts β€” readers never block writers and writers never block readers.
πŸ’‘
Oracle DBA Note
Oracle also uses MVCC, but stores old row versions in the UNDO tablespace. PostgreSQL stores them in the table itself (heap), which is why VACUUM is needed to reclaim space.
Q4 What is WAL (Write-Ahead Logging) in PostgreSQL?
Architecture +

WAL (Write-Ahead Logging) is PostgreSQL's mechanism for ensuring data durability and crash recovery. The core principle is: changes are written to the WAL log file first, before being applied to actual data files.

  • WAL files are stored in the $PGDATA/pg_wal directory.
  • Each WAL file is 16 MB by default and has a name like 000000010000000000000001.
  • WAL is used for crash recovery, point-in-time recovery (PITR), and streaming replication.
  • WAL level is configured via wal_level parameter: minimal, replica, or logical.
-- Check WAL level SHOW wal_level;-- Check current WAL location SELECT pg_current_wal_lsn();-- Manually switch to next WAL file SELECT pg_switch_wal();
πŸ’‘
Oracle DBA Note
WAL in PostgreSQL β‰ˆ Online Redo Logs in Oracle. WAL archiving β‰ˆ Oracle archivelog mode. pg_wal directory β‰ˆ Oracle's redo log location.
Q5 What is the difference between a Role and a User in PostgreSQL?
Admin +

In PostgreSQL, there is no difference between a role and a user at the database level. A USER is simply a ROLE with the LOGIN privilege.

-- These two are equivalent: CREATE USER raj WITH PASSWORD 'mypassword'; CREATE ROLE raj LOGIN PASSWORD 'mypassword';-- A role WITHOUT login (cannot connect to DB) CREATE ROLE readonly_role;-- Grant a role to a user GRANT readonly_role TO raj;-- List all roles \du
  • Roles can be granted to other roles, enabling role inheritance.
  • SUPERUSER roles have unrestricted access β€” equivalent to Oracle's SYSDBA.
  • Use NOLOGIN for group roles that are never used to connect directly.
Q6 What is pg_hba.conf and what is it used for?
Admin +

pg_hba.conf is the Host-Based Authentication configuration file in PostgreSQL. It controls which hosts are allowed to connect, which databases they can access, which users can connect, and what authentication method is used.

# TYPE DATABASE USER ADDRESS METHOD local all postgres peer local all all md5 host all all 127.0.0.1/32 scram-sha-256 host all all 192.168.1.0/24 scram-sha-256 host replication all 192.168.1.52/32 scram-sha-256
  • local β€” Unix socket connections.
  • host β€” TCP/IP connections (both SSL and non-SSL).
  • hostssl β€” SSL-only connections.
  • Authentication methods: trust, md5, scram-sha-256, peer, ldap.
  • After editing, reload with: SELECT pg_reload_conf();
πŸ’‘
Oracle DBA Note
pg_hba.conf β‰ˆ Oracle sqlnet.ora + listener.ora combined for controlling who can connect and how they authenticate.
Q7 What is a tablespace in PostgreSQL and how do you create one?
Admin +

A tablespace in PostgreSQL is a named location on disk where database objects (tables, indexes) are stored. It allows DBAs to control where data is physically stored β€” for example, placing large tables on a faster disk.

-- Step 1: Create directory (as OS user) mkdir -p /pgdata/tbs/app_tbs01 chown postgres:postgres /pgdata/tbs/app_tbs01-- Step 2: Create tablespace in PostgreSQL CREATE TABLESPACE app_tbs01 OWNER postgres LOCATION '/pgdata/tbs/app_tbs01';-- Step 3: Create a table in that tablespace CREATE TABLE orders (id SERIAL, amount NUMERIC) TABLESPACE app_tbs01;-- List all tablespaces \db
πŸ’Ύ
Backup & Recovery
pg_dump, pg_basebackup, PITR, and WAL archiving
Q8 – Q13
Q8 What are the types of backups available in PostgreSQL?
Backup +

PostgreSQL supports two main types of backups:

  • Logical Backup β€” Uses pg_dump or pg_dumpall. Exports SQL statements. Human-readable, portable across versions. Cannot be used for PITR. Best for schema/table level recovery.
  • Physical Backup β€” Uses pg_basebackup. Copies the actual data files. Can be combined with WAL archives for Point-in-Time Recovery (PITR). Used for full cluster recovery and standby server setup.
πŸ’‘
Oracle DBA Note
pg_dump β‰ˆ Oracle Data Pump Export (expdp). pg_basebackup β‰ˆ Oracle RMAN full backup. WAL archiving β‰ˆ Oracle archivelog mode for PITR.
Q9 What is the difference between pg_dump and pg_dumpall?
Backup +
-- pg_dump: backup a SINGLE database pg_dump -U postgres -d mydb -Fc -f /backup/mydb.dmp-- pg_dumpall: backup ALL databases + global objects (roles, tablespaces) pg_dumpall -U postgres -f /backup/all_databases.sql-- pg_dumpall globals only (roles and tablespaces) pg_dumpall -U postgres --globals-only -f /backup/globals.sql-- Restore pg_dump backup pg_restore -U postgres -d mydb -v /backup/mydb.dmp-- Restore pg_dumpall backup psql -U postgres -f /backup/all_databases.sql
  • pg_dump backs up one database at a time. Supports custom (-Fc), plain (-Fp), directory (-Fd) formats.
  • pg_dumpall backs up all databases AND global objects (roles, tablespaces). Output is always plain SQL.
  • Neither supports PITR β€” for that, use pg_basebackup + WAL archiving.
Q10 What is pg_basebackup and when do you use it?
Backup +

pg_basebackup takes a physical binary backup of the entire PostgreSQL cluster while the database is running (online backup). It copies all data files, WAL files, and configuration files.

-- Basic pg_basebackup (tar format, includes WAL) pg_basebackup -U postgres \ -D /backup/base_bkp \ -Ft -Xs -P -v-- Options explained: -- -Ft : tar format -- -Xs : stream WAL during backup -- -P : show progress -- -v : verbose
  • Used for setting up standby (replica) servers for streaming replication.
  • Used as the base for Point-in-Time Recovery (PITR) when combined with WAL archives.
  • Requires wal_level = replica and replication privilege on the user.
Q11 What is Point-in-Time Recovery (PITR) in PostgreSQL?
Backup +

PITR allows you to restore a PostgreSQL database to any specific point in time β€” for example, just before an accidental DROP TABLE. It requires a base backup + continuous WAL archives.

  • Enable archiving: set archive_mode = on and archive_command in postgresql.conf.
  • Take a base backup using pg_basebackup.
  • During recovery, set restore_command and recovery_target_time in postgresql.conf.
  • Create an empty recovery.signal file in PGDATA to trigger recovery mode.
  • After recovery, run SELECT pg_wal_replay_resume(); to promote the DB.
-- postgresql.conf settings for PITR recovery restore_command = 'cp /backup/archive/%f %p' recovery_target_time = '2025-10-12 22:05:00'-- Create recovery signal file touch $PGDATA/recovery.signal-- After DB starts in recovery, promote it SELECT pg_wal_replay_resume();
πŸ’‘
Oracle DBA Note
PostgreSQL PITR β‰ˆ Oracle RMAN Point-in-Time Recovery. recovery.signal β‰ˆ Oracle's incomplete recovery trigger. WAL archives β‰ˆ Oracle archived redo logs.
Q12 How do you enable WAL archiving in PostgreSQL?
Backup +
-- Edit postgresql.conf wal_level = replica archive_mode = on archive_command = 'cp %p /pgArchive/arch/%f' max_wal_senders = 10-- Reload configuration SELECT pg_reload_conf();-- Verify archiving is active SELECT * FROM pg_stat_archiver;-- Manually force a WAL switch to test archive_command SELECT pg_switch_wal();
  • %p in archive_command = full path of the WAL file to be archived.
  • %f = filename only.
  • The archive directory must be owned by the postgres OS user.
  • Check pg_stat_archiver.last_failed_wal to diagnose archiving failures.
Q13 How do you restore a single table using pg_dump and pg_restore?
Backup +
-- Step 1: Dump a specific table (custom format) pg_dump -U postgres -d mydb \ -t schema_name.table_name \ -Fc -v \ -f /backup/table_backup.dmp-- Step 2: Verify contents of the dump pg_restore -l /backup/table_backup.dmp-- Step 3: Restore the table to the database pg_restore -U postgres -d mydb \ -v /backup/table_backup.dmp
  • Use -Fc (custom format) for table-level restores β€” plain SQL format does not support selective restore.
  • If the table already exists, add --clean flag to drop it before restoring.
  • Use -n schema_name to specify schema if needed.
⚑
Performance & Maintenance
VACUUM, ANALYZE, indexes, and query tuning basics
Q14 – Q18
Q14 What is VACUUM in PostgreSQL and why is it needed?
Performance +

Due to MVCC, PostgreSQL does not immediately delete updated or deleted rows β€” it marks them as "dead tuples". Over time, these accumulate and cause table bloat, slowing down queries. VACUUM reclaims this dead space.

-- Standard VACUUM: marks space as reusable (does NOT shrink file) VACUUM mytable;-- VACUUM ANALYZE: reclaim space + update statistics VACUUM ANALYZE mytable;-- VACUUM FULL: rewrites entire table, returns space to OS (LOCKS table!) VACUUM FULL mytable;-- Check dead tuples per table SELECT relname, n_dead_tup, last_autovacuum FROM pg_stat_user_tables ORDER BY n_dead_tup DESC;
  • Autovacuum runs VACUUM automatically in the background β€” it is enabled by default.
  • VACUUM does NOT lock the table. VACUUM FULL holds an exclusive lock.
  • VACUUM also prevents Transaction ID (XID) wraparound β€” a critical PostgreSQL risk.
Q15 What is autovacuum and how does it work?
Performance +

Autovacuum is a background PostgreSQL daemon that automatically runs VACUUM and ANALYZE on tables when they accumulate enough dead tuples or changed rows, without DBA intervention.

  • It is triggered when: dead tuples > autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor Γ— total_rows
  • Key parameters: autovacuum_max_workers (default: 3), autovacuum_naptime (default: 1 min).
  • Never disable autovacuum on production β€” it prevents bloat and XID wraparound.
-- Check autovacuum settings SHOW autovacuum; SHOW autovacuum_vacuum_scale_factor;-- Monitor autovacuum activity SELECT pid, query FROM pg_stat_activity WHERE query LIKE 'autovacuum%';
πŸ’‘
Oracle DBA Note
Autovacuum β‰ˆ Oracle SMON (cleaning temporary segments and managing undo). However, PostgreSQL autovacuum must also prevent XID wraparound, which has no direct Oracle equivalent.
Q16 What types of indexes are available in PostgreSQL?
Performance +
  • B-Tree (default) β€” Best for equality and range queries. Used for most cases.
  • Hash β€” Only for equality comparisons (=). Faster than B-Tree for pure equality.
  • GIN (Generalized Inverted Index) β€” Best for full-text search, arrays, and JSONB data.
  • GiST (Generalized Search Tree) β€” Used for geometric data, full-text search, and range types.
  • BRIN (Block Range Index) β€” Very small index for large tables with naturally ordered data (e.g., timestamps).
  • SP-GiST β€” Space-partitioned trees for non-balanced data structures.
-- Create a standard B-Tree index CREATE INDEX idx_emp_name ON employees(last_name);-- Create index without locking table (CONCURRENTLY) CREATE INDEX CONCURRENTLY idx_emp_email ON employees(email);-- GIN index for JSONB CREATE INDEX idx_data_gin ON logs USING GIN (payload);
Q17 How do you generate and read an execution plan in PostgreSQL?
Performance +
-- EXPLAIN: shows plan without executing EXPLAIN SELECT * FROM employees WHERE dept_id = 10;-- EXPLAIN ANALYZE: executes query and shows actual timings EXPLAIN ANALYZE SELECT * FROM employees WHERE dept_id = 10;-- EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT * FROM employees WHERE dept_id = 10;
  • Seq Scan β€” Full table scan (no index used).
  • Index Scan β€” Index used to fetch specific rows.
  • cost= β€” Estimated startup cost .. total cost.
  • actual time= β€” Actual execution time in milliseconds.
  • rows= β€” Estimated vs actual row count. Large difference = stale statistics β†’ run ANALYZE.
πŸ’‘
Oracle DBA Note
EXPLAIN ANALYZE β‰ˆ Oracle's EXPLAIN PLAN + AUTOTRACE. The output is similar to Oracle's execution plan with cost estimates and actual row counts.
Q18 What are the key parameters in postgresql.conf that affect performance?
Performance +
-- Memory Parameters shared_buffers = 4GB -- 25% of total RAM (like Oracle SGA) work_mem = 64MB -- Per-sort operation memory maintenance_work_mem = 512MB -- For VACUUM, CREATE INDEX effective_cache_size = 12GB -- Estimated OS + DB cache (for planner)-- WAL / Checkpoint Parameters checkpoint_timeout = 15min max_wal_size = 2GB wal_compression = on-- Connection Parameters max_connections = 200-- Parallel Query max_parallel_workers_per_gather = 4
  • shared_buffers β€” Most impactful single parameter. Set to 25% of RAM.
  • work_mem β€” Be careful: each sort/hash in each query can use this amount.
  • effective_cache_size β€” Hint to the planner only; does not allocate memory.
πŸ”
Replication & High Availability
Streaming replication, failover, and standby concepts
Q19 – Q22
Q19 What is streaming replication in PostgreSQL?
High Availability +

Streaming replication allows a standby (replica) server to stay in sync with the primary by continuously receiving and applying WAL records over a TCP connection β€” in near real time.

  • The standby connects to the primary using the replication protocol.
  • By default it is asynchronous β€” primary does not wait for standby confirmation before committing.
  • Synchronous replication is possible via synchronous_standby_names β€” zero data loss but adds latency.
  • The standby can serve read-only queries (Hot Standby).
  • Monitor replication lag via pg_stat_replication on primary.
πŸ’‘
Oracle DBA Note
PostgreSQL streaming replication β‰ˆ Oracle Data Guard Physical Standby. Synchronous mode β‰ˆ Oracle Data Guard SYNC protection mode. pg_stat_replication β‰ˆ Oracle v$managed_standby.
Q20 What is the difference between asynchronous and synchronous replication?
High Availability +
  • Asynchronous (default) β€” Primary commits immediately without waiting for standby confirmation. Better performance, but risk of small data loss if primary crashes before WAL is sent to standby.
  • Synchronous β€” Primary waits for at least one standby to confirm WAL receipt before committing. Zero data loss, but adds latency to every write transaction.
-- Enable synchronous replication on PRIMARY -- (postgresql.conf) synchronous_standby_names = 'standby1'-- Check replication status SELECT application_name, sync_state, sent_lsn, replay_lsn FROM pg_stat_replication;
Q21 How do you promote a standby to primary (manual failover)?
High Availability +
-- Method 1: Using pg_promote() function (PostgreSQL 12+) SELECT pg_promote();-- Method 2: Using pg_ctl promote command pg_ctl promote -D /pgdata/pgsql17/data-- Verify promotion was successful SELECT pg_is_in_recovery(); -- Returns: f (false) = now a primary-- Check timeline (should increase by 1 after promotion) SELECT timeline_id FROM pg_control_checkpoint();
  • After promotion, the standby becomes a new primary on a new timeline.
  • Old primary should NOT be brought back up without reinitializing as a new standby.
  • Tools like Patroni or repmgr automate this process.
Q22 How do you check replication lag in PostgreSQL?
High Availability +
-- On PRIMARY: check all connected standbys and their lag SELECT application_name, client_addr, state, sent_lsn, replay_lsn, (sent_lsn - replay_lsn) AS replication_lag_bytes, sync_state FROM pg_stat_replication;-- On STANDBY: check how far behind this standby is SELECT now() - pg_last_xact_replay_timestamp() AS replication_delay;
πŸ› οΈ
Day-to-Day Administration
Common DBA commands and monitoring queries
Q23 – Q25
Q23 How do you find and kill long-running queries in PostgreSQL?
Admin +
-- Find all active queries running more than 5 minutes SELECT pid, now() - pg_stat_activity.query_start AS duration, query, state, usename, client_addr FROM pg_stat_activity WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes' AND state != 'idle' ORDER BY duration DESC;-- Gracefully cancel a query (sends SIGINT) SELECT pg_cancel_backend(12345);-- Forcefully terminate a session (sends SIGTERM) SELECT pg_terminate_backend(12345);
πŸ’‘
Oracle DBA Note
pg_stat_activity β‰ˆ Oracle v$session. pg_cancel_backend β‰ˆ ALTER SYSTEM CANCEL SQL. pg_terminate_backend β‰ˆ ALTER SYSTEM KILL SESSION.
Q24 How do you find blocking sessions in PostgreSQL?
Admin +
-- Find blocking and blocked sessions SELECT blocked.pid AS blocked_pid, blocked.query AS blocked_query, blocking.pid AS blocking_pid, blocking.query AS blocking_query, blocked.usename AS blocked_user, blocking.usename AS blocking_user FROM pg_stat_activity AS blocked JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid)) WHERE cardinality(pg_blocking_pids(blocked.pid)) > 0;-- Kill the blocking session SELECT pg_terminate_backend(blocking_pid);
Q25 What are the most important monitoring views every PostgreSQL DBA must know?
Admin +
  • pg_stat_activity β€” Active sessions, queries, wait events. (β‰ˆ Oracle v$session)
  • pg_stat_user_tables β€” Table-level stats: dead tuples, seq scans, last vacuum. (β‰ˆ Oracle dba_tab_modifications)
  • pg_stat_user_indexes β€” Index usage statistics. Identify unused indexes.
  • pg_stat_replication β€” Standby connection status and replication lag. (β‰ˆ Oracle v$managed_standby)
  • pg_stat_archiver β€” WAL archiving status and failures.
  • pg_stat_statements β€” Top SQL by execution count, total time. (β‰ˆ Oracle v$sql β€” requires extension)
  • pg_locks β€” Active lock information. (β‰ˆ Oracle v$lock)
  • pg_database β€” Database list with sizes. (β‰ˆ Oracle dba_data_files)
-- Top 10 queries by total execution time SELECT query, calls, total_exec_time, mean_exec_time FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;-- Enable pg_stat_statements (in postgresql.conf) shared_preload_libraries = 'pg_stat_statements'

Synchronous Replication in PostgreSQL

How to Convert Asynchronous PostgreSQL Replication to Synchronous Replication

Table of Contents



0. Overview

  • Synchronous Streaming Replication (SYNC) in PostgreSQL ensures that a transaction is committed only after the data is successfully replicated to one or more standby servers.
  • This provides zero data loss (RPO = 0) in case the primary crashes, because every committed transaction exists on at least one standby.
  • PostgreSQL synchronous replication = Oracle Dataguard Maximum Protection mode

How It Works

Β  Β  Β  1. A client issues a COMMIT on the primary.
Β  Β  Β  2. PostgreSQL writes the transaction to the WAL (Write-Ahead Log).
Β  Β  Β  3. The WAL data is streamed to standby servers via the WAL sender (walsender).
Β  Β  Β  4. WAL receiver (walreceiver) processes.
The primary waits until:
Β  Β  Β  5. At least one synchronous standby confirms it has received the WAL record.
Β  Β  Β  6. Only then does the primary report the transaction as committed to the client.

Advantages

  • No data loss if the primary fails (RPO = 0).
  • Ensures data durability across nodes.
  • Suitable for financial or critical systems.

Disadvantages

  • Higher latency for commits (client waits for standby acknowledgment).
  • If synchronous standby is down or slow, the primary will pause commits.
  • Requires stable, low-latency network.

1. Environment

NodeIPRoleSync TypePurpose
rac1192.168.2.21Standby1asyncConvert ASYNC to SYNC
rac2192.168.2.22PrimaryasyncMain writter
rac3192.168.3.20Standby2asyncWill remain async

2. Goal

Convert ASYNC to SYNC only for Standby 1 (rac1)

rac1 β†’ Standby 1 (Synchronous mode)
rac2 β†’ Primary
rac3 β†’ Standby 2 (Asynchronous mode)

Since rac1 operates in SYNC mode, the primary waits for commit acknowledgment from rac1 before completing each transaction.

This behavior ensures data consistency, as the primary confirms commits only after receiving acknowledgment from the synchronous standby.

If rac1 is stopped, the transaction (for example, process PID 6101) will pause or hang until rac1 becomes available again β€” this is expected synchronous replication behavior.

Meanwhile, rac3 (the asynchronous standby) does not block transactions, since it doesn’t participate in the synchronous commit process.

3. Verify Application Name on Primary

# On Primary Node

# Each standby must have a unique application_name in its connection info, but here both standby's have same application name.

[postgres@rac2 ~]$ psql -c "SELECT application_name, client_addr, sync_state, sync_priority FROM pg_stat_replication;"
 application_name | client_addr  | sync_state | sync_priority
------------------+--------------+------------+---------------
 walreceiver      | 192.168.3.20 | async      |             0
 walreceiver      | 192.168.2.21 | async      |             0
(2 rows)

[postgres@rac2 ~]$

4. Edit Standby1 (rac1) Connection Info

# On Standby 1 (rac1)

[postgres@rac1 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac1_standby_slot'
[postgres@rac1 ~]$


[postgres@rac1 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# ALTER SYSTEM SET primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable application_name=rac1';
ALTER SYSTEM
postgres=#

[postgres@rac1 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_slot_name = 'rac1_standby_slot'
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable application_name=rac1'
[postgres@rac1 ~]$


[postgres@rac1 ~]$ psql -c "SELECT pg_reload_conf();"
 pg_reload_conf
----------------
 t
(1 row)

[postgres@rac1 ~]$

5. Edit Standby2 (rac3) Connection Info

[postgres@rac3 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac3_standby_slot'
[postgres@rac3 ~]$
[postgres@rac3 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# ALTER SYSTEM SET primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable application_name=rac3';
ALTER SYSTEM
postgres=#
[postgres@rac3 ~]$
[postgres@rac3 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_slot_name = 'rac3_standby_slot'
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable application_name=rac3'
[postgres@rac3 ~]$

[postgres@rac3 ~]$ psql -c "SELECT pg_reload_conf();"
 pg_reload_conf
----------------
 t
(1 row)

[postgres@rac3 ~]$

6. Verify Application Name on Primary (After Change)

# On Primary node
[postgres@rac2 ~]$ psql -c "SELECT application_name, client_addr, sync_state, sync_priority FROM pg_stat_replication;"
 application_name | client_addr  | sync_state | sync_priority
------------------+--------------+------------+---------------
 rac1             | 192.168.2.21 | async      |             0
 rac3             | 192.168.3.20 | async      |             0
(2 rows)

[postgres@rac2 ~]$

7. Enable Synchronous Mode (Convert ASYNC to SYNC)

On Primary (rac2):

examples: 
/*
# ALTER SYSTEM SET synchronous_standby_names='application_name'; 
# ALTER SYSTEM SET synchronous_standby_names='(rac2, rac3)'; # both to be synchronous
# ALTER SYSTEM SET synchronous_standby_names='ANY 1 (rac2, rac3)'; # only one to be synchronous (any one of the two)
# ALTER SYSTEM SET synchronous_standby_names='*'; # all to be synchronous
*/

[postgres@rac2 ~]$ psql -c "SELECT application_name, client_addr, sync_state, sync_priority FROM pg_stat_replication;"
 application_name | client_addr  | sync_state | sync_priority
------------------+--------------+------------+---------------
 rac1             | 192.168.2.21 | async      |             0
 rac3             | 192.168.3.20 | async      |             0
(2 rows)

[postgres@rac2 ~]$ psql -c "ALTER SYSTEM SET synchronous_standby_names='rac1';"
ALTER SYSTEM
[postgres@rac2 ~]$ psql -c "ALTER SYSTEM SET synchronous_commit = on;"
ALTER SYSTEM
[postgres@rac2 ~]$ psql -c "SELECT pg_reload_conf();"
 pg_reload_conf
----------------
 t  <-----
(1 row)

[postgres@rac2 ~]$

8. Validate Synchronization settings

# On Primary Node
[postgres@rac2 ~]$ psql -c "SHOW synchronous_standby_names;"
 synchronous_standby_names
---------------------------
 rac1 <-----  This is Changed to SYNC.
(1 row)

[postgres@rac2 ~]$ psql -c "SHOW synchronous_commit;"
 synchronous_commit
--------------------
 on <----
(1 row)

[postgres@rac2 ~]$

9. Summary of Results

[postgres@rac2 ~]$ psql -c "SELECT application_name, client_addr, sync_state, sync_priority FROM pg_stat_replication;"
 application_name | client_addr  | sync_state | sync_priority
------------------+--------------+------------+---------------
 rac1             | 192.168.2.21 | sync       |             1
 rac3             | 192.168.3.20 | async      |             0
(2 rows)

[postgres@rac2 ~]$

[postgres@rac2 ~]$ tail -f /pgData/pgsql17/data/log/postgresql-Sat.log
..
..
2025-10-18 05:18:17.188 EDT [1521] LOG:  parameter "synchronous_standby_names" changed to "rac1"
2025-10-18 05:18:26.727 EDT [4880] LOG:  standby "rac1" is now a synchronous standby with priority 1
2025-10-18 05:18:26.727 EDT [4880] STATEMENT:  START_REPLICATION SLOT "rac1_standby_slot" 0/1B000000 TIMELINE 2

10. Practical Test of Synchronous Replication

10.1 Check Current Status

[postgres@rac2 ~]$ psql -c "SELECT application_name, client_addr, sync_state, sync_priority FROM pg_stat_replication;"
 application_name | client_addr  | sync_state | sync_priority
------------------+--------------+------------+---------------
 rac1             | 192.168.2.21 | sync       |             1
 rac3             | 192.168.3.20 | async      |             0
(2 rows)

10.2 Insert Test Data on Primary

# On Primary :

[postgres@rac2 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=#
postgres=# CREATE TABLE emp (name TEXT, designation TEXT, project TEXT, company TEXT);
CREATE TABLE
postgres=# INSERT INTO emp VALUES ('Sugi', 'DBA', 'Jetstar', 'iGATE');
INSERT 0 1  <---- Got inserted 
postgres=#

[postgres@rac2 ~]$ psql -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
(1 row)

[postgres@rac2 ~]$

10.3 Verify Data on Sync Standby

# Standby 1 (rac1)

[postgres@rac1 ~]$ psql -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
(1 row)

[postgres@rac1 ~]$

# Standby 1 (rac3)
[postgres@rac3 ~]$ psql -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
(1 row)

[postgres@rac3 ~]$

10.4 Test Sync Behavior

On Standby 1 (rac1): shutdown

[root@rac1 ~]# systemctl stop postgresql-17.service
[root@rac1 ~]#
[root@rac1 ~]# ps -ef | grep postgres
root        4901    3426  0 12:56 pts/0    00:00:00 grep --color=auto postgres
[root@rac1 ~]#

On Primary (rac2):

[postgres@rac2 ~]$ psql -c "INSERT INTO emp VALUES ('Teja', 'DBA', 'RCM', 'iGATE');"

-- hanging, INSERT Waiting, not getting committed

# synchronous_standby_names='(rac1)', the insert will hang until rac1 (standby 1) is back online.

On Standby 2 (rac3):

[postgres@rac3 ~]$ psql -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE  <--- i can see data on ASYNC Standby server (rac3)
(2 rows)

[postgres@rac3 ~]$

10.5 Observe Primary Blocking

# Taken another session of Primary (rac2) and run as below. 

[postgres@rac2 ~]$ psql -c "SELECT pid, state, wait_event_type, wait_event FROM pg_stat_activity;"
 pid  | state  | wait_event_type |     wait_event
------+--------+-----------------+---------------------
 5620 | active | IPC             | SyncRep
 5645 | active |                 |
 5062 |        | Activity        | AutovacuumMain
 5064 |        | Activity        | LogicalLauncherMain
 5066 | active | Activity        | WalSenderMain
 5058 |        | Activity        | CheckpointerMain
 5059 |        | Activity        | BgwriterHibernate
 5061 |        | Activity        | WalWriterMain
 5063 |        | Activity        | ArchiverMain
(9 rows)

[postgres@rac2 ~]$


[postgres@rac2 ~]$ psql -c "SELECT pid, usename, application_name, client_addr, client_hostname, state, wait_event_type, wait_event FROM pg_stat_activity WHERE state = 'active';"
 pid  | usename  | application_name | client_addr  | client_hostname | state  | wait_event_type |  wait_event
------+----------+------------------+--------------+-----------------+--------+-----------------+---------------
 5656 | postgres | psql             |              |                 | active |                 |
 5620 | postgres | psql             |              |                 | active | IPC             | SyncRep
 5066 | repuser  | rac3             | 192.168.3.20 | rac3            | active | Activity        | WalSenderMain
(3 rows)

[postgres@rac2 ~]$

10.6 Restart Standby

[root@rac1 ~]# systemctl start postgresql-17.service
[root@rac1 ~]#

10.7 Observe Replication Lag

# After restart postgrel on standby 1 (rac1), INSERT statement got completed on primary.

[postgres@rac2 ~]$ psql -c "INSERT INTO emp VALUES ('Teja', 'DBA', 'RCM', 'iGATE');"
INSERT 0 1
[postgres@rac2 ~]$

# Verify lag from primary (rac2)

[postgres@rac2 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# SELECT application_name, client_addr, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn
postgres-# FROM pg_stat_replication;
 application_name | client_addr  | sync_state |  sent_lsn  | write_lsn  | flush_lsn  | replay_lsn
------------------+--------------+------------+------------+------------+------------+------------
 rac3             | 192.168.3.20 | async      | 0/26F8CF18 | 0/26F8CF18 | 0/26F8CF18 | 0/26F8CF18
 rac1             | 192.168.2.21 | sync       | 0/26F8CF18 | 0/26F8CF18 | 0/26F8CF18 | 0/26F8CF18
(2 rows)

postgres=#

[postgres@rac2 ~]$ psql -c "
> SELECT
> application_name AS standby_name,
> client_addr AS standby_ip,
> state,
> sync_state,
> pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS byte_lag
> FROM pg_stat_replication;
> "
 standby_name |  standby_ip  |   state   | sync_state | byte_lag
--------------+--------------+-----------+------------+----------
 rac3         | 192.168.3.20 | streaming | async      |        0 <---
 rac1         | 192.168.2.21 | streaming | sync       |        0 <---
(2 rows)

[postgres@rac2 ~]$

# Verify Data 

On Primary (rac2):

[postgres@rac2 ~]$ psql -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
(2 rows)

[postgres@rac2 ~]$

On Standby (rac1) 1:

[postgres@rac1 ~]$ psql -c "SELECT * FROM EMP";
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
(2 rows)

[postgres@rac1 ~]$

On Standby 2 (rac3):

[postgres@rac3 ~]$ psql -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
(2 rows)

[postgres@rac3 ~]$

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/

Failover Streaming Replication

How to Perform Manual Failover in PostgreSQL Streaming Replication (No repmgr)

Table of Contents



0. Objective : Perform Failover from rac1 β†’ rac2

PostgreSQL natively supports failover, not switchover (unlike Oracle Data Guard).
For managed or automated switchover, use tools such as repmgr or Patroni.

Notes:

  • In case of an unplanned outage or disaster recovery, if the primary becomes unreachable, promote the standby to act as the new primary.
  • The old primary must then be rebuilt as a standby using data from the new primary.
  • For production environments, use replication slots to prevent WAL loss.
  • Synchronous replication β†’ Zero data loss (commit waits for standby acknowledgment).
  • Asynchronous replication β†’ Possible data loss during failover.
  • Always check replication lag before performing a planned failover.

1. Environment Setup

NodeIPRoleSync TypePurpose
rac1192.168.2.21PrimaryasyncOld primary (will fail)
rac2192.168.2.22StandbyasyncTo be promoted as new primary
rac3192.168.3.20StandbyasyncWill remain standby after failover

2. Simulate and Confirm Primary (rac1) Failure

DISCLAIMER: The kill command given below is just for learning purposes and should only be used on testing systems. We will not take any responsibility of any consequences or loss of data caused by this command.

Note:Β In this demonstration, I used a simple KILL command to simulate a PostgreSQL failover. In real-world scenarios, failover events may occur due to factors such as server unavailability, disk corruption, or other critical system failures.

[root@rac1 data]# ps -ef | grep postgres
postgres   12125       1  0 07:56 ?        00:00:00 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data
postgres   12127   12125  0 07:56 ?        00:00:00 postgres: logger
postgres   12128   12125  0 07:56 ?        00:00:00 postgres: checkpointer
postgres   12129   12125  0 07:56 ?        00:00:00 postgres: background writer
postgres   12131   12125  0 07:56 ?        00:00:00 postgres: walwriter
postgres   12132   12125  0 07:56 ?        00:00:00 postgres: autovacuum launcher
postgres   12133   12125  0 07:56 ?        00:00:00 postgres: archiver last was 000000010000000000000017.00000028.backup
postgres   12134   12125  0 07:56 ?        00:00:00 postgres: logical replication launcher
postgres   12282   12125  0 08:08 ?        00:00:00 postgres: walsender repuser 192.168.2.22(51152) streaming 0/18023510
postgres   12283   12125  0 08:08 ?        00:00:00 postgres: walsender repuser 192.168.3.20(51354) streaming 0/18023510
root       15502    3678  0 12:52 pts/0    00:00:00 grep --color=auto postgres
[root@rac1 data]# kill -9 12125
[root@rac1 data]# ps -ef | grep postgres
root       15513    3678  0 12:52 pts/0    00:00:00 grep --color=auto postgres
[root@rac1 data]# cd
[root@rac1 ~]#

[postgres@rac1 ~]$ psql
psql: error: connection to server on socket "/run/postgresql/.s.PGSQL.5432" failed: Connection refused
        Is the server running locally and accepting connections on that socket?
[postgres@rac1 ~]$

3. Failover Procedure: Promote rac2 (Standby1) as New Primary

3.1 Promote rac2 to Primary

# use pg_ctl promote -D /pgData/pgsql17/data (or) psql -U postgres -c "SELECT pg_promote();" to initiate failover

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
                Is the server running on that host and accepting TCP/IP connections?
2025-10-17 12:57:50.553 EDT [9070] LOG:  waiting for WAL to become available at 0/18023528
2025-10-17 12:57:55.552 EDT [11746] FATAL:  could not connect to the primary server: connection to server at "192.168.2.21", port 5432 failed: Connection refused
                Is the server running on that host and accepting TCP/IP connections?
2025-10-17 12:57:55.554 EDT [9070] LOG:  waiting for WAL to become available at 0/18023528
2025-10-17 12:58:00.559 EDT [11747] FATAL:  could not connect to the primary server: connection to server at "192.168.2.21", port 5432 failed: Connection refused
                Is the server running on that host and accepting TCP/IP connections?
2025-10-17 12:58:00.562 EDT [9070] LOG:  waiting for WAL to become available at 0/18023528
2025-10-17 12:58:05.562 EDT [11748] FATAL:  could not connect to the primary server: connection to server at "192.168.2.21", port 5432 failed: Connection refused
                Is the server running on that host and accepting TCP/IP connections?
2025-10-17 12:58:05.564 EDT [9070] LOG:  waiting for WAL to become available at 0/18023528
[postgres@rac2 ~]$

[postgres@rac2 ~]$ psql -U postgres -c "SELECT pg_promote();"
 pg_promote
------------
 t  <---- Failover completed successfully.
(1 row)

[postgres@rac2 ~]$

# Verify logs
[postgres@rac2 ~]$ cat /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
2025-10-17 12:59:30.609 EDT [9070] LOG:  waiting for WAL to become available at 0/18023528
2025-10-17 12:59:32.986 EDT [9070] LOG:  received promote request
2025-10-17 12:59:32.986 EDT [9070] LOG:  redo done at 0/180234D8 system usage: CPU: user: 0.02 s, system: 0.02 s, elapsed: 17448.30 s
2025-10-17 12:59:32.986 EDT [9070] LOG:  last completed transaction was at log time 2025-10-17 08:32:12.184495-04
2025-10-17 12:59:32.987 EDT [9070] LOG:  selected new timeline ID: 2
2025-10-17 12:59:33.220 EDT [9070] LOG:  archive recovery complete
2025-10-17 12:59:33.257 EDT [9068] LOG:  checkpoint starting: force
2025-10-17 12:59:33.261 EDT [9064] LOG:  database system is ready to accept connections
2025-10-17 12:59:33.320 EDT [9068] LOG:  checkpoint complete: wrote 2 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.001 s, sync=0.017 s, total=0.064 s; sync files=2, longest=0.012 s, average=0.009 s; distance=0 kB, estimate=39825 kB; lsn=0/180235A0, redo lsn=0/18023548
2025-10-17 13:04:33.420 EDT [9068] LOG:  checkpoint starting: time
2025-10-17 13:04:33.543 EDT [9068] LOG:  checkpoint complete: wrote 1 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.101 s, sync=0.005 s, total=0.123 s; sync files=1, longest=0.005 s, average=0.005 s; distance=1 kB, estimate=35843 kB; lsn=0/18023C68, redo lsn=0/18023C10
[postgres@rac2 ~]$

3.2 Update pg_hba.conf

# Update pg_hba.conf with standby servers IP's

FROM: 

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/pg_hba.conf
..
..
# Allow standby servers for replication
host    replication    repuser    192.168.2.22/32    scram-sha-256
host    replication    repuser    192.168.3.20/32    scram-sha-256
[postgres@rac2 ~]$ 

TO:

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/pg_hba.conf
..
..
# Allow standby servers for replication
host    replication    repuser    192.168.2.21/32    scram-sha-256
host    replication    repuser    192.168.3.20/32    scram-sha-256
[postgres@rac2 ~]$ 

3.3 Reset primary_conninfo in postgresql.auto.conf

# Update primary_conninfo info on postgresql.auto.conf
# Primary node will not have primary_conninfo entires, hence we are removing from primary node.


FROM:

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.21 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac2_standby_slot'
[postgres@rac2 ~]$


TO:

[postgres@rac2 ~]$ psql -U postgres -c "ALTER SYSTEM RESET primary_conninfo;"
ALTER SYSTEM
[postgres@rac2 ~]$ psql -U postgres -c "ALTER SYSTEM RESET primary_slot_name;"
ALTER SYSTEM
[postgres@rac2 ~]$ psql -U postgres -c "SELECT pg_reload_conf();"
 pg_reload_conf
----------------
 t
(1 row)

[postgres@rac2 ~]$

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
[postgres@rac2 ~]$

3.4 Restart PostgreSQL Service

[postgres@rac2 ~]$ psql -U postgres -c "SELECT pg_reload_conf();"
 pg_reload_conf
----------------
 t
(1 row)

[postgres@rac2 ~]$

 --- OR ---

[root@rac2 ~]# systemctl stop postgresql-17.service
[root@rac2 ~]# systemctl start postgresql-17.service

4. Verify Failover Operation (rac2 is primary)

# Verify that rac2 is now primary

[postgres@rac2 ~]$ psql -U postgres -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
-------------------
 f  <---- false means Primary 
(1 row)

[postgres@rac2 ~]$

5. Reconfigure rac3 (Standby2) to Point to New Primary (rac2)

5.1 Update primary_conninfo on rac3

# Update primary_conninfo info on postgresql.auto.conf

FROM: 
[postgres@rac3 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.21 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac3_standby_slot'
[postgres@rac3 ~]$

TO:

postgres=# ALTER SYSTEM SET primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable';
ALTER SYSTEM
postgres=# ALTER SYSTEM SET primary_slot_name = 'rac3_standby_slot';
ALTER SYSTEM
postgres=#
postgres=# SELECT pg_reload_conf();
 pg_reload_conf
----------------
 t
(1 row)

postgres=#

[postgres@rac3 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac3_standby_slot'
[postgres@rac3 ~]$

[postgres@rac3 ~]$ psql -U postgres -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
-------------------
 t  <---- True means Standby
(1 row)

[postgres@rac3 ~]$

5.2 Update pg_hba.conf

[postgres@rac3 ~]$ cat /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
                Is the server running on that host and accepting TCP/IP connections?
2025-10-17 13:00:30.625 EDT [8688] LOG:  waiting for WAL to become available at 0/18023528
2025-10-17 13:00:35.627 EDT [11404] FATAL:  could not connect to the primary server: connection to server at "192.168.2.21", port 5432 failed: Connection refused
                Is the server running on that host and accepting TCP/IP connections?
2025-10-17 13:00:35.629 EDT [8688] LOG:  waiting for WAL to become available at 0/18023528
[postgres@rac3 ~]$

# Update pg_hba.conf

FROM: 

[postgres@rac3 ~]$ cat /pgData/pgsql17/data/pg_hba.conf
..
..
# Allow standby servers for replication
host    replication    repuser    192.168.2.22/32    scram-sha-256
host    replication    repuser    192.168.3.20/32    scram-sha-256
[postgres@rac3 ~]$

TO:

[postgres@rac3 ~]$ cat /pgData/pgsql17/data/pg_hba.conf
..
..
# Allow standby servers for replication
host    replication    repuser    192.168.2.21/32    scram-sha-256
host    replication    repuser    192.168.3.20/32    scram-sha-256
[postgres@rac3 ~]$

5.3 Restart PostgreSQL Service

[postgres@rac3 ~]$ psql -U postgres -c "SELECT pg_reload_conf();"
 pg_reload_conf
----------------
 t
(1 row)

[postgres@rac3 ~]$

 --- OR ---

[root@rac3 ~]# systemctl stop postgresql-17.service
[root@rac3 ~]# systemctl start postgresql-17.service

6. Data Validation Test – Change 1

6.1 Insert Data on New Primary and Verify logs

On Primary (rac2)

[postgres@rac2 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# SELECT * FROM EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

postgres=# INSERT INTO emp VALUES ('KK', 'DBA LEAD', 'RCM', 'iGATE');
INSERT 0 1
postgres=# SELECT * FROM EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE <-----
(4 rows)

postgres=#

2025-10-17 13:57:30.510 EDT [12525] ERROR:  replication slot "rac3_standby_slot" does not exist
2025-10-17 13:57:30.510 EDT [12525] STATEMENT:  START_REPLICATION SLOT "rac3_standby_slot" 0/18000000 TIMELINE 2

6.2 Create replication slot (rac3_standby_slot) on New Primary

# On new primary 

[postgres@rac2 ~]$ psql -U postgres -c "SELECT * FROM pg_create_physical_replication_slot('rac3_standby_slot');"
     slot_name     | lsn
-------------------+-----
 rac3_standby_slot |
(1 row)

[postgres@rac2 ~]$

2025-10-17 13:59:30.571 EDT [12570] ERROR:  replication slot "rac3_standby_slot" does not exist
2025-10-17 13:59:30.571 EDT [12570] STATEMENT:  START_REPLICATION SLOT "rac3_standby_slot" 0/18000000 TIMELINE 2
2025-10-17 13:59:34.554 EDT [9068] LOG:  checkpoint starting: time
2025-10-17 13:59:34.681 EDT [9068] LOG:  checkpoint complete: wrote 2 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.102 s, sync=0.006 s, total=0.127 s; sync files=2, longest=0.004 s, average=0.003 s; distance=0 kB, estimate=32259 kB; lsn=0/18023EF0, redo lsn=0/18023E98
2025-10-17 13:59:35.572 EDT [12571] ERROR:  replication slot "rac3_standby_slot" does not exist
2025-10-17 13:59:35.572 EDT [12571] STATEMENT:  START_REPLICATION SLOT "rac3_standby_slot" 0/18000000 TIMELINE 2
2025-10-17 13:59:40.577 EDT [12572] ERROR:  replication slot "rac3_standby_slot" does not exist
2025-10-17 13:59:40.577 EDT [12572] STATEMENT:  START_REPLICATION SLOT "rac3_standby_slot" 0/18000000 TIMELINE 2
2025-10-17 13:59:45.580 EDT [12574] ERROR:  replication slot "rac3_standby_slot" does not exist
2025-10-17 13:59:45.580 EDT [12574] STATEMENT:  START_REPLICATION SLOT "rac3_standby_slot" 0/18000000 TIMELINE 2
2025-10-17 13:59:50.581 EDT [12575] ERROR:  replication slot "rac3_standby_slot" does not exist
2025-10-17 13:59:50.581 EDT [12575] STATEMENT:  START_REPLICATION SLOT "rac3_standby_slot" 0/18000000 TIMELINE 2
[postgres@rac2 ~]$

[postgres@rac2 ~]$ psql -U postgres -c "
> SELECT
> application_name AS standby_name,
> client_addr AS standby_ip,
> state,
> sync_state,
> pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS byte_lag
> FROM pg_stat_replication;
> "
 standby_name |  standby_ip  |   state   | sync_state | byte_lag
--------------+--------------+-----------+------------+----------
 walreceiver  | 192.168.3.20 | streaming | async      |        0  <--- no lag
(1 row)

[postgres@rac2 ~]$

*** Afrer few seconds there were no errors reported in the logs.

6.3 Verify Data on Standby and logs

postgres=# SELECT * FROM EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE  <----
(4 rows)

postgres=#

2025-10-17 13:59:50.581 EDT [12669] FATAL:  could not start WAL streaming: ERROR:  replication slot "rac3_standby_slot" does not exist
2025-10-17 13:59:50.584 EDT [8688] LOG:  waiting for WAL to become available at 0/18002000
2025-10-17 13:59:55.583 EDT [12670] LOG:  started streaming WAL from primary at 0/18000000 on timeline 2
2025-10-17 13:59:57.951 EDT [8686] LOG:  restartpoint starting: time
2025-10-17 13:59:58.183 EDT [8686] LOG:  restartpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.207 s, sync=0.009 s, total=0.232 s; sync files=3, longest=0.005 s, average=0.003 s; distance=2 kB, estimate=13284 kB; lsn=0/18023EF0, redo lsn=0/18023E98
2025-10-17 13:59:58.183 EDT [8686] LOG:  recovery restart point at 0/18023E98
2025-10-17 13:59:58.183 EDT [8686] DETAIL:  Last completed transaction was at log time 2025-10-17 13:55:47.944361-04.
[postgres@rac3 ~]$

*** Afrer few seconds there were no errors reported in the logs.

7. Data Validation Test – Change 2

7.1 Create Table and Insert Data on New Primary

[postgres@rac2 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# CREATE TABLE test_failover(id serial primary key, msg text);
CREATE TABLE
postgres=# INSERT INTO test_failover(msg) VALUES ('Replication working after failover');
INSERT 0 1
postgres=#
postgres=#
postgres=# SELECT * FROM test_failover;
 id |                msg
----+------------------------------------
  1 | Replication working after failover
(1 row)

postgres=#

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
2025-10-17 14:29:35.647 EDT [9068] LOG:  checkpoint starting: time
2025-10-17 14:29:40.208 EDT [9068] LOG:  checkpoint complete: wrote 45 buffers (0.3%); 0 WAL file(s) added, 0 removed, 0 recycled; write=4.436 s, sync=0.092 s, total=4.561 s; sync files=38, longest=0.037 s, average=0.003 s; distance=184 kB, estimate=26162 kB; lsn=0/18077EA8, redo lsn=0/18077E50
[postgres@rac2 ~]$

*** No errors reported in the logs.

7.2 Verify Data on Standby

[postgres@rac3 ~]$ psql -U postgres -c "SELECT * FROM test_failover;"
 id |                msg
----+------------------------------------
  1 | Replication working after failover  <---- Working as expected.
(1 row)

[postgres@rac3 ~]$

[postgres@rac3 ~]$ cat /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
2025-10-17 14:29:52.637 EDT [12847] LOG:  restartpoint starting: time
2025-10-17 14:29:57.261 EDT [12847] LOG:  restartpoint complete: wrote 46 buffers (0.3%); 0 WAL file(s) added, 0 removed, 0 recycled; write=4.537 s, sync=0.072 s, total=4.624 s; sync files=38, longest=0.015 s, average=0.002 s; distance=184 kB, estimate=184 kB; lsn=0/18077EA8, redo lsn=0/18077E50
2025-10-17 14:29:57.261 EDT [12847] LOG:  recovery restart point at 0/18077E50
2025-10-17 14:29:57.261 EDT [12847] DETAIL:  Last completed transaction was at log time 2025-10-17 14:28:28.964977-04.
[postgres@rac3 ~]$

*** No errors reported in the logs.

8. Rebuild Old Primary (rac1) as Standby (Optional / Later Step)

Rebuild using pg_basebackup (Clean and reliable, always works)

8.1 Stop PostgreSQL if Running

[root@rac1 ~]# systemctl stop postgresql-17.service
[root@rac1 ~]#
[root@rac1 ~]# ps -ef | grep postgres
root       16544    3678  0 14:43 pts/0    00:00:00 grep --color=auto postgres
[root@rac1 ~]#

8.2 Delete DATA, WAL, and ARCHIVE Files

[root@rac1 ~]# su - postgres
[postgres@rac1 ~]$ 

[postgres@rac1 ~]$ rm -rf /pgData/pgsql17/data/*
[postgres@rac1 ~]$ rm -rf /pgWal/pgsql17/wal/*
[postgres@rac1 ~]$ rm -rf /pgArch/pgsql17/arch/*
[postgres@rac1 ~]$

8.3 Perform Backup from Primary to Rebuild rac1 as Standby

[postgres@rac1 ~]$ pg_basebackup -h 192.168.2.22 -U repuser -p 5432 -D /pgData/pgsql17/data -Fp -Xs -P -R -C -S rac1_standby_slot
Password:
24643/24643 kB (100%), 1/1 tablespace
[postgres@rac1 ~]$

8.4 Verify postgresql.auto.conf and standby.signal

[postgres@rac1 ~]$ ls -ltr  /pgData/pgsql17/data/standby.signal
-rw-------. 1 postgres postgres 0 Oct 17 14:49 /pgData/pgsql17/data/standby.signal
[postgres@rac1 ~]$
[postgres@rac1 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.22 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac1_standby_slot'
[postgres@rac1 ~]$

8.5 Start PostgreSQL on rac1

[root@rac1 ~]# systemctl start postgresql-17.service
[root@rac1 ~]#

[postgres@rac1 ~]$ cat /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
2025-10-17 14:54:36.566 EDT [16742] LOG:  starting PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-26), 64-bit
2025-10-17 14:54:36.566 EDT [16742] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-10-17 14:54:36.573 EDT [16742] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2025-10-17 14:54:36.586 EDT [16742] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2025-10-17 14:54:36.596 EDT [16748] LOG:  database system was interrupted; last known up at 2025-10-17 14:49:32 EDT
2025-10-17 14:54:38.095 EDT [16748] LOG:  starting backup recovery with redo LSN 0/19000028, checkpoint LSN 0/19000080, on timeline ID 2
2025-10-17 14:54:38.095 EDT [16748] LOG:  entering standby mode
2025-10-17 14:54:38.106 EDT [16748] LOG:  redo starts at 0/19000028
2025-10-17 14:54:38.111 EDT [16748] LOG:  completed backup recovery with redo LSN 0/19000028 and end LSN 0/19000120
2025-10-17 14:54:38.111 EDT [16748] LOG:  consistent recovery state reached at 0/19000120
2025-10-17 14:54:38.112 EDT [16742] LOG:  database system is ready to accept read-only connections
2025-10-17 14:54:38.181 EDT [16749] LOG:  started streaming WAL from primary at 0/1A000000 on timeline 2
[postgres@rac1 ~]$

*** No errors reported in the logs.

9. Replication Verification – Change 3

9.1 Load Test Data into Table on Primary (rac2)

# Verify lag from Primary node

[postgres@rac2 ~]$ psql -U postgres -c "
> SELECT
> application_name AS standby_name,
> client_addr AS standby_ip,
> state,
> sync_state,
> pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS byte_lag
> FROM pg_stat_replication;
> "
 standby_name |  standby_ip  |   state   | sync_state | byte_lag
--------------+--------------+-----------+------------+----------
 walreceiver  | 192.168.2.21 | streaming | async      |        0
 walreceiver  | 192.168.3.20 | streaming | async      |        0
(2 rows)

[postgres@rac2 ~]$
[postgres@rac2 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \x
Expanded display is on.
postgres=# select * from pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 13145
usesysid         | 16452
usename          | repuser
application_name | walreceiver
client_addr      | 192.168.2.21
client_hostname  |
client_port      | 40334
backend_start    | 2025-10-17 14:54:38.15459-04
backend_xmin     |
state            | streaming
sent_lsn         | 0/1A000430
write_lsn        | 0/1A000430
flush_lsn        | 0/1A000430
replay_lsn       | 0/1A000430
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 0
sync_state       | async
reply_time       | 2025-10-17 17:05:39.286255-04
-[ RECORD 2 ]----+------------------------------
pid              | 12747
usesysid         | 16452
usename          | repuser
application_name | walreceiver
client_addr      | 192.168.3.20
client_hostname  |
client_port      | 36018
backend_start    | 2025-10-17 14:16:07.947815-04
backend_xmin     |
state            | streaming
sent_lsn         | 0/1A000430
write_lsn        | 0/1A000430
flush_lsn        | 0/1A000430
replay_lsn       | 0/1A000430
write_lag        |
flush_lag        |
replay_lag       |
sync_priority    | 0
sync_state       | async
reply_time       | 2025-10-17 17:05:39.320194-04

postgres=#

# Verify Replication slots
[postgres@rac2 ~]$ psql -U postgres -c "SELECT slot_name, slot_type, database, active FROM pg_replication_slots;"
     slot_name     | slot_type | database | active
-------------------+-----------+----------+--------
 rac3_standby_slot | physical  |          | t
 rac1_standby_slot | physical  |          | t
(2 rows)

[postgres@rac2 ~]$

[postgres@rac2 ~]$ psql -U postgres -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE
(4 rows)

[postgres@rac2 ~]$ psql -U postgres -c "INSERT INTO emp VALUES ('DEV', 'DBA MANAGER', 'RCM', 'iGATE');"
INSERT 0 1
[postgres@rac2 ~]$
[postgres@rac2 ~]$ psql -U postgres -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE
 DEV  | DBA MANAGER | RCM     | iGATE <---
(5 rows)

[postgres@rac2 ~]$

9.2 Monitor Replication on Standby 1 (rac1)

[postgres@rac1 ~]$ psql -U postgres -c "SELECT slot_name, slot_type, database, active FROM pg_replication_slots;"
 slot_name | slot_type | database | active
-----------+-----------+----------+--------
(0 rows)

[postgres@rac1 ~]$

[postgres@rac1 ~]$ psql -U postgres -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE
 DEV  | DBA MANAGER | RCM     | iGATE <---
(5 rows)

[postgres@rac1 ~]$

9.3 Monitor Replication on Standby 2 (rac3)

[postgres@rac3 ~]$ psql -U postgres -c "SELECT slot_name, slot_type, database, active FROM pg_replication_slots;"
 slot_name | slot_type | database | active
-----------+-----------+----------+--------
(0 rows)

[postgres@rac3 ~]$
[postgres@rac3 ~]$ psql -U postgres -c "SELECT * FROM EMP;"
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE
 DEV  | DBA MANAGER | RCM     | iGATE <---
(5 rows)

[postgres@rac3 ~]$

10. Log Verification

10.1 Check Logs on Primary

[postgres@rac2 ~]$ tail -100 /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
2025-10-17 14:54:32.813 EDT [9068] LOG:  checkpoint starting: time
2025-10-17 14:54:32.860 EDT [9068] LOG:  checkpoint complete: wrote 0 buffers (0.0%); 0 WAL file(s) added, 0 removed, 1 recycled; write=0.001 s, sync=0.001 s, total=0.048 s; sync files=0, longest=0.000 s, average=0.000 s; distance=16384 kB, estimate=24261 kB; lsn=0/1A0000B8, redo lsn=0/1A000060
2025-10-17 15:04:33.059 EDT [9068] LOG:  checkpoint starting: time
2025-10-17 15:04:33.219 EDT [9068] LOG:  checkpoint complete: wrote 2 buffers (0.0%); 0 WAL file(s) added, 0 removed, 2 recycled; write=0.101 s, sync=0.007 s, total=0.160 s; sync files=2, longest=0.005 s, average=0.004 s; distance=0 kB, estimate=21835 kB; lsn=0/1A000380, redo lsn=0/1A000328
[postgres@rac2 ~]$

*** No errors reported in the logs.

10.2 Check Logs on Standby 1 (rac1)

[postgres@rac1 ~]$ tail -100 /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
2025-10-17 15:04:36.818 EDT [16746] LOG:  restartpoint starting: time
2025-10-17 15:04:36.946 EDT [16746] LOG:  restartpoint complete: wrote 2 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.107 s, sync=0.007 s, total=0.129 s; sync files=2, longest=0.005 s, average=0.004 s; distance=0 kB, estimate=14745 kB; lsn=0/1A000380, redo lsn=0/1A000328
2025-10-17 15:04:36.946 EDT [16746] LOG:  recovery restart point at 0/1A000328
2025-10-17 15:04:36.946 EDT [16746] DETAIL:  Last completed transaction was at log time 2025-10-17 15:03:38.479334-04.
[postgres@rac1 ~]$

*** No errors reported in the logs.

10.3 Check Logs on Standby 2 (rac3)

[postgres@rac3 ~]$ tail -100 /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
..
2025-10-17 15:04:38.825 EDT [12847] LOG:  restartpoint starting: time
2025-10-17 15:04:38.950 EDT [12847] LOG:  restartpoint complete: wrote 2 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.102 s, sync=0.008 s, total=0.125 s; sync files=2, longest=0.005 s, average=0.004 s; distance=0 kB, estimate=14745 kB; lsn=0/1A000380, redo lsn=0/1A000328
2025-10-17 15:04:38.950 EDT [12847] LOG:  recovery restart point at 0/1A000328
2025-10-17 15:04:38.950 EDT [12847] DETAIL:  Last completed transaction was at log time 2025-10-17 15:03:38.479334-04.
[postgres@rac3 ~]$

*** No errors reported in the logs.

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/

PostgreSQL Streaming Replication

How To Configure Streaming Replication inΒ PostgreSQL

Table of Contents


On Master (rac1)

On Standby (rac2, rac3)


A. Environment

HostnameIPOSVersionRoleHot StandbyReplicationSync type
rac1192.168.2.21LinuxPostgreSQL 17Primary
rac2192.168.2.22LinuxPostgreSQL 17StandbyYes (Active DG)Streamingasync (Maximum Performance)
rac3192.168.3.20LinuxPostgreSQL 17StandbyYes (Active DG)Streamingasync (Maximum Performance)

0. Pre-requisites

1. Install PostgreSQL on all servers (rac1, rac2, rac3)
2. Ensure network connectivity (port 5432) between nodes
3. Ensure same PostgreSQL version and paths on all nodes

Overview: 

Physical streaming replication works at the cluster level, not at the database level in PostgreSQL.
Physical (streaming) replication = whole cluster
Logical replication = per database or table

Streaming replication is a way to keep one or more standby servers in sync with a primary server in real-time.
It ensures that all changes made on the primary database are continuously sent to the standby servers. This provides high availability and read scaling.

How It Works:

1. Primary records changes

Every change (INSERT, UPDATE, DELETE) is first written to the WAL (Write-Ahead Log) on the primary server.

2. Standbys connect to the primary

Each standby uses its connection info (primary_conninfo) to connect to the primary.

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.21 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac2_standby_slot'
[postgres@rac2 ~]$


3. Primary sends WAL to standbys

Once the connection is established, the primary streams the WAL changes to the standbys continuously.

4. Standbys apply changes

Standbys receive WAL and replay it to stay in sync with the primary. Hot standbys can even allow read-only queries while receiving data.

5. Replication modes

Asynchronous: Primary doesn’t wait for standby, standby may lag slightly. (Maximum Performance)
Synchronous: Primary waits for standby acknowledgment before committing. zero data loss. (Maximum Protection).

6. Important Notes:

Asynchronous = Maximum Performance (Oracle) - Safe

Replication slots retain WAL files, so if a standby goes offline for a long time, disk usage can grow on the primary. Monitor pg_wal size.
If a standby is permanently removed, drop the slot to free space.
WAL retention can grow β†’ monitor pg_wal size.
Primary keeps working even if standby is down.

Synchronous =  Maximum Protection (Oracle) - Critical

WAL retention isn’t the main concern, because transactions won’t commit on primary if the standby is offline.
Disk usage won’t grow indefinitely due to WALs for the offline standby, but the primary database pauses writes until the standby returns online.

7. Simple Analogy

Imagine the primary is a teacher writing on a blackboard.
The standbys are students copying the board in real-time.
As the teacher writes (WAL logs), students continuously copy (replay WAL) so everyone stays synchronized.
Some students may write slightly slower (async), or the teacher may wait for all students to copy before continuing (sync).

On Master:

1. Create Replication User (Primary – rac1)

# The replication user can stream WAL and connect as standby.
postgres=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS

postgres=#
postgres=# create user repuser with replication encrypted password 'repuser';
CREATE ROLE
postgres=#
postgres=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS
 repuser   | Replication

postgres=#

2. Update postgresql.conf (Primary – rac1)

# Edit postgresql.conf

listen_addresses = '0.0.0.0' # ipv4 only
wal_level = 'replica'
hot_standby = on

archive_mode = on
archive_command = 'cp %p /pgArch/pgsql17/arch/%f'

max_wal_senders = 10
max_replication_slots = 10
wal_log_hints = on

# End 

3. Update pg_hba.conf (Primary – rac1)

# replication privilege.
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust

# Allow standby servers for replication
host    replication    repuser    192.168.2.22/32    scram-sha-256
host    replication    repuser    192.168.3.20/32    scram-sha-256

4. Restart Configuration (Primary – rac1)

[root@rac1 ~]# systemctl stop postgresql-17.service
[root@rac1 ~]# systemctl start postgresql-17.service
[root@rac1 ~]#

postgres=# show wal_level;
 wal_level
-----------
 replica <--- 
(1 row)

postgres=# show hot_standby;
 hot_standby
-------------
 on <----
(1 row)

postgres=# show listen_addresses;
 listen_addresses
------------------
 0.0.0.0
(1 row)

postgres=#

On Standbys

5. Stop PostgreSQL on Standbys

5.1 Run from rac2

[root@rac2 ~]# systemctl stop postgresql-17.service
[root@rac2 ~]#

5.2 Run from rac3

[root@rac3 ~]# systemctl stop postgresql-17.service
[root@rac3 ~]#

6. Delete all files under data directory

6.1 Run from rac2

[postgres@rac2 ~]$ rm -rf /pgData/pgsql17/data/*
[postgres@rac2 ~]$ rm -rf /pgWal/pgsql17/wal/*
[postgres@rac2 ~]$ rm -rf /pgArch/pgsql17/arch/*

6.2 Run from rac3

[postgres@rac3 ~]$ rm -rf /pgData/pgsql17/data/*
[postgres@rac3 ~]$ rm -rf /pgWal/pgsql17/wal/*
[postgres@rac3 ~]$ rm -rf /pgArch/pgsql17/arch/*

7. Run the backup on the standby to copy data from the primary

7.1 Run from rac2

# Each standby must have a unique slot name
# Physical slots are only for streaming replication, not logical replication.
# Oracle - ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY = rac2_standby_slot
# Replication slots retain WAL files until apply on standby

[postgres@rac2 ~]$ pg_basebackup -h 192.168.2.21 -U repuser -p 5432 -D /pgData/pgsql17/data -Fp -Xs -P -R -C -S rac2_standby_slot
Password:
24406/24406 kB (100%), 1/1 tablespace
[postgres@rac2 ~]$

7.2 Run from rac3

# Each standby must have a unique slot name
# Physical slots are only for streaming replication, not logical replication.
# Oracle - ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY = rac3_standby_slot
# Replication slots retain WAL files until apply on standby

[postgres@rac3 ~]$ pg_basebackup -h 192.168.2.21 -U repuser -p 5432 -D /pgData/pgsql17/data -Fp -Xs -P -R -C -S rac3_standby_slot
Password:
24407/24407 kB (100%), 1/1 tablespace
[postgres@rac3 ~]$

8. Verify primary_conninfo on Standbys

8.1 Run from rac2

# This automatically creates physical replication slots on the primary while taking the base backup.
# Check primary_conninfo in postgresql.auto.conf

[postgres@rac2 ~]$ ls -ltr  /pgData/pgsql17/data/postgresql.auto.conf
-rw-------. 1 postgres postgres 452 Oct 17 07:56 /pgData/pgsql17/data/postgresql.auto.conf
[postgres@rac2 ~]$
[postgres@rac2 ~]$ ls -ltr  /pgData/pgsql17/data/standby.signal
-rw-------. 1 postgres postgres 0 Oct 17 07:56 /pgData/pgsql17/data/standby.signal
[postgres@rac2 ~]$

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.21 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac2_standby_slot'
[postgres@rac2 ~]$

8.2 Run from rac3


# This automatically creates physical replication slots on the primary while taking the base backup.
# Check primary_conninfo in postgresql.auto.conf

[postgres@rac3 ~]$ ls -ltr  /pgData/pgsql17/data/postgresql.auto.conf
-rw-------. 1 postgres postgres 452 Oct 17 08:00 /pgData/pgsql17/data/postgresql.auto.conf
[postgres@rac3 ~]$
[postgres@rac3 ~]$ ls -ltr  /pgData/pgsql17/data/standby.signal
-rw-------. 1 postgres postgres 0 Oct 17 08:00 /pgData/pgsql17/data/standby.signal
[postgres@rac3 ~]$
[postgres@rac3 ~]$ cat /pgData/pgsql17/data/postgresql.auto.conf
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo = 'user=repuser password=repuser channel_binding=prefer host=192.168.2.21 port=5432 sslmode=prefer sslnegotiation=postgres sslcompression=0 sslcertmode=allow sslsni=1 ssl_min_protocol_version=TLSv1.2 gssencmode=prefer krbsrvname=postgres gssdelegation=0 target_session_attrs=any load_balance_hosts=disable'
primary_slot_name = 'rac3_standby_slot'
[postgres@rac3 ~]$

9. Start PostgreSQL on Standbys

9.1 Run from rac2

[root@rac2 ~]# systemctl start postgresql-17.service
[root@rac2 ~]#

[postgres@rac2 ~]$ cat /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
2025-10-17 08:08:43.168 EDT [9064] LOG:  starting PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-26), 64-bit
2025-10-17 08:08:43.169 EDT [9064] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-10-17 08:08:43.175 EDT [9064] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2025-10-17 08:08:43.187 EDT [9064] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2025-10-17 08:08:43.198 EDT [9070] LOG:  database system was interrupted; last known up at 2025-10-17 07:56:39 EDT
2025-10-17 08:08:44.673 EDT [9070] LOG:  starting backup recovery with redo LSN 0/15000028, checkpoint LSN 0/15000080, on timeline ID 1
2025-10-17 08:08:44.673 EDT [9070] LOG:  entering standby mode
2025-10-17 08:08:44.684 EDT [9070] LOG:  redo starts at 0/15000028
2025-10-17 08:08:44.689 EDT [9070] LOG:  completed backup recovery with redo LSN 0/15000028 and end LSN 0/15000120
2025-10-17 08:08:44.689 EDT [9070] LOG:  consistent recovery state reached at 0/15000120
2025-10-17 08:08:44.689 EDT [9064] LOG:  database system is ready to accept read-only connections
2025-10-17 08:08:44.760 EDT [9071] LOG:  started streaming WAL from primary at 0/16000000 on timeline 1
[postgres@rac2 ~]$

9.2 Run from rac3

[root@rac3 ~]# systemctl start postgresql-17.service
[root@rac3 ~]#

[postgres@rac3 ~]$ cat /pgData/pgsql17/data/log/postgresql-Fri.log
..
..
2025-10-17 08:08:53.603 EDT [8683] LOG:  starting PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-26), 64-bit
2025-10-17 08:08:53.604 EDT [8683] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-10-17 08:08:53.612 EDT [8683] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2025-10-17 08:08:53.623 EDT [8683] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2025-10-17 08:08:53.634 EDT [8688] LOG:  database system was interrupted; last known up at 2025-10-17 08:00:22 EDT
2025-10-17 08:08:55.128 EDT [8688] LOG:  starting backup recovery with redo LSN 0/17000028, checkpoint LSN 0/17000080, on timeline ID 1
2025-10-17 08:08:55.128 EDT [8688] LOG:  entering standby mode
2025-10-17 08:08:55.139 EDT [8688] LOG:  redo starts at 0/17000028
2025-10-17 08:08:55.144 EDT [8688] LOG:  completed backup recovery with redo LSN 0/17000028 and end LSN 0/17000158
2025-10-17 08:08:55.144 EDT [8688] LOG:  consistent recovery state reached at 0/17000158
2025-10-17 08:08:55.144 EDT [8683] LOG:  database system is ready to accept read-only connections
2025-10-17 08:08:55.206 EDT [8689] LOG:  started streaming WAL from primary at 0/18000000 on timeline 1
[postgres@rac3 ~]$

10. Verify Streaming Replication

10.1 Run from rac1

[postgres@rac1 ~]$ psql -U postgres -c "SELECT pid, client_addr, state, sync_state FROM pg_stat_replication;"
  pid  | client_addr  |   state   | sync_state
-------+--------------+-----------+------------
 12282 | 192.168.2.22 | streaming | async
 12283 | 192.168.3.20 | streaming | async
(2 rows)

[postgres@rac1 ~]$ 

[postgres@rac1 ~]$ psql -U postgres -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
-------------------
 f  <---- it means primary
(1 row)

[postgres@rac1 ~]$

postgres=# SELECT * FROM pg_replication_slots;
     slot_name     | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase | inactive_since |
 conflicting | invalidation_reason | failover | synced
-------------------+--------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+-----------+----------------+
-------------+---------------------+----------+--------
 rac2_standby_slot |        | physical  |        |          | f         | t      |      12282 |      |              | 0/18023510  |                     | reserved   |               | f         |                |
             |                     | f        | f
 rac3_standby_slot |        | physical  |        |          | f         | t      |      12283 |      |              | 0/18023510  |                     | reserved   |               | f         |                |
             |                     | f        | f
(2 rows)

postgres=#

postgres=# CREATE TABLE emp (name TEXT, designation TEXT, project TEXT, company TEXT);
CREATE TABLE
postgres=# INSERT INTO emp VALUES ('Sugi', 'DBA', 'Jetstar', 'iGATE');
INSERT 0 1
postgres=# INSERT INTO emp VALUES ('Teja', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
postgres=# INSERT INTO emp VALUES ('RAJ', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
postgres=#
postgres=# SELECT * FROM EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

postgres=#

10.2 Run from rac2


[postgres@rac2 ~]$ psql -U postgres -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
-------------------
 t <---- it means standby
(1 row)

[postgres@rac2 ~]$
[postgres@rac2 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# SELECT * FROM EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

postgres=#

2025-10-17 08:13:43.297 EDT [9068] LOG:  restartpoint starting: time
2025-10-17 08:13:43.333 EDT [9068] LOG:  restartpoint complete: wrote 1 buffers (0.0%); 0 WAL file(s) added, 0 removed, 3 recycled; write=0.002 s, sync=0.001 s, total=0.037 s; sync files=0, longest=0.000 s, average=0.000 s; distance=49152 kB, estimate=49152 kB; lsn=0/180000B8, redo lsn=0/18000060
2025-10-17 08:13:43.333 EDT [9068] LOG:  recovery restart point at 0/18000060
[postgres@rac2 ~]$

10.3 Run from rac3


[postgres@rac3 ~]$ psql -U postgres -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
-------------------
 t <---- it means standby
(1 row)

[postgres@rac3 ~]$
[postgres@rac3 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# SELECT * FROM EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

postgres=#

2025-10-17 08:13:53.731 EDT [8686] LOG:  restartpoint starting: time
2025-10-17 08:13:53.757 EDT [8686] LOG:  restartpoint complete: wrote 1 buffers (0.0%); 0 WAL file(s) added, 0 removed, 1 recycled; write=0.002 s, sync=0.001 s, total=0.026 s; sync files=0, longest=0.000 s, average=0.000 s; distance=16384 kB, estimate=16384 kB; lsn=0/180000B8, redo lsn=0/18000060
2025-10-17 08:13:53.757 EDT [8686] LOG:  recovery restart point at 0/18000060
[postgres@rac3 ~]$

11 Verify lag from rac1 (Primary)

[postgres@rac1 ~]$ psql -U postgres -c "
> SELECT
> application_name AS standby_name,
> client_addr AS standby_ip,
> state,
> sync_state,
> pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS byte_lag
> FROM pg_stat_replication;
> "
standby_name | standby_ip | state | sync_state | byte_lag
--------------+--------------+-----------+------------+----------
walreceiver | 192.168.2.22 | streaming | async | 0
walreceiver | 192.168.3.20 | streaming | async | 0
(2 rows)

[postgres@rac1 ~]$

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/

PostgreSQL Point-in-Time Recovery (PITR)

PostgreSQL PITR: How to Restore & Recover to a Specific Point in Time

Table of Contents



0. Goal

Scenario: Application team deleted critical data at 2025-10-12 22:05:29 PM.

Action: Recover database to 2025-10-12 22:05:00 PM using base backup and WAL archives. 
---> Restore and recover on other server
---> Take backup of table
---> Restore the table back.

pg_basebackup works at the cluster level, not at the single database level. Please keep this in mind.

In the following example, I’m demonstrating Point-In-Time Recovery (PITR) for a single database by restoring the entire cluster on another server, then exporting the recovered data (dropped table) for the specific database and restoring it back to the original environment.

1. Environment (Source / Target)

AspectSourceTargetDifference
Hostnamelxicbpgdsgv01lxicbpgdsgv02Different hostnames
IP Address192.168.2.51192.168.2.52Different IPs
OSRHEL 9RHEL 9Same
DB VersionPostgreSQL v17.6PostgreSQL v17.6Same
Archive modearchive_mode=onarchive_mode=onSame
PGDATA/pgData/pgsql17/data/pgdata/pgsql17/dataDifferent path case (D vs d)
WAL Directory/pgWal/pgsql17/wal/pgwal/pgsql17/walDifferent path case (W vs w)
WAL Archive Directory/pgArch/pgsql17/arch/pgarchive/pgsql17/archiveDifferent directory case (A vs a)
Backup Directory/pgBackup/pgsql17/backup/pgbackup/pgsql17/backupDifferent path case (B vs b)
restore_commandNot Applicable/pgbackup/pgsql17/backup/archive_bkp12OCT2025restore_command on target for full recovery
recovery_target_timeTable dropped at 2025-10-12 22:05:29Recover until 2025-10-12 22:05:00recovery_target_time on target for PITR
Tablespace & PathDELL_TB_DATA:/pgTb/pgsql17/tbs/delltbs01, ORCL_TB_DATA:/pgTb/pgsql17/tbs/orcltbs01DELL_TB_DATA:/pgtsdata01/pgsql17/tbs/delltbs01, ORCL_TB_DATA:/pgtsdata01/pgsql17/tbs/orcltbs01Same tablespaces, different locations
DatabasesDELL, ORCLWe will restore both from backupBoth databases will be restored

2. Verify Existing DB Setup

[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \l+
                                                                                        List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   |  Tablespace  |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+--------------+--------------------------------------------
 dell      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7755 kB | dell_tb_data |
 orcl      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7569 kB | orcl_tb_data |
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 492 MB  | pg_default   | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default   | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |              |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7569 kB | pg_default   | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |              |
(5 rows)

postgres=# \db
                  List of tablespaces
     Name     |  Owner   |          Location
--------------+----------+-----------------------------
 dell_tb_data | postgres | /pgTb/pgsql17/tbs/delltbs01
 orcl_tb_data | postgres | /pgTb/pgsql17/tbs/orcltbs01
 pg_default   | postgres |
 pg_global    | postgres |
(4 rows)

postgres=#

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=# select * from test.emp;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE
(4 rows)

dell=#

3. Pre-requisites

3.1. Verify postgresql.conf

postgres=# SHOW wal_level;
 wal_level
-----------
 replica
(1 row)

postgres=# show archive_mode;
 archive_mode
--------------
 on
(1 row)

postgres=# show archive_command;
        archive_command
-------------------------------
 cp %p /pgArch/pgsql17/arch/%f
(1 row)

postgres=#

3.2. Verify pg_hba.conf

# TYPE  DATABASE        USER            ADDRESS             METHOD
# Local connections for replication (for pg_basebackup run locally)
local   replication     all                                 trust

# Remote connections for replication (for pg_basebackup run remotely)
#host    replication     repl_user       192.168.2.52/32     scram-sha-256

3.3. Verify User Permissions (REPLICATION or SUPERUSER)

postgres=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS

postgres=#

3.4. Verify Free Space for Backup

[postgres@lxicbpgdsgv01 ~]$ df -h /pgBackup
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdd1       100G  746M  100G   1% /pgBackup
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ mkdir -p /pgBackup/pgsql17/backup/base_bkp12OCT2025
[postgres@lxicbpgdsgv01 ~]$ mkdir -p /pgBackup/pgsql17/backup/archive_bkp12OCT2025
[postgres@lxicbpgdsgv01 ~]$

4. Take Base Backup and WAL Archive

4.1. Take Base Backup

[postgres@lxicbpgdsgv01 ~]$ nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/base_bkp12OCT2025 -Ft -Xs -P -v > /pgBackup/pgsql17/backup/base_bkp12OCT2025.log 2>&1 &
[1] 3347
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ cat /pgBackup/pgsql17/backup/base_bkp12OCT2025.log
nohup: ignoring input
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/91000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_3350"
  7754/535860 kB (1%), 0/3 tablespaces (...ckup/base_bkp12OCT2025/16542.tar)
  7754/535860 kB (1%), 1/3 tablespaces (...ckup/base_bkp12OCT2025/16542.tar)
 15474/535860 kB (2%), 1/3 tablespaces (...ckup/base_bkp12OCT2025/16545.tar)
 15474/535860 kB (2%), 2/3 tablespaces (...ckup/base_bkp12OCT2025/16545.tar)
191400/535860 kB (35%), 2/3 tablespaces (...ackup/base_bkp12OCT2025/base.tar)
372072/535860 kB (69%), 2/3 tablespaces (...ackup/base_bkp12OCT2025/base.tar)
525644/535860 kB (98%), 2/3 tablespaces (...ackup/base_bkp12OCT2025/base.tar)
535873/535873 kB (100%), 2/3 tablespaces (...ackup/base_bkp12OCT2025/base.tar)
535873/535873 kB (100%), 3/3 tablespaces
pg_basebackup: write-ahead log end point: 0/91000120
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed <----
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ du -sh /pgBackup/pgsql17/backup/base_bkp12OCT2025
540M    /pgBackup/pgsql17/backup/base_bkp12OCT2025
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ ls -ltr /pgBackup/pgsql17/backup/base_bkp12OCT2025
total 552508
-rw-------. 1 postgres postgres   7940096 Oct 12 21:57 16542.tar
-rw-------. 1 postgres postgres   7905792 Oct 12 21:57 16545.tar
-rw-------. 1 postgres postgres 532888576 Oct 12 21:57 base.tar
-rw-------. 1 postgres postgres    243763 Oct 12 21:57 backup_manifest
-rw-------. 1 postgres postgres  16778752 Oct 12 21:57 pg_wal.tar
[postgres@lxicbpgdsgv01 ~]$

4.2. Insert new row on table test.emp

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=# INSERT INTO test.emp VALUES ('DEV', 'DBA MANAGER', 'RCM', 'iGATE');
INSERT 0 1
dell=# CHECKPOINT;
CHECKPOINT
dell=# SELECT * FROM TEST.EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE
 DEV  | DBA MANAGER | RCM     | iGATE <-- New row 
(5 rows)

dell=# SELECT NOW();
              now
-------------------------------
 2025-10-12 22:04:29.793434+08
(1 row)

dell=#

dell=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/92000298
(1 row)

dell=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/93000000
(1 row)

dell=#

4.3. Dropped table test.emp accidentally


dell=# SELECT NOW();
              now
-------------------------------
 2025-10-12 22:05:29.954216+08 <----
(1 row)

dell=# DROP TABLE TEST.EMP; <-----
DROP TABLE
dell=# SELECT NOW();
              now
-------------------------------
 2025-10-12 22:05:42.890468+08
(1 row)

dell=#
dell=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/93007FF0
(1 row)

dell=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/94000000
(1 row)

dell=#

5. Transfer Base Backup and WAL Archives to Target


# Copy WAL Archive Fils 

[postgres@lxicbpgdsgv01 ~]$ cp /pgArch/pgsql17/arch/* /pgBackup/pgsql17/backup/archive_bkp12OCT2025
[postgres@lxicbpgdsgv01 ~]$ 

[postgres@lxicbpgdsgv01 backup]$ tar -cvf base_bkp12OCT2025.tar base_bkp12OCT2025
base_bkp12OCT2025/
base_bkp12OCT2025/16542.tar
base_bkp12OCT2025/pg_wal.tar
base_bkp12OCT2025/16545.tar
base_bkp12OCT2025/base.tar
base_bkp12OCT2025/backup_manifest
[postgres@lxicbpgdsgv01 backup]$
[postgres@lxicbpgdsgv01 backup]$ tar -cvf archive_bkp12OCT2025.tar archive_bkp12OCT2025
archive_bkp12OCT2025/
archive_bkp12OCT2025/00000001000000000000008E
archive_bkp12OCT2025/00000001000000000000008F
archive_bkp12OCT2025/000000010000000000000090
archive_bkp12OCT2025/000000010000000000000091
archive_bkp12OCT2025/000000010000000000000091.00000028.backup
archive_bkp12OCT2025/000000010000000000000092
archive_bkp12OCT2025/000000010000000000000093
[postgres@lxicbpgdsgv01 backup]$ pwd
/pgBackup/pgsql17/backup
[postgres@lxicbpgdsgv01 backup]$
[postgres@lxicbpgdsgv01 backup]$ ls -ltr
total 650832
drwxr-xr-x. 2 postgres postgres        97 Oct 12 21:57 base_bkp12OCT2025
-rw-r--r--. 1 postgres postgres      1286 Oct 12 21:57 base_bkp12OCT2025.log
drwxr-xr-x. 2 postgres postgres      4096 Oct 12 22:13 archive_bkp12OCT2025
-rw-r--r--. 1 postgres postgres 565770240 Oct 12 22:36 base_bkp12OCT2025.tar  <--- 
-rw-r--r--. 1 postgres postgres 100669440 Oct 12 22:36 archive_bkp12OCT2025.tar <--- 
[postgres@lxicbpgdsgv01 backup]$

[postgres@lxicbpgdsgv01 backup]$ scp *.tar 192.168.2.52:/pgbackup/pgsql17/backup
postgres@192.168.2.52's password:
archive_bkp12OCT2025.tar                   100%   96MB  61.0MB/s   00:01
base_bkp12OCT2025.tar                      100%  540MB  67.0MB/s   00:08
[postgres@lxicbpgdsgv01 backup]$

6. Check and Prepare Target Environment

6.1. Check Existing symbolic link and Mounts

[postgres@lxicbpgdsgv02 ~]$ find /pgdata/pgsql17/data -type l -ls
134356985      0 lrwxrwxrwx   1 postgres postgres       18 Oct 12 01:50 /pgdata/pgsql17/data/pg_wal -> /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$

6.2. Create Tablespace Directories

[postgres@lxicbpgdsgv02 ~]$ mkdir -p /pgtsdata01/pgsql17/tbs/delltbs01
[postgres@lxicbpgdsgv02 ~]$ mkdir -p /pgtsdata01/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgtsdata01/pgsql17/tbs/delltbs01
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgtsdata01/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgtsdata01/pgsql17/tbs/delltbs01
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgtsdata01/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$

6.3. Stop PostgreSQL

[root@lxicbpgdsgv02 ~]# systemctl stop postgresql-17.service
[root@lxicbpgdsgv02 ~]# ps -ef | grep pmon
root        3529    3228  0 23:50 pts/0    00:00:00 grep --color=auto pmon
[root@lxicbpgdsgv02 ~]#

6.4. Clean Data, WAL, and Archive Directories

# Please ensure a backup is taken, if needed, before deleting the contents.
# Remove $PGDATA contents
[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgdata/pgsql17/data/*
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data
total 0
[postgres@lxicbpgdsgv02 ~]$

# Remove WAL log files (Redo log files)
[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgwal/pgsql17/wal/*
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgwal/pgsql17/wal
total 0
[postgres@lxicbpgdsgv02 ~]$

# Remove WAL Archive log files 
[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgarchive/pgsql17/archive/*
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgarchive/pgsql17/archive
total 0
[postgres@lxicbpgdsgv02 ~]$

7. Restore Backup on Target

7.1. Extract Backup Files

[postgres@lxicbpgdsgv02 ~]$ cd /pgbackup/pgsql17/backup
[postgres@lxicbpgdsgv02 backup]$ ls -ltr
total 650824
-rw-r--r--. 1 postgres postgres 100669440 Oct 12 22:38 archive_bkp12OCT2025.tar
-rw-r--r--. 1 postgres postgres 565770240 Oct 12 22:38 base_bkp12OCT2025.tar
[postgres@lxicbpgdsgv02 backup]$
[postgres@lxicbpgdsgv02 backup]$ tar -xvf base_bkp12OCT2025.tar
base_bkp12OCT2025/
base_bkp12OCT2025/16542.tar
base_bkp12OCT2025/pg_wal.tar
base_bkp12OCT2025/16545.tar
base_bkp12OCT2025/base.tar
base_bkp12OCT2025/backup_manifest
[postgres@lxicbpgdsgv02 backup]$
[postgres@lxicbpgdsgv02 backup]$ ls -ltr
total 650824
drwxr-xr-x. 2 postgres postgres        97 Oct 12 21:57 base_bkp12OCT2025
-rw-r--r--. 1 postgres postgres 100669440 Oct 12 22:38 archive_bkp12OCT2025.tar
-rw-r--r--. 1 postgres postgres 565770240 Oct 12 22:38 base_bkp12OCT2025.tar
[postgres@lxicbpgdsgv02 backup]$ cd base_bkp12OCT2025/
[postgres@lxicbpgdsgv02 base_bkp12OCT2025]$ ls -ltr
total 552508
-rw-------. 1 postgres postgres   7905792 Oct 12 21:57 16545.tar
-rw-------. 1 postgres postgres   7940096 Oct 12 21:57 16542.tar
-rw-------. 1 postgres postgres  16778752 Oct 12 21:57 pg_wal.tar
-rw-------. 1 postgres postgres 532888576 Oct 12 21:57 base.tar
-rw-------. 1 postgres postgres    243763 Oct 12 21:57 backup_manifest
[postgres@lxicbpgdsgv02 base_bkp12OCT2025]$

7.2. Restore Base Data Directory

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/
total 0
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base_bkp12OCT2025/base.tar -C /pgdata/pgsql17/data > /pgbackup/pgsql17/backup/base_restore.log 2>&1 &
[1] 3607
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/
total 80
-rw-------. 1 postgres postgres   227 Oct 10 18:41 backup_label.old
-rw-------. 1 postgres postgres  1169 Oct 10 18:41 postgresql.conf.bkp_10sep2025
-rw-------. 1 postgres postgres 30702 Oct 10 18:41 postgresql.conf.bkp
-rw-------. 1 postgres postgres    88 Oct 10 18:41 postgresql.auto.conf
drwx------. 2 postgres postgres    18 Oct 10 18:41 pg_xact
-rw-------. 1 postgres postgres     3 Oct 10 18:41 PG_VERSION
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_twophase
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_stat_tmp
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_snapshots
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_serial
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_notify
drwx------. 4 postgres postgres    36 Oct 10 18:41 pg_multixact
-rw-------. 1 postgres postgres  2640 Oct 10 18:41 pg_ident.conf
-rw-------. 1 postgres postgres  5600 Oct 10 18:41 pg_hba.conf
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_dynshmem
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_commit_ts
drwx------. 2 postgres postgres     6 Oct 10 19:45 pg_subtrans
-rw-------. 1 postgres postgres  1169 Oct 11 02:42 postgresql.conf
drwx------. 2 postgres postgres     6 Oct 11 02:57 pg_tblspc
drwx------. 5 postgres postgres    33 Oct 11 03:01 base
drwx------. 4 postgres postgres    68 Oct 12 21:57 pg_logical
-rw-------. 1 postgres postgres    68 Oct 12 21:57 tablespace_map
drwx------. 2 postgres postgres     6 Oct 12 21:57 pg_replslot
-rw-------. 1 postgres postgres   227 Oct 12 21:57 backup_label
drwx------. 2 postgres postgres     6 Oct 12 23:17 pg_stat
drwx------. 4 postgres postgres    45 Oct 12 23:53 pg_wal
drwx------. 2 postgres postgres  4096 Oct 12 23:53 global
drwx------. 2 postgres postgres   188 Oct 13  2025 log
-rw-------. 1 postgres postgres    30 Oct 13  2025 current_logfiles
[postgres@lxicbpgdsgv02 ~]$

7.3. Restore WAL Directory

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgwal/pgsql17/wal/
total 0
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base_bkp12OCT2025/pg_wal.tar -C /pgwal/pgsql17/wal > /pgbackup/pgsql17/backup/wal_restore.log 2>&1 &
[1] 3610
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgwal/pgsql17/wal/
total 16384
-rw-------. 1 postgres postgres 16777216 Oct 12 21:57 000000010000000000000091
[postgres@lxicbpgdsgv02 ~]$

7.4. Remove and Symlink pg_wal

[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgdata/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ln -s /pgwal/pgsql17/wal /pgdata/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ld /pgdata/pgsql17/data/pg_wal
lrwxrwxrwx. 1 postgres postgres 18 Oct 12 23:57 /pgdata/pgsql17/data/pg_wal -> /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$

7.5. Update $PGDATA/tablespace_map

[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/tablespace_map
16542 /pgTb/pgsql17/tbs/delltbs01
16545 /pgTb/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$

# Update to new location
[postgres@lxicbpgdsgv02 ~]$ sed -i 's|/pgTb/|/pgtsdata01/|g' /pgdata/pgsql17/data/tablespace_map
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/tablespace_map
16542 /pgtsdata01/pgsql17/tbs/delltbs01
16545 /pgtsdata01/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgtsdata01/pgsql17/tbs/delltbs01
total 0
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgtsdata01/pgsql17/tbs/orcltbs01
total 0
[postgres@lxicbpgdsgv02 ~]$

7.6. Restore Tablespace Data

# Restore Tablespace DELL_TB_DATA
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base_bkp12OCT2025/16542.tar -C /pgtsdata01/pgsql17/tbs/delltbs01 > /pgbackup/pgsql17/backup/16542_restore.log 2>&1 &
[1] 3652
[postgres@lxicbpgdsgv02 ~]$

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgtsdata01/pgsql17/tbs/delltbs01
total 0
drwx------. 3 postgres postgres 19 Oct 11 02:55 PG_17_202406281
[postgres@lxicbpgdsgv02 ~]$

# Restore Tablespace ORCL_TB_DATA
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base_bkp12OCT2025/16545.tar -C /pgtsdata01/pgsql17/tbs/orcltbs01 > /pgbackup/pgsql17/backup/16545_restore.log 2>&1 &
[1] 3655
[postgres@lxicbpgdsgv02 ~]$

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgtsdata01/pgsql17/tbs/orcltbs01
total 0
drwx------. 3 postgres postgres 19 Oct 11 02:58 PG_17_202406281
[postgres@lxicbpgdsgv02 ~]$

7.7. Restore WAL Archive files to backup location

# Please use this location for restore_command in postgresql.conf file

[postgres@lxicbpgdsgv02 ~]$ cd /pgbackup/pgsql17/backup/
[postgres@lxicbpgdsgv02 backup]$ tar -xvf archive_bkp12OCT2025.tar
archive_bkp12OCT2025/
archive_bkp12OCT2025/00000001000000000000008E
archive_bkp12OCT2025/00000001000000000000008F
archive_bkp12OCT2025/000000010000000000000090
archive_bkp12OCT2025/000000010000000000000091
archive_bkp12OCT2025/000000010000000000000091.00000028.backup
archive_bkp12OCT2025/000000010000000000000092
archive_bkp12OCT2025/000000010000000000000093
[postgres@lxicbpgdsgv02 backup]$

[postgres@lxicbpgdsgv02 backup]$ cd archive_bkp12OCT2025/
[postgres@lxicbpgdsgv02 archive_bkp12OCT2025]$ pwd
/pgbackup/pgsql17/backup/archive_bkp12OCT2025
[postgres@lxicbpgdsgv02 archive_bkp12OCT2025]$ ls -ltr
total 98308
-rw-------. 1 postgres postgres 16777216 Oct 12 22:13 000000010000000000000093
-rw-------. 1 postgres postgres 16777216 Oct 12 22:13 000000010000000000000092
-rw-------. 1 postgres postgres      341 Oct 12 22:13 000000010000000000000091.00000028.backup
-rw-------. 1 postgres postgres 16777216 Oct 12 22:13 000000010000000000000091
-rw-------. 1 postgres postgres 16777216 Oct 12 22:13 000000010000000000000090
-rw-------. 1 postgres postgres 16777216 Oct 12 22:13 00000001000000000000008F
-rw-------. 1 postgres postgres 16777216 Oct 12 22:13 00000001000000000000008E
[postgres@lxicbpgdsgv02 archive_bkp12OCT2025]$

7.8. Create $PGDATA/recovery.signal file


[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/recovery.signal
ls: cannot access '/pgdata/pgsql17/data/recovery.signal': No such file or directory
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ touch /pgdata/pgsql17/data/recovery.signal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/recovery.signal
-rw-r--r--. 1 postgres postgres 0 Oct 13 00:09 /pgdata/pgsql17/data/recovery.signal  <--------------
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgdata/pgsql17/data/recovery.signal
[postgres@lxicbpgdsgv02 ~]$

7.9. Set Permissions

[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgarchive/pgsql17/archive
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgarchive/pgsql17/archive
[postgres@lxicbpgdsgv02 ~]$

8. PostgreSQL Configuration on Target

8.1. Update postgresql.conf

# β€’ restore_command (Mandatory)
# β€’ recovery_target_time (Mandatory)
# β€’ archive_mode (Optional)
# β€’ archive_command (Optional)
# eg: echo "recovery_target_time = '2025-10-12 22:05:00'" >> /pgdata/pgsql17/data/postgresql.conf

[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/postgresql.conf | egrep -i 'archive_|command'
archive_mode = on
archive_command = 'cp %p /pgArch/pgsql17/arch/%f'
[postgres@lxicbpgdsgv02 ~]$

# Update archive_mode=on (Optional)
# Update archive_command='cp %p /pgarchive/pgsql17/archive/%f' (Optional)
# Update restore_command = 'cp /pgbackup/pgsql17/backup/archive_bkp12OCT2025/%f %p' 
# Update recovery_target_time = '2025-10-12 22:05:00'

[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/postgresql.conf | egrep -i 'archive_|command|recover'
archive_mode = on
archive_command='cp %p /pgarchive/pgsql17/archive/%f'
restore_command = 'cp /pgbackup/pgsql17/backup/archive_bkp12OCT2025/%f %p'
recovery_target_time = '2025-10-12 22:05:00'
[postgres@lxicbpgdsgv02 ~]$

8.2. Validate PGDATA in systemd and bash shell profile

[postgres@lxicbpgdsgv02 ~]$ cat /usr/lib/systemd/system/postgresql-17.service | grep -i "Environment=PGDATA"
Environment=PGDATA=/pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ cat .bash_profile | grep -i PGDATA=
PGDATA=/pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$

9. Start PostgreSQL Service

[root@lxicbpgdsgv02 ~]# systemctl start postgresql-17.service
[root@lxicbpgdsgv02 ~]#
[root@lxicbpgdsgv02 ~]# systemctl status postgresql-17.service
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Mon 2025-10-13 00:28:04 +08; 10min ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 3859 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 3878 (postgres)
      Tasks: 6 (limit: 20496)
     Memory: 52.4M
        CPU: 221ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€3878 /usr/pgsql-17/bin/postgres -D /pgdata/pgsql17/data
             β”œβ”€3885 "postgres: logger "
             β”œβ”€3886 "postgres: checkpointer "
             β”œβ”€3887 "postgres: background writer "
             β”œβ”€3888 "postgres: startup waiting for 000000010000000000000094"   <---- NO Need to copy this archive log file.
             └─3901 "postgres: postgres dell [local] idle"

Oct 13 00:28:03 lxicbpgdsgv02.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 13 00:28:03 lxicbpgdsgv02.rajasekhar.com postgres[3878]: 2025-10-13 00:28:03.490 +08 [3878] LOG:  redirecting log output to logging collector process
Oct 13 00:28:03 lxicbpgdsgv02.rajasekhar.com postgres[3878]: 2025-10-13 00:28:03.490 +08 [3878] HINT:  Future log output will appear in directory "log".
Oct 13 00:28:04 lxicbpgdsgv02.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.
[root@lxicbpgdsgv02 ~]#

10. Final Validation

10.1. Review PostgreSQL Logs

2025-10-13 00:28:03.490 +08 [3878] LOG:  starting PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-5), 64-bit
2025-10-13 00:28:03.494 +08 [3878] LOG:  listening on IPv6 address "::1", port 5432
2025-10-13 00:28:03.494 +08 [3878] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2025-10-13 00:28:03.498 +08 [3878] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2025-10-13 00:28:03.504 +08 [3878] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2025-10-13 00:28:03.510 +08 [3888] LOG:  database system was interrupted; last known up at 2025-10-12 21:57:50 +08
2025-10-13 00:28:03.512 +08 [3888] LOG:  creating missing WAL directory "pg_wal/archive_status"
2025-10-13 00:28:03.512 +08 [3888] LOG:  creating missing WAL directory "pg_wal/summaries"
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp12OCT2025/00000002.history': No such file or directory
2025-10-13 00:28:04.414 +08 [3888] LOG:  starting backup recovery with redo LSN 0/91000028, checkpoint LSN 0/91000080, on timeline ID 1
2025-10-13 00:28:04.434 +08 [3888] LOG:  restored log file "000000010000000000000091" from archive
2025-10-13 00:28:04.486 +08 [3888] LOG:  starting point-in-time recovery to 2025-10-12 22:05:00+08
2025-10-13 00:28:04.497 +08 [3888] LOG:  redo starts at 0/91000028
2025-10-13 00:28:04.518 +08 [3888] LOG:  restored log file "000000010000000000000092" from archive
2025-10-13 00:28:04.591 +08 [3888] LOG:  restored log file "000000010000000000000093" from archive
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp12OCT2025/000000010000000000000094': No such file or directory
2025-10-13 00:28:04.651 +08 [3888] LOG:  completed backup recovery with redo LSN 0/91000028 and end LSN 0/91000120
2025-10-13 00:28:04.651 +08 [3888] LOG:  consistent recovery state reached at 0/91000120
2025-10-13 00:28:04.652 +08 [3888] LOG:  recovery stopping before commit of transaction 897, time 2025-10-12 22:05:35.873371+08
2025-10-13 00:28:04.652 +08 [3888] LOG:  pausing at the end of recovery
2025-10-13 00:28:04.652 +08 [3888] HINT:  Execute pg_wal_replay_resume() to promote.
2025-10-13 00:28:04.652 +08 [3878] LOG:  database system is ready to accept read-only connections

10.2. Execute pg_wal_replay_resume()

[postgres@lxicbpgdsgv02 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# select pg_wal_replay_resume();
 pg_wal_replay_resume
----------------------

(1 row)

postgres=#

10.3. Review PostgreSQL Logs again

...
2025-10-13 00:30:22.955 +08 [3982] STATEMENT:  pg_wal_replay_resume()
        pg_wal_replay_resume();
2025-10-13 00:32:11.748 +08 [3973] LOG:  redo done at 0/93007B70 system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 174.26 s
2025-10-13 00:32:11.768 +08 [3973] LOG:  restored log file "000000010000000000000093" from archive
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp12OCT2025/00000002.history': No such file or directory
2025-10-13 00:32:11.827 +08 [3973] LOG:  selected new timeline ID: 2
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp12OCT2025/00000001.history': No such file or directory
2025-10-13 00:32:11.957 +08 [3973] LOG:  archive recovery complete
2025-10-13 00:32:11.960 +08 [3971] LOG:  checkpoint starting: end-of-recovery immediate wait
2025-10-13 00:32:11.987 +08 [3971] LOG:  checkpoint complete: wrote 8 buffers (0.0%); 0 WAL file(s) added, 0 removed, 1 recycled; write=0.002 s, sync=0.012 s, total=0.029 s; sync files=7, longest=0.004 s, average=0.002 s; distance=16414 kB, estimate=16414 kB; lsn=0/93007B70, redo lsn=0/93007B70
2025-10-13 00:32:12.006 +08 [3969] LOG:  database system is ready to accept connections
[postgres@lxicbpgdsgv02 ~]$

10.4. Confirm recovery.signal Auto-deletion

# File should be gone after successful recovery.

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/recovery.signal
ls: cannot access '/pgdata/pgsql17/data/recovery.signal': No such file or directory
[postgres@lxicbpgdsgv02 ~]$

10.5. Check DB recovery status

[postgres@lxicbpgdsgv02 ~]$ psql -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
-------------------
 f  <--- means recovery is completed.
(1 row)

[postgres@lxicbpgdsgv02 ~]$

10.6. Check Database and Tablespace Listing

[postgres@lxicbpgdsgv02 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \l+
                                                                                        List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   |  Tablespace  |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+--------------+--------------------------------------------
 dell      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7755 kB | dell_tb_data |
 orcl      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7569 kB | orcl_tb_data |
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 492 MB  | pg_default   | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default   | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |              |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7569 kB | pg_default   | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |              |
(5 rows)

postgres=# \db
                     List of tablespaces
     Name     |  Owner   |             Location
--------------+----------+-----------------------------------
 dell_tb_data | postgres | /pgtsdata01/pgsql17/tbs/delltbs01
 orcl_tb_data | postgres | /pgtsdata01/pgsql17/tbs/orcltbs01
 pg_default   | postgres |
 pg_global    | postgres |
(4 rows)

postgres=#

10.7. Verify Application Data

[postgres@lxicbpgdsgv02 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=#
dell=# SELECT * FROM TEST.EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE
 DEV  | DBA MANAGER | RCM     | iGATE
(5 rows)

dell=#

10.8. Validate Symbolic Links for Tablespaces

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/pg_tblspc/
total 0
lrwxrwxrwx. 1 postgres postgres 33 Oct 13 00:28 16545 -> /pgtsdata01/pgsql17/tbs/orcltbs01
lrwxrwxrwx. 1 postgres postgres 33 Oct 13 00:28 16542 -> /pgtsdata01/pgsql17/tbs/delltbs01
[postgres@lxicbpgdsgv02 ~]$

11. Take Backup of dropped table test.emp

[postgres@lxicbpgdsgv02 ~]$ pg_dump -U postgres -d dell -t test.emp -Fc -v -f /pgbackup/pgsql17/backup/table_dell_test-emp.dmp
pg_dump: last built-in OID is 16383
pg_dump: reading extensions
pg_dump: identifying extension members
pg_dump: reading schemas
pg_dump: reading user-defined tables
pg_dump: reading user-defined functions
pg_dump: reading user-defined types
pg_dump: reading procedural languages
pg_dump: reading user-defined aggregate functions
pg_dump: reading user-defined operators
pg_dump: reading user-defined access methods
pg_dump: reading user-defined operator classes
pg_dump: reading user-defined operator families
pg_dump: reading user-defined text search parsers
pg_dump: reading user-defined text search templates
pg_dump: reading user-defined text search dictionaries
pg_dump: reading user-defined text search configurations
pg_dump: reading user-defined foreign-data wrappers
pg_dump: reading user-defined foreign servers
pg_dump: reading default privileges
pg_dump: reading user-defined collations
pg_dump: reading user-defined conversions
pg_dump: reading type casts
pg_dump: reading transforms
pg_dump: reading table inheritance information
pg_dump: reading event triggers
pg_dump: finding extension tables
pg_dump: finding inheritance relationships
pg_dump: reading column info for interesting tables
pg_dump: flagging inherited columns in subtables
pg_dump: reading partitioning data
pg_dump: reading indexes
pg_dump: flagging indexes in partitioned tables
pg_dump: reading extended statistics
pg_dump: reading constraints
pg_dump: reading triggers
pg_dump: reading rewrite rules
pg_dump: reading policies
pg_dump: reading row-level security policies
pg_dump: reading publications
pg_dump: reading publication membership of tables
pg_dump: reading publication membership of schemas
pg_dump: reading subscriptions
pg_dump: reading subscription membership of tables
pg_dump: reading dependency data
pg_dump: saving encoding = UTF8
pg_dump: saving "standard_conforming_strings = on"
pg_dump: saving "search_path = "
pg_dump: saving database definition
pg_dump: dumping contents of table "test.emp"
[postgres@lxicbpgdsgv02 ~]$

12. Transfer backup to source server

[postgres@lxicbpgdsgv02 ~]$ scp /pgbackup/pgsql17/backup/table_dell_test-emp.dmp 192.168.2.51:/pgBackup/pgsql17/backup
postgres@192.168.2.51's password:
table_dell_test-emp.dmp                    100% 1396   836.2KB/s   00:00
[postgres@lxicbpgdsgv02 ~]$

13. Restore dropped table and Validation

[postgres@lxicbpgdsgv01 ~]$ ls -ltr /pgBackup/pgsql17/backup/table_dell_test-emp.dmp
-rw-r--r--. 1 postgres postgres 1396 Oct 13 01:07 /pgBackup/pgsql17/backup/table_dell_test-emp.dmp
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=#
dell=# SELECT * FROM TEST.EMP;
ERROR:  relation "test.emp" does not exist
LINE 1: SELECT * FROM TEST.EMP;
                      ^
dell=#


[postgres@lxicbpgdsgv01 ~]$ pg_restore -l /pgBackup/pgsql17/backup/table_dell_test-emp.dmp
;
; Archive created at 2025-10-13 01:05:27 +08
;     dbname: dell
;     TOC Entries: 6
;     Compression: gzip
;     Dump Version: 1.16-0
;     Format: CUSTOM
;     Integer: 4 bytes
;     Offset: 8 bytes
;     Dumped from database version: 17.6
;     Dumped by pg_dump version: 17.6
;
;
; Selected TOC Entries:
;
218; 1259 16553 TABLE test emp postgres
4334; 0 16553 TABLE DATA test emp postgres
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ pg_restore -U postgres -d dell -v /pgBackup/pgsql17/backup/table_dell_test-emp.dmp
pg_restore: connecting to database for restore
pg_restore: creating TABLE "test.emp"
pg_restore: processing data for table "test.emp"
[postgres@lxicbpgdsgv01 ~]$

dell=# SELECT * FROM TEST.EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE
 DEV  | DBA MANAGER | RCM     | iGATE
(5 rows)

dell=#

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/

PostgreSQL Backup & Restore to New Host with WAL Archive files

How to Backup & Restore + Recover a PostgreSQL to New Host using pg_basebackup+WAL Archives

Table of Contents



0. Goal

Perform a full recovery to the latest consistent state by restoring a complete backup taken with pg_basebackup and applying the WAL archive files.

Note: pg_basebackup does not include WAL archive files (archive log files) in its backup; these must be backed up separately.

We have a base backup taken without using –tablespace-mapping, and the restore needs to be performed on a different host with the following differences:

  • Tablespace mount point paths are different from the source server.
  • Archive WAL directory is located in a different path.
  • WAL file (pg_wal) location differs.
  • PGDATA directory path is also different.

1. Environment (Source / Target)

AspectSourceTargetDifference
Hostnamelxicbpgdsgv01lxicbpgdsgv02Different hostnames
IP Address192.168.2.51192.168.2.52Different IPs
OSRHEL 9RHEL 9Same
DB VersionPostgreSQL v17.6PostgreSQL v17.6Same
Archive modearchive_mode=onarchive_mode=onSame
PGDATA/pgData/pgsql17/data/pgdata/pgsql17/dataDifferent path case (D vs d)
WAL Directory/pgWal/pgsql17/wal/pgwal/pgsql17/walDifferent path case (W vs w)
WAL Archive Directory/pgArch/pgsql17/arch/pgarchive/pgsql17/archiveDifferent path case (W vs w)
Backup Directory/pgBackup/pgsql17/backup/pgbackup/pgsql17/backupDifferent path case (B vs b)
restore_commandNot Applicable/pgbackup/pgsql17/backup/archive_bkp11OCT2025restore_command on target server for full recovery using WAL archive files.
Tablespace & PathDELL_TB_DATA:/pgTb/pgsql17/tbs/delltbs01 ORCL_TB_DATA:/pgTb/pgsql17/tbs/orcltbs01DELL_TB_DATA:/pgtsdata01/pgsql17/tbs/delltbs01 ORCL_TB_DATA:/pgtsdata01/pgsql17/tbs/orcltbs01It will restore using the same tablespace names, but at different locations.
DatabasesDELL, ORCLWe will restore both from backupWe will restore both

2. Verify Existing DB Setup

[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \l+
                                                                                        List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   |  Tablespace  |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+--------------+--------------------------------------------
 dell      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7755 kB | dell_tb_data |
 orcl      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7569 kB | orcl_tb_data |
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 492 MB  | pg_default   | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default   | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |              |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7569 kB | pg_default   | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |              |
(5 rows)

postgres=# \db
                  List of tablespaces
     Name     |  Owner   |          Location
--------------+----------+-----------------------------
 dell_tb_data | postgres | /pgTb/pgsql17/tbs/delltbs01
 orcl_tb_data | postgres | /pgTb/pgsql17/tbs/orcltbs01
 pg_default   | postgres |
 pg_global    | postgres |
(4 rows)

postgres=#

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=# CREATE TABLE test.emp (name TEXT, designation TEXT, project TEXT, company TEXT) TABLESPACE DELL_TB_DATA;
CREATE TABLE
dell=# INSERT INTO test.emp VALUES ('Sugi', 'DBA', 'Jetstar', 'iGATE');
INSERT 0 1
dell=# INSERT INTO test.emp VALUES ('Teja', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
dell=# INSERT INTO test.emp VALUES ('RAJ', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
dell=# CHECKPOINT;
CHECKPOINT
dell=# SELECT * FROM TEST.EMP;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

dell=#

3. Pre-requisites

3.1. Verify postgresql.conf

postgres=# SHOW wal_level;
 wal_level
-----------
 replica <----
(1 row)

postgres=# show archive_mode;
 archive_mode
--------------
 on <----
(1 row)

postgres=# show archive_command;
        archive_command
-------------------------------
 cp %p /pgArch/pgsql17/arch/%f
(1 row)

postgres=#

3.2. Verify pg_hba.conf

# TYPE  DATABASE        USER            ADDRESS             METHOD
# Local connections for replication (for pg_basebackup run locally)
local   replication     all                                 trust

# Remote connections for replication (for pg_basebackup run remotely)
#host    replication     repl_user       192.168.2.52/32     scram-sha-256

3.3. Verify User Permissions (REPLICATION or SUPERUSER)

postgres=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS

postgres=#

3.4. Verify Free Space for Backup

[postgres@lxicbpgdsgv01 ~]$ df -h /pgBackup
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdd1       100G  746M  100G   1% /pgBackup
[postgres@lxicbpgdsgv01 ~]$
# Create directories for base backup and WAL archive log files
[postgres@lxicbpgdsgv01 ~]$ mkdir -p /pgBackup/pgsql17/backup/base_bkp11OCT2025
[postgres@lxicbpgdsgv01 ~]$ mkdir -p /pgBackup/pgsql17/backup/archive_bkp11OCT2025
[postgres@lxicbpgdsgv01 ~]$

4. Take Base Backup and WAL Archive

4.1. Take Base Backup

# Take base backup

[postgres@lxicbpgdsgv01 ~]$ nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/base_bkp11OCT2025 -Ft -Xs -P -v > /pgBackup/pgsql17/backup/base_bkp11OCT2025.log 2>&1 &
[1] 3413
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ cat /pgBackup/pgsql17/backup/base_bkp11OCT2025.log
nohup: ignoring input
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/8C000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_3416"
  7754/535855 kB (1%), 0/3 tablespaces (...ckup/base_bkp11OCT2025/16542.tar)
  7754/535855 kB (1%), 1/3 tablespaces (...ckup/base_bkp11OCT2025/16542.tar)
 15474/535855 kB (2%), 1/3 tablespaces (...ckup/base_bkp11OCT2025/16545.tar)
 15474/535855 kB (2%), 2/3 tablespaces (...ckup/base_bkp11OCT2025/16545.tar)
157800/535855 kB (29%), 2/3 tablespaces (...ackup/base_bkp11OCT2025/base.tar)
342056/535855 kB (63%), 2/3 tablespaces (...ackup/base_bkp11OCT2025/base.tar)
496488/535855 kB (92%), 2/3 tablespaces (...ackup/base_bkp11OCT2025/base.tar)
535868/535868 kB (100%), 2/3 tablespaces (...ackup/base_bkp11OCT2025/base.tar)
535868/535868 kB (100%), 3/3 tablespaces
pg_basebackup: write-ahead log end point: 0/8C000120
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed <-----
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ du -sh /pgBackup/pgsql17/backup/base_bkp11OCT2025
540M    /pgBackup/pgsql17/backup/base_bkp11OCT2025
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ ls -ltr /pgBackup/pgsql17/backup/base_bkp11OCT2025
total 552504
-rw-------. 1 postgres postgres   7940096 Oct 12 00:42 16542.tar
-rw-------. 1 postgres postgres   7905792 Oct 12 00:42 16545.tar
-rw-------. 1 postgres postgres 532883456 Oct 12 00:42 base.tar
-rw-------. 1 postgres postgres    243611 Oct 12 00:42 backup_manifest
-rw-------. 1 postgres postgres  16778752 Oct 12 00:42 pg_wal.tar
[postgres@lxicbpgdsgv01 ~]$

backup_manifest is a JSON file included inside the tar backup.
It contains metadata about the backup, like:
--> List of all files included in the backup
--> Their sizes and checksums
--> Backup timestamps
--> Backup type (full, incremental, differential)
--> Other metadata needed to verify and restore the backup properly

4.2. Insert new row on table test.emp after backup

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=# INSERT INTO test.emp VALUES ('KK', 'DBA LEAD', 'RCM', 'iGATE');
INSERT 0 1
dell=# CHECKPOINT;
CHECKPOINT
dell=# select * from test.emp;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE <---- New row
(4 rows)

# Switch Archivelog (WAL Archive logs)
dell=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/8D000328
(1 row)

dell=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/8E000000
(1 row)

dell=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/8E000000
(1 row)

dell=#

4.3. Copy WAL Archive Files Separately

[postgres@lxicbpgdsgv01 ~]$ cp /pgArch/pgsql17/arch/* /pgBackup/pgsql17/backup/archive_bkp11OCT2025
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ ls -ltr /pgBackup/pgsql17/backup/archive_bkp11OCT2025
total 65540
-rw-------. 1 postgres postgres 16777216 Oct 12 00:53 00000001000000000000008A
-rw-------. 1 postgres postgres 16777216 Oct 12 00:53 00000001000000000000008B
-rw-------. 1 postgres postgres      341 Oct 12 00:53 00000001000000000000008C.00000028.backup
-rw-------. 1 postgres postgres 16777216 Oct 12 00:53 00000001000000000000008C
-rw-------. 1 postgres postgres 16777216 Oct 12 00:53 00000001000000000000008D
[postgres@lxicbpgdsgv01 ~]$

5. Transfer Base Backup and WAL Archives to Target

[postgres@lxicbpgdsgv01 ~]$ cd /pgBackup/pgsql17/backup/
[postgres@lxicbpgdsgv01 backup]$ ls -ltr
total 4
drwxr-xr-x. 2 postgres postgres   97 Oct 12 00:42 base_bkp11OCT2025
-rw-r--r--. 1 postgres postgres 1286 Oct 12 00:42 base_bkp11OCT2025.log
drwxr-xr-x. 2 postgres postgres  182 Oct 12 00:56 archive_bkp11OCT2025
[postgres@lxicbpgdsgv01 backup]$
[postgres@lxicbpgdsgv01 backup]$ tar -cvf base_bkp11OCT2025.tar base_bkp11OCT2025
base_bkp11OCT2025/
base_bkp11OCT2025/16542.tar
base_bkp11OCT2025/pg_wal.tar
base_bkp11OCT2025/16545.tar
base_bkp11OCT2025/base.tar
base_bkp11OCT2025/backup_manifest
[postgres@lxicbpgdsgv01 backup]$
[postgres@lxicbpgdsgv01 backup]$ tar -cvf archive_bkp11OCT2025.tar archive_bkp11OCT2025
archive_bkp11OCT2025/
archive_bkp11OCT2025/00000001000000000000008A
archive_bkp11OCT2025/00000001000000000000008B
archive_bkp11OCT2025/00000001000000000000008C
archive_bkp11OCT2025/00000001000000000000008C.00000028.backup
archive_bkp11OCT2025/00000001000000000000008D
[postgres@lxicbpgdsgv01 backup]$
[postgres@lxicbpgdsgv01 backup]$ ls -ltr
total 618056
drwxr-xr-x. 2 postgres postgres        97 Oct 12 00:42 base_bkp11OCT2025
-rw-r--r--. 1 postgres postgres      1286 Oct 12 00:42 base_bkp11OCT2025.log
drwxr-xr-x. 2 postgres postgres       182 Oct 12 00:56 archive_bkp11OCT2025
-rw-r--r--. 1 postgres postgres 565760000 Oct 12 01:00 base_bkp11OCT2025.tar
-rw-r--r--. 1 postgres postgres  67123200 Oct 12 01:01 archive_bkp11OCT2025.tar
[postgres@lxicbpgdsgv01 backup]$

[postgres@lxicbpgdsgv01 backup]$ scp *.tar 192.168.2.52:/pgbackup/pgsql17/backup
postgres@192.168.2.52's password:
archive_bkp11OCT2025.tar                      100%   64MB  54.6MB/s   00:01
base_bkp11OCT2025.tar                         100%  540MB  58.3MB/s   00:09
[postgres@lxicbpgdsgv01 backup]$

6. Check and Prepare Target Environment

6.1. Check Existing symbolic link and Mounts

[postgres@lxicbpgdsgv02 ~]$ find /pgdata/pgsql17/data -type l -ls
 67117239      0 lrwxrwxrwx   1 postgres postgres       18 Oct 10 19:43 /pgdata/pgsql17/data/pg_wal -> /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$

6.2. Create Tablespace Directories

[postgres@lxicbpgdsgv02 ~]$ mkdir -p /pgtsdata01/pgsql17/tbs/delltbs01
[postgres@lxicbpgdsgv02 ~]$ mkdir -p /pgtsdata01/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgtsdata01/pgsql17/tbs/delltbs01
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgtsdata01/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgtsdata01/pgsql17/tbs/delltbs01
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgtsdata01/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$

6.3. Stop PostgreSQL

[root@lxicbpgdsgv02 ~]# systemctl stop postgresql-17.service
[root@lxicbpgdsgv02 ~]# ps -ef | grep postgres
root        4269    3222  0 01:14 pts/0    00:00:00 grep --color=auto postgres
[root@lxicbpgdsgv02 ~]#

6.4. Clean Data, WAL, and Archive Directories

# Please ensure a backup is taken, if needed, before deleting the contents.
# Remove $PGDATA contents
[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgdata/pgsql17/data/*
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data
total 0
[postgres@lxicbpgdsgv02 ~]$

# Remove WAL log files (Redo log files)
[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgwal/pgsql17/wal/*
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgwal/pgsql17/wal
total 0
[postgres@lxicbpgdsgv02 ~]$

# Remove WAL Archive log files 
[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgarchive/pgsql17/archive/*
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgarchive/pgsql17/archive
total 0
[postgres@lxicbpgdsgv02 ~]$

7. Restore Backup on Target

7.1. Extract Backup Files

[postgres@lxicbpgdsgv02 ~]$ cd /pgbackup/pgsql17/backup
[postgres@lxicbpgdsgv02 backup]$ ls -ltr
total 618052
-rw-r--r--. 1 postgres postgres  67123200 Oct 12 01:04 archive_bkp11OCT2025.tar
-rw-r--r--. 1 postgres postgres 565760000 Oct 12 01:04 base_bkp11OCT2025.tar
[postgres@lxicbpgdsgv02 backup]$
[postgres@lxicbpgdsgv02 backup]$ tar -xvf base_bkp11OCT2025.tar
base_bkp11OCT2025/
base_bkp11OCT2025/16542.tar
base_bkp11OCT2025/pg_wal.tar
base_bkp11OCT2025/16545.tar
base_bkp11OCT2025/base.tar
base_bkp11OCT2025/backup_manifest
[postgres@lxicbpgdsgv02 backup]$
[postgres@lxicbpgdsgv02 backup]$ tar -xvf archive_bkp11OCT2025.tar
archive_bkp11OCT2025/
archive_bkp11OCT2025/00000001000000000000008A
archive_bkp11OCT2025/00000001000000000000008B
archive_bkp11OCT2025/00000001000000000000008C
archive_bkp11OCT2025/00000001000000000000008C.00000028.backup
archive_bkp11OCT2025/00000001000000000000008D
[postgres@lxicbpgdsgv02 backup]$
[postgres@lxicbpgdsgv02 backup]$ ls -ltr
total 618052
drwxr-xr-x. 2 postgres postgres        97 Oct 12 00:42 base_bkp11OCT2025
drwxr-xr-x. 2 postgres postgres       182 Oct 12 00:56 archive_bkp11OCT2025
-rw-r--r--. 1 postgres postgres  67123200 Oct 12 01:04 archive_bkp11OCT2025.tar
-rw-r--r--. 1 postgres postgres 565760000 Oct 12 01:04 base_bkp11OCT2025.tar
[postgres@lxicbpgdsgv02 backup]$
[postgres@lxicbpgdsgv02 backup]$ cd base_bkp11OCT2025
[postgres@lxicbpgdsgv02 base_bkp11OCT2025]$ ls -ltr
total 552504
-rw-------. 1 postgres postgres   7940096 Oct 12 00:42 16542.tar
-rw-------. 1 postgres postgres   7905792 Oct 12 00:42 16545.tar
-rw-------. 1 postgres postgres  16778752 Oct 12 00:42 pg_wal.tar
-rw-------. 1 postgres postgres 532883456 Oct 12 00:42 base.tar
-rw-------. 1 postgres postgres    243611 Oct 12 00:42 backup_manifest
[postgres@lxicbpgdsgv02 base_bkp11OCT2025]$

7.2. Restore Base Data Directory

# Restore base backup to $PGDATA

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/
total 0
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base_bkp11OCT2025/base.tar -C /pgdata/pgsql17/data > /pgbackup/pgsql17/backup/base_restore.log 2>&1 &
[1] 4482
[postgres@lxicbpgdsgv02 ~]$

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/
total 80
-rw-------. 1 postgres postgres   227 Oct 10 18:41 backup_label.old
-rw-------. 1 postgres postgres  1169 Oct 10 18:41 postgresql.conf.bkp_10sep2025
-rw-------. 1 postgres postgres 30702 Oct 10 18:41 postgresql.conf.bkp
-rw-------. 1 postgres postgres    88 Oct 10 18:41 postgresql.auto.conf
drwx------. 2 postgres postgres    18 Oct 10 18:41 pg_xact
-rw-------. 1 postgres postgres     3 Oct 10 18:41 PG_VERSION
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_twophase
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_stat_tmp
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_snapshots
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_serial
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_notify
drwx------. 4 postgres postgres    36 Oct 10 18:41 pg_multixact
-rw-------. 1 postgres postgres  2640 Oct 10 18:41 pg_ident.conf
-rw-------. 1 postgres postgres  5600 Oct 10 18:41 pg_hba.conf
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_dynshmem
drwx------. 2 postgres postgres     6 Oct 10 18:41 pg_commit_ts
drwx------. 2 postgres postgres     6 Oct 10 19:45 pg_subtrans
-rw-------. 1 postgres postgres  1169 Oct 11 02:42 postgresql.conf
drwx------. 2 postgres postgres     6 Oct 11 02:57 pg_tblspc
drwx------. 5 postgres postgres    33 Oct 11 03:01 base
drwx------. 2 postgres postgres     6 Oct 12 00:42 pg_replslot
drwx------. 4 postgres postgres    68 Oct 12 00:42 pg_logical
-rw-------. 1 postgres postgres    68 Oct 12 00:42 tablespace_map
-rw-------. 1 postgres postgres   227 Oct 12 00:42 backup_label
drwx------. 4 postgres postgres    45 Oct 12 01:29 pg_wal <-- it created as directory.
drwx------. 2 postgres postgres  4096 Oct 12 01:29 global
drwx------. 2 postgres postgres     6 Oct 12  2025 pg_stat
drwx------. 2 postgres postgres   162 Oct 12  2025 log
-rw-------. 1 postgres postgres    30 Oct 12  2025 current_logfiles
[postgres@lxicbpgdsgv02 ~]$

7.3. Restore WAL Directory

# Restore WAL Files to New WAL location 

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgwal/pgsql17/wal/
total 0
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base_bkp11OCT2025/pg_wal.tar -C /pgwal/pgsql17/wal > /pgbackup/pgsql17/backup/wal_restore.log 2>&1 &
[1] 4495
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgwal/pgsql17/wal/
total 16384
-rw-------. 1 postgres postgres 16777216 Oct 12 00:42 00000001000000000000008C
[postgres@lxicbpgdsgv02 ~]$

7.4. Remove and Symlink pg_wal

# Remove default pg_wal directory from $PGDATA
# Create symbolic link to new WAL file location 
[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgdata/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ln -s /pgwal/pgsql17/wal /pgdata/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ld /pgdata/pgsql17/data/pg_wal
lrwxrwxrwx. 1 postgres postgres 18 Oct 12 01:50 /pgdata/pgsql17/data/pg_wal -> /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$

7.5. Update $PGDATA/tablespace_map

[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/tablespace_map
16542 /pgTb/pgsql17/tbs/delltbs01
16545 /pgTb/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$

# Update to new location
[postgres@lxicbpgdsgv02 ~]$ sed -i 's|/pgTb/|/pgtsdata01/|g' /pgdata/pgsql17/data/tablespace_map
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/tablespace_map
16542 /pgtsdata01/pgsql17/tbs/delltbs01
16545 /pgtsdata01/pgsql17/tbs/orcltbs01
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgtsdata01/pgsql17/tbs/delltbs01
total 0
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgtsdata01/pgsql17/tbs/orcltbs01
total 0
[postgres@lxicbpgdsgv02 ~]$

7.6. Restore Tablespace Data

# Restore Tablespace DELL_TB_DATA
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base_bkp11OCT2025/16542.tar -C /pgtsdata01/pgsql17/tbs/delltbs01 > /pgbackup/pgsql17/backup/16542_restore.log 2>&1 &
[1] 4593
[postgres@lxicbpgdsgv02 ~]$

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgtsdata01/pgsql17/tbs/delltbs01
total 0
drwx------. 3 postgres postgres 19 Oct 11 02:55 PG_17_202406281 <---
[postgres@lxicbpgdsgv02 ~]$

# Restore Tablespace ORCL_TB_DATA
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base_bkp11OCT2025/16545.tar -C /pgtsdata01/pgsql17/tbs/orcltbs01 > /pgbackup/pgsql17/backup/16545_restore.log 2>&1 &
[1] 4594
[postgres@lxicbpgdsgv02 ~]$

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgtsdata01/pgsql17/tbs/orcltbs01
total 0
drwx------. 3 postgres postgres 19 Oct 11 02:58 PG_17_202406281 <---
[postgres@lxicbpgdsgv02 ~]$

7.7. Restore WAL Archive files to backup location

# I have already extracted Archivelog files in the step number 7.1
# Please use this location for restore_command in postgresql.conf file

[postgres@lxicbpgdsgv02 ~]$ cd /pgbackup/pgsql17/backup/archive_bkp11OCT2025/
[postgres@lxicbpgdsgv02 archive_bkp11OCT2025]$ ls -ltr
total 65540
-rw-------. 1 postgres postgres 16777216 Oct 12 00:53 00000001000000000000008D
-rw-------. 1 postgres postgres      341 Oct 12 00:53 00000001000000000000008C.00000028.backup
-rw-------. 1 postgres postgres 16777216 Oct 12 00:53 00000001000000000000008C
-rw-------. 1 postgres postgres 16777216 Oct 12 00:53 00000001000000000000008B
-rw-------. 1 postgres postgres 16777216 Oct 12 00:53 00000001000000000000008A
[postgres@lxicbpgdsgv02 archive_bkp11OCT2025]$

7.8. Create $PGDATA/recovery.signal file

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/recovery.signal
ls: cannot access '/pgdata/pgsql17/data/recovery.signal': No such file or directory
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ touch /pgdata/pgsql17/data/recovery.signal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/recovery.signal
-rw-r--r--. 1 postgres postgres 0 Oct 12 02:06 /pgdata/pgsql17/data/recovery.signal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgdata/pgsql17/data/recovery.signal
[postgres@lxicbpgdsgv02 ~]$

7.9. Set Permissions

[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgarchive/pgsql17/archive
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgarchive/pgsql17/archive
[postgres@lxicbpgdsgv02 ~]$

8. PostgreSQL Configuration on Target

8.1. Update postgresql.conf

# β€’ restore_command
# β€’ archive_mode (Optional)
# β€’ archive_command (Optional)

[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/postgresql.conf | egrep -i 'archive_|command'
archive_mode = on
archive_command = 'cp %p /pgArch/pgsql17/arch/%f'
[postgres@lxicbpgdsgv02 ~]$

# Update archive_mode=on (Optional)
# Update archive_command='cp %p /pgarchive/pgsql17/archive/%f' (Optional)
# Update restore_command = 'cp /pgbackup/pgsql17/backup/archive_bkp11OCT2025/%f %p'  <--- Must required for full recovery using WAL Archive log files.

[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/postgresql.conf | egrep -i 'archive_|command'
archive_mode = on
archive_command='cp %p /pgarchive/pgsql17/archive/%f'
restore_command = 'cp /pgbackup/pgsql17/backup/archive_bkp11OCT2025/%f %p' <---- must be set correctly
[postgres@lxicbpgdsgv02 ~]$

8.2. Validate PGDATA in systemd and bash shell profile

[postgres@lxicbpgdsgv02 ~]$ cat /usr/lib/systemd/system/postgresql-17.service | grep -i "Environment=PGDATA"
Environment=PGDATA=/pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ cat .bash_profile | grep -i PGDATA=
PGDATA=/pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$

9. Start PostgreSQL Service

[root@lxicbpgdsgv02 ~]# systemctl start postgresql-17.service
[root@lxicbpgdsgv02 ~]#
[root@lxicbpgdsgv02 ~]# systemctl status postgresql-17.service
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Sun 2025-10-12 02:23:36 +08; 1min 17s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 4887 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 4892 (postgres)
      Tasks: 8 (limit: 20496)
     Memory: 66.3M
        CPU: 200ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€4892 /usr/pgsql-17/bin/postgres -D /pgdata/pgsql17/data
             β”œβ”€4893 "postgres: logger "
             β”œβ”€4894 "postgres: checkpointer "
             β”œβ”€4895 "postgres: background writer "
             β”œβ”€4905 "postgres: walwriter "
             β”œβ”€4906 "postgres: autovacuum launcher "
             β”œβ”€4907 "postgres: archiver last was 00000002.history"
             └─4908 "postgres: logical replication launcher "

Oct 12 02:23:35 lxicbpgdsgv02.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 12 02:23:35 lxicbpgdsgv02.rajasekhar.com postgres[4892]: 2025-10-12 02:23:35.389 +08 [4892] LOG:  redirecting log output to logging collector process
Oct 12 02:23:35 lxicbpgdsgv02.rajasekhar.com postgres[4892]: 2025-10-12 02:23:35.389 +08 [4892] HINT:  Future log output will appear in directory "log".
Oct 12 02:23:36 lxicbpgdsgv02.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.
[root@lxicbpgdsgv02 ~]#

10. Final Validation

10.1. Check Database and Tablespace Listing

[postgres@lxicbpgdsgv02 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \l+
                                                                                        List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   |  Tablespace  |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+--------------+--------------------------------------------
 dell      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7755 kB | dell_tb_data |
 orcl      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7569 kB | orcl_tb_data |
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 492 MB  | pg_default   | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default   | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |              |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7569 kB | pg_default   | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |              |
(5 rows)

postgres=# \db
                     List of tablespaces
     Name     |  Owner   |             Location
--------------+----------+-----------------------------------
 dell_tb_data | postgres | /pgtsdata01/pgsql17/tbs/delltbs01
 orcl_tb_data | postgres | /pgtsdata01/pgsql17/tbs/orcltbs01
 pg_default   | postgres |
 pg_global    | postgres |
(4 rows)

postgres=#

10.2. Verify Application Data

[postgres@lxicbpgdsgv02 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=# select * from test.emp;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
 KK   | DBA LEAD    | RCM     | iGATE <----
(4 rows)

dell=# exit
[postgres@lxicbpgdsgv02 ~]$

10.3. Validate Symbolic Links for Tablespaces

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/pg_tblspc/
total 0
lrwxrwxrwx. 1 postgres postgres 33 Oct 12 02:23 16545 -> /pgtsdata01/pgsql17/tbs/orcltbs01
lrwxrwxrwx. 1 postgres postgres 33 Oct 12 02:23 16542 -> /pgtsdata01/pgsql17/tbs/delltbs01
[postgres@lxicbpgdsgv02 ~]$

10.4. Confirm recovery.signal Auto-deletion

# File should be gone after successful recovery.

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/recovery.signal
ls: cannot access '/pgdata/pgsql17/data/recovery.signal': No such file or directory
[postgres@lxicbpgdsgv02 ~]$

10.5. Review PostgreSQL Logs

[postgres@lxicbpgdsgv02 ~]$ cat /pgdata/pgsql17/data/log/postgresql-Sun.log
...
...
2025-10-12 02:23:35.389 +08 [4892] LOG:  starting PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 11.5.0 20240719 (Red Hat 11.5.0-5), 64-bit
2025-10-12 02:23:35.391 +08 [4892] LOG:  listening on IPv6 address "::1", port 5432
2025-10-12 02:23:35.392 +08 [4892] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2025-10-12 02:23:35.409 +08 [4892] LOG:  listening on Unix socket "/run/postgresql/.s.PGSQL.5432"
2025-10-12 02:23:35.418 +08 [4892] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2025-10-12 02:23:35.424 +08 [4896] LOG:  database system was interrupted; last known up at 2025-10-12 00:42:13 +08
2025-10-12 02:23:35.424 +08 [4896] LOG:  creating missing WAL directory "pg_wal/archive_status"
2025-10-12 02:23:35.424 +08 [4896] LOG:  creating missing WAL directory "pg_wal/summaries"
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp11OCT2025/00000002.history': No such file or directory
2025-10-12 02:23:36.418 +08 [4896] LOG:  starting backup recovery with redo LSN 0/8C000028, checkpoint LSN 0/8C000080, on timeline ID 1
2025-10-12 02:23:36.440 +08 [4896] LOG:  restored log file "00000001000000000000008C" from archive
2025-10-12 02:23:36.505 +08 [4896] LOG:  starting archive recovery
2025-10-12 02:23:36.516 +08 [4896] LOG:  redo starts at 0/8C000028
2025-10-12 02:23:36.539 +08 [4896] LOG:  restored log file "00000001000000000000008D" from archive
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp11OCT2025/00000001000000000000008E': No such file or directory
2025-10-12 02:23:36.597 +08 [4896] LOG:  completed backup recovery with redo LSN 0/8C000028 and end LSN 0/8C000120
2025-10-12 02:23:36.597 +08 [4896] LOG:  consistent recovery state reached at 0/8C000120
2025-10-12 02:23:36.599 +08 [4892] LOG:  database system is ready to accept read-only connections
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp11OCT2025/00000001000000000000008E': No such file or directory
2025-10-12 02:23:36.612 +08 [4896] LOG:  redo done at 0/8D000310 system usage: CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.09 s
2025-10-12 02:23:36.612 +08 [4896] LOG:  last completed transaction was at log time 2025-10-12 00:52:29.813112+08
2025-10-12 02:23:36.639 +08 [4896] LOG:  restored log file "00000001000000000000008D" from archive
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp11OCT2025/00000002.history': No such file or directory
2025-10-12 02:23:36.700 +08 [4896] LOG:  selected new timeline ID: 2
cp: cannot stat '/pgbackup/pgsql17/backup/archive_bkp11OCT2025/00000001.history': No such file or directory
2025-10-12 02:23:36.779 +08 [4896] LOG:  archive recovery complete
2025-10-12 02:23:36.782 +08 [4894] LOG:  checkpoint starting: end-of-recovery immediate wait
2025-10-12 02:23:36.810 +08 [4894] LOG:  checkpoint complete: wrote 4 buffers (0.0%); 0 WAL file(s) added, 0 removed, 2 recycled; write=0.002 s, sync=0.008 s, total=0.031 s; sync files=3, longest=0.003 s, average=0.003 s; distance=32768 kB, estimate=32768 kB; lsn=0/8E000028, redo lsn=0/8E000028
2025-10-12 02:23:36.823 +08 [4892] LOG:  database system is ready to accept connections
[postgres@lxicbpgdsgv02 ~]$

10.6. Check DB recovery status

[postgres@lxicbpgdsgv02 ~]$ psql -c "SELECT pg_is_in_recovery();"
 pg_is_in_recovery
-------------------
 f  <--- means recovery is completed.
(1 row)

[postgres@lxicbpgdsgv02 ~]$

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/

Backup and Restore on Same Host Using pg_basebackup

How to Backup and Restore PostgreSQL DB Cluster on the Same Host Using pg_basebackup

Table of Contents


1. Environment
2. Verify Existing DB Setup
3. Pre-requisites
4. Take Backup
5. Prepare & Restore
Β  Β  Β 5.1 Stop PostgreSQL and Clean Directories
Β  Β  Β 5.2 Remove all from Data & WAL directories
Β  Β  Β 5.3 Restore Data and WAL
Β  Β  Β  Β  Β A. Copy Backup files to $PGDATA
Β  Β  Β  Β  Β B. Copy WAL files from $PGDATA/pg_wal to /pgWal/pgsql17/wal/
Β  Β  Β  Β  Β C. Remove the existing $PGDATA/pg_wal directory
Β  Β  Β  Β  Β D. Create a symbolic link pointing $PGDATA/pg_wal to a separate WAL directory
Β  Β  Β  Β  Β E. Set Permissions
6. Start PostgreSQL
7. Final Verification


1. Environment

ASPECTEnv
Hostnamelxicbpgdsgv01
IP Address192.168.2.51
OSRHEL 9
DB VersionPostgreSQL v17.6
Archive modearchive_mode=off
pgData/pgData/pgsql17/data
WAL Directory/pgWal/pgsql17/wal
Tablespacepg_default
DatabasesDELL, ORCL

2. Verify Existing DB Setup

[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \l+
                                                                                       List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   | Tablespace |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+------------+--------------------------------------------
 dell      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7763 kB | pg_default |
 orcl      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7907 kB | pg_default |
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 492 MB  | pg_default | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7723 kB | pg_default | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
(5 rows)

postgres=# \db
       List of tablespaces
    Name    |  Owner   | Location
------------+----------+----------
 pg_default | postgres |
 pg_global  | postgres |
(2 rows)

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=# select * from test.emp;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

dell=#

3. Pre-requisites

  • Verify postgresql.conf
postgres=# SHOW wal_level;
 wal_level
-----------
 replica <----
(1 row)

postgres=#
postgres=# SHOW max_wal_senders;
 max_wal_senders
-----------------
 10
(1 row)

postgres=# SHOW archive_mode;
 archive_mode
--------------
 off
(1 row)

postgres=# 
  • Verify pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS             METHOD
# Local connections for replication (for pg_basebackup run locally)
local   replication     all                                 trust

# Remote connections for replication (for pg_basebackup run remotely)
#host    replication     repl_user       192.168.2.52/32     scram-sha-256

  • Verify user permissions:REPLICATION or SUPERUSER required
postgres=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS

postgres=#
  • Verify free space for backup
[postgres@lxicbpgdsgv01 ~]$ du -sh /pgData/pgsql17/data/
524M    /pgData/pgsql17/data/
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ du -sh /pgWal/pgsql17/wal/
801M    /pgWal/pgsql17/wal/
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ df -h /pgBackup/
Filesystem      Size  Used Avail Use% Mounted on
/dev/sdd1       100G  746M  100G   1% /pgBackup <----
[postgres@lxicbpgdsgv01 ~]$ mkdir -p /pgBackup/pgsql17/backup/basebackup_10OCT2025
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ mkdir -p /pgBackup/pgsql17/backup/log/
[postgres@lxicbpgdsgv01 ~]$

4. Take Backup

[postgres@lxicbpgdsgv01 ~]$ ls -ltrh /pgWal/pgsql17/wal | wc -l
53 <---- 
[postgres@lxicbpgdsgv01 ~]$

pg_basebackup does not include all files from the pg_wal directory in the backup. Instead, it selectively includes only the WAL files required to make the base backup consistent at the point in time the backup was taken.

-- If you want to store the base backup and WAL files in separate backup directories. 

nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/basebackup_10OCT2025 --waldir=/pgBackup/pgsql17/backup/wal_backup -Fp -Xs -P -v > /pgBackup/pgsql17/backup/log/basebackup_10OCT2025.log 2>&1 &

The --waldir option in pg_basebackup is supported only when using the plain format (-Fp), not with the tar format (-Ft).

If we want symlinks preserved β†’ use (both -Fp & --waldir use together) -Fp --waldir=/pgWal/pgsql17/wal

-- OR --

The directory mush be empty: /pgBackup/pgsql17/backup/basebackup_10OCT2025

[postgres@lxicbpgdsgv01 ~]$ nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/basebackup_10OCT2025 -Fp -Xs -P -v > /pgBackup/pgsql17/backup/log/basebackup_10OCT2025.log 2>&1 &
[1] 4973
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ cat /pgBackup/pgsql17/backup/log/basebackup_10OCT2025.log
nohup: ignoring input
pg_basebackup: initiating base backup, waiting for checkpoint to complete
pg_basebackup: checkpoint completed
pg_basebackup: write-ahead log start point: 0/85000028 on timeline 1
pg_basebackup: starting background WAL receiver
pg_basebackup: created temporary replication slot "pg_basebackup_4975"
279413/536037 kB (52%), 0/1 tablespace (...asebackup_10OCT2025/base/5/16533)
536047/536047 kB (100%), 0/1 tablespace (...ckup_10OCT2025/global/pg_control)
536047/536047 kB (100%), 1/1 tablespace
pg_basebackup: write-ahead log end point: 0/85000158
pg_basebackup: waiting for background process to finish streaming ...
pg_basebackup: syncing data to disk ...
pg_basebackup: renaming backup_manifest.tmp to backup_manifest
pg_basebackup: base backup completed  <-----
[postgres@lxicbpgdsgv01 ~]$

5. Prepare & Restore

5.1 Stop PostgreSQL and Clean Directories

[root@lxicbpgdsgv01 ~]# systemctl stop postgresql-17.service
[root@lxicbpgdsgv01 ~]# 
[root@lxicbpgdsgv01 ~]# ps -ef | grep postgres
root        5057    3151  0 18:57 pts/0    00:00:00 grep --color=auto postgres
[root@lxicbpgdsgv01 ~]#

5.2 Remove all from Data & WAL directories

-- Remove all from PGDATA directory

[root@lxicbpgdsgv01 ~]# rm -rf /pgData/pgsql17/data/*
[root@lxicbpgdsgv01 ~]# ls -ltr /pgData/pgsql17/data/
total 0
[root@lxicbpgdsgv01 ~]#

-- Remove all from WAL directory 

[root@lxicbpgdsgv01 ~]# rm -rf /pgWal/pgsql17/wal/*
[root@lxicbpgdsgv01 ~]# ls -ltr /pgWal/pgsql17/wal/
total 0
[root@lxicbpgdsgv01 ~]#

5.3 Restore Data and WAL

A. Copy Backup files to $PGDATA
Since we did not use the -Fp format with the --waldir option, all required WAL files will be included in the backup under the default path: PGDATA/pg_wal.

[postgres@lxicbpgdsgv01 ~]$ ls -ltr /pgData/pgsql17/data/
total 0
[postgres@lxicbpgdsgv01 ~]$ cd /pgBackup/pgsql17/backup/basebackup_10OCT2025/
[postgres@lxicbpgdsgv01 basebackup_10OCT2025]$ cp -Rp * /pgData/pgsql17/data/
[postgres@lxicbpgdsgv01 basebackup_10OCT2025]$
[postgres@lxicbpgdsgv01 basebackup_10OCT2025]$ ls -ltr /pgData/pgsql17/data/
total 296
-rw-------. 1 postgres postgres    227 Oct 10 18:41 backup_label
drwx------. 4 postgres postgres     77 Oct 10 18:41 pg_wal
drwx------. 7 postgres postgres     59 Oct 10 18:41 base
drwx------. 4 postgres postgres     68 Oct 10 18:41 pg_logical
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_dynshmem
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_commit_ts
drwx------. 2 postgres postgres    110 Oct 10 18:41 log
-rw-------. 1 postgres postgres   1169 Oct 10 18:41 postgresql.conf.bkp_10sep2025
-rw-------. 1 postgres postgres  30702 Oct 10 18:41 postgresql.conf.bkp
-rw-------. 1 postgres postgres     88 Oct 10 18:41 postgresql.auto.conf
drwx------. 2 postgres postgres     18 Oct 10 18:41 pg_xact
-rw-------. 1 postgres postgres      3 Oct 10 18:41 PG_VERSION
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_twophase
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_tblspc
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_subtrans
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_stat_tmp
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_stat
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_snapshots
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_serial
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_replslot
drwx------. 2 postgres postgres      6 Oct 10 18:41 pg_notify
drwx------. 4 postgres postgres     36 Oct 10 18:41 pg_multixact
-rw-------. 1 postgres postgres   2640 Oct 10 18:41 pg_ident.conf
-rw-------. 1 postgres postgres   5600 Oct 10 18:41 pg_hba.conf
-rw-------. 1 postgres postgres   1171 Oct 10 18:41 postgresql.conf
drwx------. 2 postgres postgres   4096 Oct 10 18:41 global
-rw-------. 1 postgres postgres     30 Oct 10 18:41 current_logfiles
-rw-------. 1 postgres postgres 227736 Oct 10 18:41 backup_manifest
[postgres@lxicbpgdsgv01 basebackup_10OCT2025]$
B. Copy WAL files from $PGDATA/pg_wal to /pgWal/pgsql17/wal/
[postgres@lxicbpgdsgv01 ~]$ ls -ltr /pgWal/pgsql17/wal/
total 0
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ cd /pgData/pgsql17/data/pg_wal/
[postgres@lxicbpgdsgv01 pg_wal]$ cp -Rp * /pgWal/pgsql17/wal
[postgres@lxicbpgdsgv01 pg_wal]$
[postgres@lxicbpgdsgv01 pg_wal]$ ls -ltr /pgWal/pgsql17/wal
total 16384
drwx------. 2 postgres postgres        6 Oct 10 18:41 summaries
drwx------. 2 postgres postgres        6 Oct 10 18:41 archive_status
-rw-------. 1 postgres postgres 16777216 Oct 10 18:41 000000010000000000000085
[postgres@lxicbpgdsgv01 pg_wal]$ cd
[postgres@lxicbpgdsgv01 ~]$
C. Remove the existing $PGDATA/pg_wal directory
[postgres@lxicbpgdsgv01 ~]$ rm -rf /pgData/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv01 ~]$
D. Create a symbolic link pointing $PGDATA/pg_wal to a separate WAL directory
[postgres@lxicbpgdsgv01 ~]$ ln -s /pgWal/pgsql17/wal /pgData/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ ls -ld /pgData/pgsql17/data/pg_wal
lrwxrwxrwx. 1 postgres postgres 18 Oct 10 19:43 /pgData/pgsql17/data/pg_wal -> /pgWal/pgsql17/wal
[postgres@lxicbpgdsgv01 ~]$
E. Set Permissions
[postgres@lxicbpgdsgv01 ~]$ chown -R postgres:postgres /pgData/pgsql17/data
[postgres@lxicbpgdsgv01 ~]$ chmod 700 /pgData/pgsql17/data
[postgres@lxicbpgdsgv01 ~]$ chown -R postgres:postgres /pgWal/pgsql17/wal
[postgres@lxicbpgdsgv01 ~]$ chmod 700 /pgWal/pgsql17/wal

6. Start PostgreSQL

[root@lxicbpgdsgv01 ~]# systemctl start postgresql-17.service
[root@lxicbpgdsgv01 ~]# systemctl status postgresql-17.service
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Fri 2025-10-10 19:45:21 +08; 5s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 5230 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 5235 (postgres)
      Tasks: 7 (limit: 15835)
     Memory: 34.2M
        CPU: 94ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€5235 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data/
             β”œβ”€5236 "postgres: logger "
             β”œβ”€5237 "postgres: checkpointer "
             β”œβ”€5238 "postgres: background writer "
             β”œβ”€5240 "postgres: walwriter "
             β”œβ”€5241 "postgres: autovacuum launcher "
             └─5242 "postgres: logical replication launcher "

Oct 10 19:45:21 lxicbpgdsgv01.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 10 19:45:21 lxicbpgdsgv01.rajasekhar.com postgres[5235]: 2025-10-10 19:45:21.177 +08 [5235] LOG:  redirecting log output to logging collector process
Oct 10 19:45:21 lxicbpgdsgv01.rajasekhar.com postgres[5235]: 2025-10-10 19:45:21.177 +08 [5235] HINT:  Future log output will appear in directory "log".
Oct 10 19:45:21 lxicbpgdsgv01.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.
[root@lxicbpgdsgv01 ~]#

7. Final Verification

[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \l+
                                                                                       List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   | Tablespace |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+------------+--------------------------------------------
 dell      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7609 kB | pg_default |
 orcl      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7753 kB | pg_default |
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 492 MB  | pg_default | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7569 kB | pg_default | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
(5 rows)

postgres=# \db
       List of tablespaces
    Name    |  Owner   | Location
------------+----------+----------
 pg_default | postgres |
 pg_global  | postgres |
(2 rows)

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=# select * from test.emp;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

dell=#

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/

Clone PostgreSQL Cluster from One Host to Another Using pg_basebackup (No Archive Mode)

How To Backup and Restore PostgreSQL DB Cluster from One Host to Another Using pg_basebackup (No Archive Mode)

Table of Contents


1. Goal
2. Environment (Source / Target)
3. Verify Existing Setup
4. Verify postgresql.conf
5. Verify pg_hba.conf
6. Verify Users
7. Directory Permissions
8. Take Backup
9. Verify Backup
10. Transfer Backup to Target
11. Prepare Target & Restore

Β  Β  Β  Β  Β  Β  Β  Β  Β  11.1 Backup Target (Optional)
Β  Β  Β  Β  Β  Β  Β  Β  Β  11.2 Stop PostgreSQL and Clean Directories
Β  Β  Β  Β  Β  Β  Β  Β  Β  11.3 Restore Data and WAL
Β  Β  Β  Β  Β  Β  Β  Β  Β  11.4 Set Permissions
Β  Β  Β  Β  Β  Β  Β  Β  Β  11.5 Verify Restored Files
Β  Β  Β  Β  Β  Β  Β  Β  Β  11.6 Create Symbolic Link for WAL

12. Start PostgreSQL on Target
13. Final Verification


In PostgreSQL, a cluster is a group of databases managed by one PostgreSQL server. This is just a standalone server, not like an Oracle RAC cluster.

1. Goal

1. Perform a consistent backup using pg_basebackup from lxicbpgdsgv01.
2. Restore the backup on lxicbpgdsgv02 without applying archived WALs.

2. Environment (Source / Target)

AspectSourceTargetDifference
Hostnamelxicbpgdsgv01lxicbpgdsgv02Different hostnames
IP Address192.168.2.51192.168.2.52Different IPs
OSRHEL 9RHEL 9Same
DB VersionPostgreSQL v17.6PostgreSQL v17.6Same
Archive modeNo ArchivelogNo ArchivelogSame
PGDATA/pgData/pgsql17/data/pgdata/pgsql17/dataDifferent path case (D vs d)
WAL Directory/pgWal/pgsql17/wal/pgwal/pgsql17/walDifferent path case (W vs w)
Tablespacepg_defaultpg_defaultSame
DatabasesDELL, ORCLNo DatabasesNeed to clone

Β 3. Verify Existing Setup

[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \l+
                                                                                       List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   | Tablespace |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+------------+--------------------------------------------
 dell      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7763 kB | pg_default |
 orcl      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7907 kB | pg_default |
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 492 MB  | pg_default | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7723 kB | pg_default | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
(5 rows)

postgres=#

postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=#

dell=# \db
       List of tablespaces
    Name    |  Owner   | Location
------------+----------+----------
 pg_default | postgres |
 pg_global  | postgres |
(2 rows)

dell=# 
dell=# \dn test
 List of schemas
 Name |  Owner
------+----------
 test | postgres
(1 row)

dell=#
dell=# \echo :AUTOCOMMIT
on
dell=#

dell=# CREATE TABLE test.emp ( name TEXT, designation TEXT, project TEXT, company TEXT);
CREATE TABLE
dell=# INSERT INTO test.emp VALUES ('Sugi', 'DBA', 'Jetstar', 'iGATE');
INSERT 0 1
dell=# INSERT INTO test.emp VALUES ('Teja', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
dell=# INSERT INTO test.emp VALUES ('RAJ', 'DBA', 'RCM', 'iGATE');
INSERT 0 1
dell=#
dell=# select * from test.emp;
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

dell=#

dell=# \c orcl
You are now connected to database "orcl" as user "postgres".
orcl=#
orcl=# \dt
            List of relations
 Schema |    Name     | Type  |  Owner
--------+-------------+-------+----------
 public | sample_data | table | postgres
(1 row)

orcl=#
orcl=# select count(*) from sample_data;
 count
-------
  1000  <----- 
(1 row)

orcl=#

4. Verify postgresql.conf


postgres=# SHOW wal_level;
 wal_level
-----------
 replica  <---- Should be replica
(1 row)

postgres=#
postgres=# SHOW max_wal_senders;
 max_wal_senders
-----------------
 10 <----- 
(1 row)

postgres=# SHOW archive_mode;
 archive_mode
--------------
 off  <----- No archive log mode
(1 row)

postgres=# show archive_command;
 archive_command
-----------------
 (disabled)
(1 row)

postgres=#

5. Verify pg_hba.conf

# TYPE  DATABASE        USER            ADDRESS             METHOD
# Local connections for replication (for pg_basebackup run locally)
local   replication     all                                 trust

# Remote connections for replication (for pg_basebackup run remotely)
#host    replication     repl_user       192.168.2.52/32     scram-sha-256

6. Verify user permissions:REPLICATION or SUPERUSER required

postgres=# \du
                             List of roles
 Role name |                         Attributes
-----------+------------------------------------------------------------
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS

postgres=#

7. Directory Permissions for Backup

[postgres@lxicbpgdsgv01 ~]$ ls -ld /pgBackup/pgsql17/backup/
drwx------. 2 postgres postgres 6 Oct  9 18:46 /pgBackup/pgsql17/backup/
[postgres@lxicbpgdsgv01 ~]$

8. Take Backup

  • Want symlinks preserved β†’ use (both -Fp & –waldir)-Fp --waldir=/pgWal/pgsql17/wal
  • Want single tar archive β†’ use -Ft, but recreate symlinks after restore, for pg_wal
  • The –waldir option in pg_basebackup is supported only when using the plain format (-Fp), not with the tar format (-Ft).
[postgres@lxicbpgdsgv01 ~]$ nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/pg_basebackup_lxicbpgdsgv01_10sep2025 -Ft -Xs -P > /pgBackup/pgsql17/backup/pg_basebackup_lxicbpgdsgv01_10sep2025.log 2>&1 &
[1] 4438
[postgres@lxicbpgdsgv01 ~]$

**** I have forgot use -v (verbose option to get extra output)
nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/pg_basebackup_lxicbpgdsgv01_10sep2025 -Ft -Xs -P -v > /pgBackup/pgsql17/backup/pg_basebackup_lxicbpgdsgv01_10sep2025.log 2>&1 &

9. Verify Backup


[postgres@lxicbpgdsgv01 ~]$ cat /pgBackup/pgsql17/backup/pg_basebackup_lxicbpgdsgv01_10sep2025.log
nohup: ignoring input
waiting for checkpoint
133816/536026 kB (24%), 0/1 tablespace
299960/536026 kB (55%), 0/1 tablespace
447864/536026 kB (83%), 0/1 tablespace
536037/536037 kB (100%), 0/1 tablespace
536037/536037 kB (100%), 1/1 tablespace
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ ls -lrth /pgBackup/pgsql17/backup/pg_basebackup_lxicbpgdsgv01_10sep2025
total 540M
-rw-------. 1 postgres postgres 524M Oct  9 18:56 base.tar  
-rw-------. 1 postgres postgres 223K Oct  9 18:56 backup_manifest
-rw-------. 1 postgres postgres  17M Oct  9 18:56 pg_wal.tar 
[postgres@lxicbpgdsgv01 ~]$

10. Transfer Backup to Target


[postgres@lxicbpgdsgv01 pg_basebackup_lxicbpgdsgv01_10sep2025]$ scp * 192.168.2.52:/pgbackup/pgsql17/backup/
postgres@192.168.2.52's password:  
backup_manifest                   100%  222KB  30.7MB/s   00:00
base.tar                          100%  523MB  74.0MB/s   00:07
pg_wal.tar                        100%   16MB  43.5MB/s   00:00
[postgres@lxicbpgdsgv01 pg_basebackup_lxicbpgdsgv01_10sep2025]$

11. Prepare Target & Restore

-- List Source Backup files 
[postgres@lxicbpgdsgv02 ~]$ ls -lrth /pgbackup/pgsql17/backup
total 540M
-rw-------. 1 postgres postgres 223K Oct  9 19:08 backup_manifest
-rw-------. 1 postgres postgres 524M Oct  9 19:08 base.tar
-rw-------. 1 postgres postgres  17M Oct  9 19:08 pg_wal.tar
[postgres@lxicbpgdsgv02 ~]$

11.1 Backup Target (Optional)


nohup pg_basebackup -U postgres -D /pgbackup/pgsql17/pg_basebackup_lxicbpgdsgv02_10sep2025 -Ft -Xs -P > /pgbackup/pgsql17/pg_basebackup_lxicbpgdsgv02_10sep2025.log 2>&1 &

-- Verify Tablespaces path -- It's pg_default in our case
-- Verify WAL File (Redo log files) location 

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/pg_wal
lrwxrwxrwx. 1 postgres postgres 18 Oct  9 17:37 /pgdata/pgsql17/data/pg_wal -> /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$

11.2 Stop PostgreSQL and Clean Directories

-- Stop PostgreSQL DB Cluster
[root@lxicbpgdsgv02 ~]# systemctl stop postgresql-17.service
[root@lxicbpgdsgv02 ~]#
[root@lxicbpgdsgv02 ~]# ps -ef | grep postgres
root       10259    7832  0 19:20 pts/0    00:00:00 grep --color=auto postgres
[root@lxicbpgdsgv02 ~]#

-- Remove all from Data directory 

[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgdata/pgsql17/data/*
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data/
total 0
[postgres@lxicbpgdsgv02 ~]$


-- Remove all from WAL directory 

[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgwal/pgsql17/wal/*
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgwal/pgsql17/wal/
total 0
[postgres@lxicbpgdsgv02 ~]$

11.3 Restore Data and WAL

-- List source backup files

[postgres@lxicbpgdsgv02 ~]$ cd /pgbackup/pgsql17/backup/
[postgres@lxicbpgdsgv02 backup]$ ls -ltr
total 552652
-rw-------. 1 postgres postgres    227724 Oct  9 19:08 backup_manifest
-rw-------. 1 postgres postgres 548901888 Oct  9 19:08 base.tar
-rw-------. 1 postgres postgres  16778752 Oct  9 19:08 pg_wal.tar
drwxr-xr-x. 3 postgres postgres        18 Oct  9 19:32 data_lxicbpgdsgv02_old
[postgres@lxicbpgdsgv02 backup]$

# Restore DATA Directory 
[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/base.tar -C /pgdata/pgsql17/data > /pgbackup/pgsql17/backup/base_restore.log 2>&1 &
[1] 11289
[postgres@lxicbpgdsgv02 ~]$


# Restore WAL Directory 

[postgres@lxicbpgdsgv02 ~]$ nohup tar -xvf /pgbackup/pgsql17/backup/pg_wal.tar -C /pgwal/pgsql17/wal > /pgbackup/pgsql17/backup/pg_wal_restore.log 2>&1 &
[1] 11304
[postgres@lxicbpgdsgv02 ~]$

-- OR -- 

# Restore base and WAL archives sequentially in a single command

nohup bash -c "tar -xvf /pgbackup/pgsql17/backup/base.tar -C /pgdata/pgsql17/data && tar -xvf /pgbackup/pgsql17/backup/pg_wal.tar -C /pgwal/pgsql17/wal" > /pgbackup/pgsql17/backup/fulltar_restore.log 2>&1 &

11.4 Set Permissions

[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgdata/pgsql17/data
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ chown -R postgres:postgres /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$ chmod 700 /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$

11.5 Verify Restored Files

[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgdata/pgsql17/data
total 72
-rw-------. 1 postgres postgres    88 Sep 30 21:50 postgresql.auto.conf
drwx------. 2 postgres postgres    18 Sep 30 21:50 pg_xact
-rw-------. 1 postgres postgres     3 Sep 30 21:50 PG_VERSION
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_twophase
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_tblspc
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_subtrans
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_stat_tmp
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_snapshots
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_serial
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_notify
drwx------. 4 postgres postgres    36 Sep 30 21:50 pg_multixact
-rw-------. 1 postgres postgres  2640 Sep 30 21:50 pg_ident.conf
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_dynshmem
drwx------. 2 postgres postgres     6 Sep 30 21:50 pg_commit_ts
-rw-------. 1 postgres postgres 30702 Oct  7 18:20 postgresql.conf.bkp
drwx------. 2 postgres postgres    84 Oct  9 00:01 log
-rw-------. 1 postgres postgres  1169 Oct  9 16:31 postgresql.conf.bkp_10sep2025
-rw-------. 1 postgres postgres  1171 Oct  9 16:32 postgresql.conf
drwx------. 7 postgres postgres    59 Oct  9 18:08 base
drwx------. 2 postgres postgres     6 Oct  9 18:44 pg_stat
-rw-------. 1 postgres postgres    30 Oct  9 18:44 current_logfiles
-rw-------. 1 postgres postgres  5600 Oct  9 18:53 pg_hba.conf
-rw-------. 1 postgres postgres     0 Oct  9 18:56 tablespace_map
drwx------. 2 postgres postgres     6 Oct  9 18:56 pg_replslot
drwx------. 4 postgres postgres    68 Oct  9 18:56 pg_logical
-rw-------. 1 postgres postgres   227 Oct  9 18:56 backup_label
drwx------. 4 postgres postgres    45 Oct  9 20:06 pg_wal <--- Created as Directory, instead of symbolic link 
drwx------. 2 postgres postgres  4096 Oct  9 20:06 global
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ltr /pgwal/pgsql17/wal
total 16384
-rw-------. 1 postgres postgres 16777216 Oct  9 18:56 000000010000000000000045
[postgres@lxicbpgdsgv02 ~]$

Please note:

--- Want symlinks preserved β†’ use -Fp
--- Want single tar archive β†’ use -Ft, but recreate symlinks after restore, for pg_wal

11.6 Create Symbolic Link for WAL

[postgres@lxicbpgdsgv02 ~]$ ls -ld /pgdata/pgsql17/data/pg_wal
drwx------. 4 postgres postgres 45 Oct  9 20:06 /pgdata/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ rm -rf /pgdata/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv02 ~]$ ln -s /pgwal/pgsql17/wal /pgdata/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv02 ~]$
[postgres@lxicbpgdsgv02 ~]$ ls -ld /pgdata/pgsql17/data/pg_wal
lrwxrwxrwx. 1 postgres postgres 18 Oct  9 21:04 /pgdata/pgsql17/data/pg_wal -> /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 ~]$ 
[postgres@lxicbpgdsgv02 ~]$ cd /pgwal/pgsql17/wal
[postgres@lxicbpgdsgv02 wal]$ ll
total 16384
-rw-------. 1 postgres postgres 16777216 Oct  9 18:56 000000010000000000000045
[postgres@lxicbpgdsgv02 wal]$

12. Start PostgreSQL on Target β€” no recovery needed.

[root@lxicbpgdsgv02 ~]# systemctl start postgresql-17.service
[root@lxicbpgdsgv02 ~]# systemctl status postgresql-17.service
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Thu 2025-10-09 21:06:08 +08; 5s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 12375 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 12380 (postgres)
      Tasks: 7 (limit: 20496)
     Memory: 33.6M
        CPU: 114ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€12380 /usr/pgsql-17/bin/postgres -D /pgdata/pgsql17/data
             β”œβ”€12381 "postgres: logger "
             β”œβ”€12382 "postgres: checkpointer "
             β”œβ”€12383 "postgres: background writer "
             β”œβ”€12385 "postgres: walwriter "
             β”œβ”€12386 "postgres: autovacuum launcher "
             └─12387 "postgres: logical replication launcher "

Oct 09 21:06:06 lxicbpgdsgv02.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 09 21:06:06 lxicbpgdsgv02.rajasekhar.com postgres[12380]: 2025-10-09 21:06:06.781 +08 [12380] LOG:  redirecting log output to logging collector process
Oct 09 21:06:06 lxicbpgdsgv02.rajasekhar.com postgres[12380]: 2025-10-09 21:06:06.781 +08 [12380] HINT:  Future log output will appear in directory "log".
Oct 09 21:06:08 lxicbpgdsgv02.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.
[root@lxicbpgdsgv02 ~]#

13. Final Verification

[postgres@lxicbpgdsgv02 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# \l+
                                                                                       List of databases
   Name    |  Owner   | Encoding | Locale Provider |   Collate   |    Ctype    | Locale | ICU Rules |   Access privileges   |  Size   | Tablespace |                Description
-----------+----------+----------+-----------------+-------------+-------------+--------+-----------+-----------------------+---------+------------+--------------------------------------------
 dell      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7609 kB | pg_default |
 orcl      | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 7753 kB | pg_default |
 postgres  | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           |                       | 492 MB  | pg_default | default administrative connection database
 template0 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7545 kB | pg_default | unmodifiable empty database
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
 template1 | postgres | UTF8     | libc            | en_SG.UTF-8 | en_SG.UTF-8 |        |           | =c/postgres          +| 7569 kB | pg_default | default template for new databases
           |          |          |                 |             |             |        |           | postgres=CTc/postgres |         |            |
(5 rows)

postgres=# \db
       List of tablespaces
    Name    |  Owner   | Location
------------+----------+----------
 pg_default | postgres |
 pg_global  | postgres |
(2 rows)

postgres=#
postgres=# \c dell
You are now connected to database "dell" as user "postgres".
dell=# \dt test.*
        List of relations
 Schema | Name | Type  |  Owner
--------+------+-------+----------
 test   | emp  | table | postgres
(1 row)

dell=#

dell=# select * from test.emp;  <---- We can see Data 
 name | designation | project | company
------+-------------+---------+---------
 Sugi | DBA         | Jetstar | iGATE
 Teja | DBA         | RCM     | iGATE
 RAJ  | DBA         | RCM     | iGATE
(3 rows)

dell=#
dell=# \c orcl
You are now connected to database "orcl" as user "postgres".
orcl=# \dt
            List of relations
 Schema |    Name     | Type  |  Owner
--------+-------------+-------+----------
 public | sample_data | table | postgres
(1 row)

orcl=#
orcl=# select count(*) from sample_data;
 count
-------
  1000 <----
(1 row)

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/

Disable ARCHIVELOG Mode

How to Disable ARCHIVELOG Mode

Table of Contents


1. Verify Existing Archive Mode
2. Edit the archive settings
3. Restart PostgreSQL
4. Verify Current Mode
5. Verify WAL Archiving Behavior


1. Verify Existing Archive Mode

postgres=# SHOW archive_mode;
 archive_mode
--------------
 on  <------ 
(1 row)

postgres=#

postgres=# SHOW archive_command;
        archive_command
-------------------------------
 cp %p /pgArch/pgsql17/arch/%f  <----- 
(1 row)

postgres=#

2. Edit the archive settings


[postgres@lxicbpgdsgv01 ~]$ cp /pgData/pgsql17/data/postgresql.conf /pgData/pgsql17/data/postgresql.conf.bkp_10sep2025
[postgres@lxicbpgdsgv01 ~]$ vi /pgData/pgsql17/data/postgresql.conf

#archive_mode = on
#archive_command = 'cp %p /pgArch/pgsql17/arch/%f'

3. Restart PostgreSQL

[root@lxicbpgdsgv01 ~]# systemctl stop postgresql-17.service
[root@lxicbpgdsgv01 ~]#
[root@lxicbpgdsgv01 ~]# systemctl start  postgresql-17.service
[root@lxicbpgdsgv01 ~]#
[root@lxicbpgdsgv01 ~]# systemctl status postgresql-17.service
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Thu 2025-10-09 16:34:01 +08; 3s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 3492 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 3497 (postgres)
      Tasks: 7 (limit: 15835)
     Memory: 17.6M
        CPU: 92ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€3497 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data/
             β”œβ”€3498 "postgres: logger "
             β”œβ”€3499 "postgres: checkpointer "
             β”œβ”€3500 "postgres: background writer "
             β”œβ”€3502 "postgres: walwriter "
             β”œβ”€3503 "postgres: autovacuum launcher "
             └─3504 "postgres: logical replication launcher "

Oct 09 16:34:01 lxicbpgdsgv01.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 09 16:34:01 lxicbpgdsgv01.rajasekhar.com postgres[3497]: 2025-10-09 16:34:01.929 +08 [3497] LOG:  redirecting log output to logging collector process
Oct 09 16:34:01 lxicbpgdsgv01.rajasekhar.com postgres[3497]: 2025-10-09 16:34:01.929 +08 [3497] HINT:  Future log output will appear in directory "log".
Oct 09 16:34:01 lxicbpgdsgv01.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.
[root@lxicbpgdsgv01 ~]#

4. Verify Current Mode

[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# SHOW archive_mode;
 archive_mode
--------------
 off  <------ it's disabled
(1 row)

postgres=# SHOW archive_command;
 archive_command
-----------------
 (disabled) <-------
(1 row)

postgres=#

5. Verify WAL Archiving Behavior


postgres=# CHECKPOINT;
CHECKPOINT
postgres=#
postgres=# CHECKPOINT;
CHECKPOINT
postgres=# CHECKPOINT;
CHECKPOINT
postgres=#
postgres=# exit
postgres=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/44000000
(1 row)

postgres=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/44000000
(1 row)

postgres=# SELECT pg_switch_wal();
 pg_switch_wal
---------------
 0/44000000
(1 row)

postgres=#
[postgres@lxicbpgdsgv01 ~]$ ls -ltr /pgArch/pgsql17/arch/
total 0  <---- Archivelogs not generating
[postgres@lxicbpgdsgv01 ~]$

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/

pg_basebackup

pg_basebackup – Backup, Restore, and Recovery

What isΒ pg_basebackup?

pg_basebackup is a utility provided by PostgreSQL to take a physical base backup of the entire database cluster.

Common Use Cases:

  • Setting up standby servers for streaming replication
  • Creating physical backups for disaster recovery
  • Performing Point-In-Time Recovery (PITR)
  • Performing Incremental Backups (PostgreSQL v17 feature)

It connects to a running PostgreSQL server and copies all necessary data files and WAL segments, producing a consistent and restorable backup.

———- Backup ———-

Pre-requisites parameter and config:

Β  Β  Β  1. User :Β Requires a user with replication role or superuser privileges
CREATE ROLE repl_user WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'replpass';
Β  Β  Β 2. postgresql.conf
  • wal_level=replicaΒ  (Mandatory)
  • max_wal_senders >=1 (Mandatory)
  • archive_mode=on (Optional if Database in NO Archivelog mode)
  • archive_command = ‘cp %p /pgArch/pgsql17/arch/%f’ (Optional if Database in NO Archivelog mode)
Β  Β  Β  3. pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS             METHOD
# Local connections for replication (for pg_basebackup run locally)
local   replication     all                                 trust

# or you can use peer (if same OS user postgres is used)
# local   replication     all                                 peer

# Remote connections for replication (for pg_basebackup run remotely)
host    replication     repl_user       192.168.2.22/32     scram-sha-256

HowΒ pg_basebackupΒ Works Internally:

Featurepg_basebackup Supports?
Backup of data directoryYes
Include enough WALs to make backup consistentYes
Backup of WAL archives (even with archive mode=on & archive_command configured)No
Works without archive_modeYes
  • Performs a physical file-level backup by copying the full data directory
  • Uses PostgreSQL’s streaming replication protocol
  • Requires a user with replication role or superuser privileges
  • Can be used while the server is running (online backup)
  • Ensures a transactionally consistent snapshot of the database
  • Even with archive_mode=on and archive_command configured, pg_basebackup does not back up WAL archive logs from the archive location. It only includes enough live WAL files to make the backup consistent, streamed from pg_wal/.
  • pg_basebackup does not include all files from the pg_wal directory in the backup.
    Instead, it selectively includes only the WAL files required to make the base backup consistent at the point in time the backup was taken.

What It Includes:

  • All essential data files of the cluster
  • Necessary WAL (Write-Ahead Log) segments for recovery
  • Custom tablespaces, replication slots, and large objects

WAL Handling Options:

  • Default: WAL files included after backup (-X fetch)
  • Streaming: WAL files streamed live during backup (-X stream)

How to take Backup using pg_basebackup ?

  • Want symlinks preserved β†’ use (both -Fp & –waldir)-Fp --waldir=/pgWal/pgsql17/wal
  • Want single tar archive β†’ use -Ft, but recreate symlinks after restore, for pg_wal
  • The –waldir option in pg_basebackup is supported only when using the plain format (-Fp), not with the tar format (-Ft).
-- Do not use -R here since it's not a replica (No standby).

Typically Backup using: Plain format, Tar format & Tar format (gzip)

1. Take backup in Plain format
nohup pg_basebackup -U postgres -D /pgBackups/pgsql17/demo_restore -Fp -Xs -P -v > pg_basebackup_demo_restore.log 2>&1 &

2. Take backup in Tar format
nohup pg_basebackup -U postgres -D /pgBackups/pgsql17/demo_tar_backup -Ft -Xs -P -v > pg_basebackup_tar.log 2>&1 &

3. Take backup in Compressed Tar format (gzip)
nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/ -Ft -z -Xs -P -v > pg_basebackup_tar.log 2>&1 &

4. Take compressed Tar backup with transfer rate limit
nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/ -Ft -z -X stream -P --max-rate=5M -v > pg_basebackup_tar.log 2>&1 &

5. Take compressed Tar backup with server-side gzip compression at max level (9)
nohup pg_basebackup -U postgres -D /pgBackup/pgsql17/backup/ -Ft --compress=server-gzip:9 -Xs -P -v > pg_basebackup.log 2>&1 &

6. Take Tar backup from a remote host
nohup pg_basebackup -h remote_host -p port -U postgres -D /pgBackup/remote_tar_backup -Ft -Xs -P -v > pg_basebackup_remote_tar.log 2>&1 &
PG BASE BACKUP FlagDescription
-U <username>Specifies the PostgreSQL user to connect as.
-D <directory>Specifies the target directory for the backup.
-F pTakes the backup in Plain format (file system copy).
-F tTakes the backup in Tar archive format.
-zCompresses the backup using gzip compression (only valid with tar format).
--compress=server-gzip:<level>Enables server-side gzip compression with specified compression level (1-9).
-X sIncludes the Write-Ahead Log (WAL) files by copying the WAL segment files.
-X streamStreams the WAL files while taking the backup for continuous consistency.
-PShows progress information during the backup.
--max-rate=<rate>Limits the maximum transfer rate during the backup (e.g., 5M for 5 megabytes/sec).
-v–verbose, extra output

———- RestoreΒ ———-

1. Restore is a File-Level Operation

A base backup is a physical copy of the database files β€” including system catalogs, user data, WAL files, and optionally config files.
Restoring is done by simply copying or extracting the backup files into a valid PostgreSQL data directory (PGDATA) on the target system.

Restore Steps:

  1. Stop PostgreSQL (if running)
  2. Copy or extract the backup into a clean data directory (PGDATA)
  3. Place a file named recovery.signal in the data directory
  4. Start PostgreSQL to begin recovery

2. Custom Tablespaces Outside PGDATA

  • Backups include symlinks to external tablespace locations
  • On restore:
    • Ensure original paths exist and are accessible
    • Or remap symlinks to new locations
    • Check ownership and permissions (postgres:postgres, 0700)

3. Restoring on a Different Host

  • Ensure matching directory structure or adjust accordingly
  • PostgreSQL version and architecture must match
  • Update postgresql.conf and pg_hba.conf as needed

4. Restoring Across PostgreSQL Versions

pg_basebackup is version-specific.

  • Not allowed: PostgreSQL 14 β†’ PostgreSQL 15 or 17 (Lower to Higher)
  • Not allowed: PostgreSQL 17 β†’ PostgreSQL 14 (Higher to Lower)
  • Use pg_dump/pg_restore or pg_upgrade for version upgrades

———-Β Recovery ———-

How Recovery Works:

  1. PostgreSQL detects recovery.signal at startup
  2. WAL files (in pg_wal/ or archive) are replayed (Redo apply / Archive applyΒ  from restore_command location )
  3. When recovery completes:
    • PostgreSQL automatically removes recovery.signal
    • The server becomes a primary (read/write)
  4. Recovery stops when:
    • All available WALs are applied, or
    • A recovery target (e.g., timestamp, transaction ID) is reached

What is recovery.signal ?

FilePurpose
recovery.signalTells PostgreSQL to enter recovery mode during startup
Automatically removed?Yes, after recovery completes
Required for standalone restore?Yes, otherwise WAL replay is skipped

SummaryΒ 

1. Take a base backup on the source server using ‘pg_basebackup’.
2. Take Backup of WAL Archive files separately on Source (Manually, because pg_basebackup does NOT take backup of WAL archive files)
3. Transfer both the base backup and WAL archive logs to the target server.
4. Restore the base backup to the PostgreSQL data directory on the target.
5. Copy the WAL files to the dedicated WAL location (e.g., ‘/pgwal/pgsql17/wals’).
6. Remove ‘$PGDATA/pg_wal’ and create a symbolic link to the WAL location:
‘ln -s /pgwal/pgsql17/wals /pgdata/pgsql17/data/pg_wal’
7. Create an empty ‘recovery.signal‘ file in ‘$PGDATA’.
8. Set ‘restore_command‘ in ‘postgresql.conf’ to point to WAL archive backup path (e.g., ‘/pgbackup/pgsql17/backup/wal_archive_bkp’).
9. Ensure WAL archive files are restored to ‘/pgbackup/pgsql17/backup/wal_archive_bkp’ for ‘restore_command’ to access.
10. Update ‘tablespace_map‘ to reflect correct paths if using custom tablespaces.
11. Start PostgreSQL on the target; recovery will complete and automatically remove ‘recovery.signal’.
12. Tablespace symbolic links will create automatically by PostgreSQL.

OperationKey Point
BackupFile-level copy using replication protocol
RestorePlace files into PGDATA, handle symlinks, configs, and versions
RecoveryTriggered by recovery.signal, replays WAL, auto-removes signal file

 

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/

Change PostgreSQL WAL Directory Path (pg_wal)

Change WAL Directory Path (pg_wal) in PostgreSQL

Table of Contents


0. Aim
1. Verify Existing pg_wal Directory
2. Create the New Directory
3. Stop PostgreSQL Service
4. Copy WAL Files to New Location
5. Backup Old WAL Directory
6. Create Symlink
7. Fix Permissions
8. Start PostgreSQL Service
9. Verify WAL Functionality
10. Remove Old WAL Directory (Optional)


0. Aim

To change the PostgreSQL 17 WAL File directory from its default location to new mount point

From : /pgData/pgsql17/data/pg_wal

TO : /pgWal/pgsql17/wal

1. Verify Existing pg_wal directory


[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# SELECT current_setting('data_directory') || '/pg_wal' AS wal_directory;
        wal_directory
-----------------------------
 /pgData/pgsql17/data/pg_wal  <----- 
(1 row)

postgres=# exit
[postgres@lxicbpgdsgv01 ~]$ ls -lrth /pgData/pgsql17/data/pg_wal
total 48M
drwx------. 2 postgres postgres   6 Sep 30 21:50 summaries
-rw-------. 1 postgres postgres 16M Oct  8 04:24 000000010000000000000008
-rw-------. 1 postgres postgres 16M Oct  8 16:08 000000010000000000000006
-rw-------. 1 postgres postgres 16M Oct  8 16:08 000000010000000000000007
drwx------. 2 postgres postgres  43 Oct  8 16:08 archive_status
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ du -sh /pgData/pgsql17/data/pg_wal
48M     /pgData/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv01 ~]$

2. Create the New Directory on a new disk

[root@lxicbpgdsgv01 ~]# mkdir -p /pgWal/pgsql17/wal
[root@lxicbpgdsgv01 ~]# chown postgres:postgres /pgWal/pgsql17/wal
[root@lxicbpgdsgv01 ~]# chmod 700 /pgWal/pgsql17/wal
[root@lxicbpgdsgv01 ~]#

3. Stop PostgreSQL Service

[root@lxicbpgdsgv01 ~]# systemctl stop postgresql-17.service
[root@lxicbpgdsgv01 ~]#
[root@lxicbpgdsgv01 ~]# ps -ef | grep postgres
root        6887    6721  0 16:08 pts/0    00:00:00 grep --color=auto postgres
[root@lxicbpgdsgv01 ~]#

4. Copy Existing WAL Files to New Location

[postgres@lxicbpgdsgv01 ~]$ nohup rsync -avh --progress /pgData/pgsql17/data/pg_wal/ /pgWal/pgsql17/wal/ > rsync_pgwal.log 2>&1 &
[1] 6943
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$
[1]+  Done                    nohup rsync -avh --progress /pgData/pgsql17/data/pg_wal/ /pgWal/pgsql17/wal/ > rsync_pgwal.log 2>&1
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ cat rsync_pgwal.log
nohup: ignoring input
sending incremental file list
./
000000010000000000000006
         16.78M 100%   81.89MB/s    0:00:00 (xfr#1, to-chk=5/7)
000000010000000000000007
         16.78M 100%   43.84MB/s    0:00:00 (xfr#2, to-chk=4/7)
000000010000000000000008
         16.78M 100%   31.07MB/s    0:00:00 (xfr#3, to-chk=3/7)
archive_status/
archive_status/000000010000000000000006.done
              0 100%    0.00kB/s    0:00:00 (xfr#4, to-chk=0/7)
summaries/

sent 50.34M bytes  received 107 bytes  33.56M bytes/sec
total size is 50.33M  speedup is 1.00
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ ls -lrth /pgWal/pgsql17/wal/
total 48M
drwx------. 2 postgres postgres   6 Sep 30 21:50 summaries
-rw-------. 1 postgres postgres 16M Oct  8 04:24 000000010000000000000008
-rw-------. 1 postgres postgres 16M Oct  8 16:08 000000010000000000000006
-rw-------. 1 postgres postgres 16M Oct  8 16:08 000000010000000000000007
drwx------. 2 postgres postgres  43 Oct  8 16:08 archive_status
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ du -sh /pgWal/pgsql17/wal/
48M     /pgWal/pgsql17/wal/
[postgres@lxicbpgdsgv01 ~]$

5. Move old directory as backup

[postgres@lxicbpgdsgv01 ~]$ mv /pgData/pgsql17/data/pg_wal /pgData/pgsql17/data/pg_wal.bak
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ ls -ld /pgData/pgsql17/data/pg_wal
ls: cannot access '/pgData/pgsql17/data/pg_wal': No such file or directory
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ ls -ld /pgData/pgsql17/data/pg_wal.bak
drwx------. 4 postgres postgres 141 Oct  8 16:08 /pgData/pgsql17/data/pg_wal.bak
[postgres@lxicbpgdsgv01 ~]$

6. Create symlink

[postgres@lxicbpgdsgv01 ~]$ ln -s /pgWal/pgsql17/wal /pgData/pgsql17/data/pg_wal
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ ls -ltr /pgData/pgsql17/data/pg_wal
lrwxrwxrwx. 1 postgres postgres 18 Oct  8 16:16 /pgData/pgsql17/data/pg_wal -> /pgWal/pgsql17/wal
[postgres@lxicbpgdsgv01 ~]$

7. Fix permissions (if required)

[postgres@lxicbpgdsgv01 ~]$ chown -R postgres:postgres /pgWal/pgsql17/wal

8. Start PostgreSQL Service

[root@lxicbpgdsgv01 ~]# systemctl start postgresql-17.service
[root@lxicbpgdsgv01 ~]#
[root@lxicbpgdsgv01 ~]# systemctl status postgresql-17.service
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Wed 2025-10-08 16:20:46 +08; 7s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 7079 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 7084 (postgres)
      Tasks: 8 (limit: 15835)
     Memory: 18.1M
        CPU: 94ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€7084 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data/
             β”œβ”€7086 "postgres: logger "
             β”œβ”€7087 "postgres: checkpointer "
             β”œβ”€7088 "postgres: background writer "
             β”œβ”€7090 "postgres: walwriter "
             β”œβ”€7091 "postgres: autovacuum launcher "
             β”œβ”€7092 "postgres: archiver "
             └─7093 "postgres: logical replication launcher "

Oct 08 16:20:46 lxicbpgdsgv01.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 08 16:20:46 lxicbpgdsgv01.rajasekhar.com postgres[7084]: 2025-10-08 16:20:46.162 +08 [7084] LOG:  redirecting log output to logging collector process
Oct 08 16:20:46 lxicbpgdsgv01.rajasekhar.com postgres[7084]: 2025-10-08 16:20:46.162 +08 [7084] HINT:  Future log output will appear in directory "log".
Oct 08 16:20:46 lxicbpgdsgv01.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.
[root@lxicbpgdsgv01 ~]#

9. Verify

-- Load WAL File generation (Testing)

postgres=# -- Create test table
DROP TABLE IF EXISTS wal_test;
CREATE TABLE wal_test (
    id serial PRIMARY KEY,
    data text
);

-- Generate WAL traffic
DO $$
DECLARE
    i integer;
BEGIN
    FOR i IN 1..50 LOOP
        -- INSERT: 10,000 rows
        INSERT INTO wal_test (data)
        SELECT repeat('wal_test_data_', 50)
        FROM generate_series(1, 10000);

        -- UPDATE: 5,000 rows using CTE with LIMIT
        WITH to_update AS (
            SELECT id FROM wal_test WHERE id % 2 = 0 LIMIT 5000
        )
        UPDATE wal_test
        SET data = data || '_updated'
        WHERE id IN (SELECT id FROM to_update);

        -- DELETE: 5,000 rows using CTE with LIMIT
        WITH to_delete AS (
            SELECT id FROM wal_test WHERE id % 3 = 0 LIMIT 5000
        )
        DELETE FROM wal_test
        WHERE id IN (SELECT id FROM to_delete);

        -- Commit to flush WAL
        COMMIT;

        -- Optional pause to slow down the loop
        PERFORM pg_sleep(0.5);
    END LOOP;
END$$;
DROP TABLE
CREATE TABLE
DO
postgres=# exit
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ ls -lrth  /pgWal/pgsql17/wal
total 752M
drwx------. 2 postgres postgres    6 Sep 30 21:50 summaries
-rw-------. 1 postgres postgres  16M Oct  8 16:34 000000010000000000000009
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000A
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000B
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000C
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000D
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000E
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000F
-rw-------. 1 postgres postgres  16M Oct  8 16:34 000000010000000000000010
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000011
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000012
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000013
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000014
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000015
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000016
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000017
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000018
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000019
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001A
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001B
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001C
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001D
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001E
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001F
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000020
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000021
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000022
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000023
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000024
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000025
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000026
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000027
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000028
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000029
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002A
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002B
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002C
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002D
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002E
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002F
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000030
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000031
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000032
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000033
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000034
-rw-------. 1 postgres postgres  16M Oct  8 16:36 000000010000000000000035
drwx------. 2 postgres postgres 4.0K Oct  8 16:36 archive_status
-rw-------. 1 postgres postgres  16M Oct  8 16:36 xlogtemp.7289
[postgres@lxicbpgdsgv01 ~]$

10. Remove Old WAL Directory (Optional, later)

[postgres@lxicbpgdsgv01 ~]$ ls -ld /pgData/pgsql17/data/pg_wal.bak
drwx------. 4 postgres postgres 141 Oct  8 16:08 /pgData/pgsql17/data/pg_wal.bak
[postgres@lxicbpgdsgv01 ~]$ rm -rf /pgData/pgsql17/data/pg_wal.bak
[postgres@lxicbpgdsgv01 ~]$
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

WAL Files

Understanding WAL Files in PostgreSQL – For Oracle DBAs

What is WAL?

WAL (Write-Ahead Logging) ensures data durability and crash recovery. Every change is first written to WAL before being flushed to data files. 

1. WAL Location: WAL files are stored in $PGDATA/pg_wal/.
2. Fixed Size: Each WAL segment is pre-allocated with a fixed size (typically 16MB), set at cluster initialization (initdb).
3. Writing & Switching: WAL segments are written sequentially. PostgreSQL switches to the next segment when the current one is full or a manual switch is triggered (e.g., via pg_switch_wal()).
4. WAL and Archive File Size: When archived, the exact same 16MB WAL segment file is copied as raw binary to the archive destination. Therefore, archive files always match the WAL segment size.
5. Archiving: If archive_mode = on, PostgreSQL uses the archive_command to copy completed WAL segments to the archive destination (e.g., /pgArch/...). Only full segments are archived.
6. Recycling: If archiving is disabled, PostgreSQL reuses old WAL segments once they’re no longer needed for recovery or replication.

WAL Files = Redo Log Files
WAL Archives = Archive Log Files

PostgreSQL vs Oracle Comparison

AspectOraclePostgreSQL
Redo Log FilesCalled Redo Log FilesCalled WAL Files
Archive Log FilesCalled Archive Log FilesCalled WAL Archives
Redo Log File Size~200MB (default)16MB (default and fixed)
Redo Log Files CountMinimum 2 or more redo log groups
(Best practice: 3)
No fixed number
Controlled by: min_wal_size / wal_segment_size
Example: 80MB / 16MB = 5 WAL files
Archive Log File Size~200MB (same as redo log file size)16MB (same as WAL file size)
Log File StorageRedo log files stored in redo log groupsWAL files stored in pg_wal directory
Archiving MechanismArchive logs created if archiving is enabledArchived via archive_command if archive_mode = on
Overwrite BehaviorRedo logs are overwritten when full (if archive not enabled)WAL segments are recycled/overwritten when full (if archive_mode is off)
Force Switch BehaviorALTER SYSTEM SWITCH LOGFILE;SELECT pg_switch_wal();

PostgreSQL WAL Configuration Parameters

ParameterMeaningDefault
wal_segment_sizeSize of each WAL file16MB
min_wal_sizeMinimum total WAL size retained80MB (5 WAL files)
Common in production: 8GB
max_wal_sizeMax WAL before triggering a checkpoint1GB
Common in production: 16GB

Check Configuration

[postgres@lxicbpgdsgv01 ~]$ psql -c "SHOW wal_segment_size;"
wal_segment_size
------------------
16MB  <----- Each redo log file size
(1 row)

[postgres@lxicbpgdsgv01 ~]$


[postgres@lxicbpgdsgv01 ~]$ psql -c "SHOW min_wal_size;"
 min_wal_size
--------------
 80MB <---- 80MB/16MB = 5 <--- Total 5 redo log files with each 16MB
(1 row)

[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ psql -c "SHOW max_wal_size;"
 max_wal_size
--------------
 1GB  <---- 1024MB
(1 row)

[postgres@lxicbpgdsgv01 ~]$

View WAL files (Redo log files)

postgres=# SELECT current_setting('data_directory') || '/pg_wal' AS wal_directory;
        wal_directory
-----------------------------
 /pgData/pgsql17/data/pg_wal  <---- Redo log file directory
(1 row)

postgres=# 
[postgres@lxicbpgdsgv01 ~]$ ls -lh /pgData/pgsql17/data/pg_wal | grep -E '^-.* [0-9]+ .* [0-9A-F]{24}$'
-rw-------. 1 postgres postgres 16M Oct 8 01:33 000000010000000000000005
-rw-------. 1 postgres postgres 16M Oct 8 01:28 000000010000000000000006
-rw-------. 1 postgres postgres 16M Oct 8 01:28 000000010000000000000007
[postgres@lxicbpgdsgv01 ~]$

min_wal_size = 80MB means PostgreSQL will try to keep at least 5 WAL segment files on disk (since 80MB Γ· 16MB = 5 files).

However, in our case, only 3 WAL files are currently present. This is likely because the system is under low load in the testing environment, so fewer WAL files are needed at the moment.

---- Lets Generate Load

postgres=# -- Create test table
DROP TABLE IF EXISTS wal_test;
CREATE TABLE wal_test (
    id serial PRIMARY KEY,
    data text
);

-- Generate WAL traffic
DO $$
DECLARE
    i integer;
BEGIN
    FOR i IN 1..50 LOOP
        -- INSERT: 10,000 rows
        INSERT INTO wal_test (data)
        SELECT repeat('wal_test_data_', 50)
        FROM generate_series(1, 10000);

        -- UPDATE: 5,000 rows using CTE with LIMIT
        WITH to_update AS (
            SELECT id FROM wal_test WHERE id % 2 = 0 LIMIT 5000
        )
        UPDATE wal_test
        SET data = data || '_updated'
        WHERE id IN (SELECT id FROM to_update);

        -- DELETE: 5,000 rows using CTE with LIMIT
        WITH to_delete AS (
            SELECT id FROM wal_test WHERE id % 3 = 0 LIMIT 5000
        )
        DELETE FROM wal_test
        WHERE id IN (SELECT id FROM to_delete);

        -- Commit to flush WAL
        COMMIT;

        -- Optional pause to slow down the loop
        PERFORM pg_sleep(0.5);
    END LOOP;
END$$;
DROP TABLE
CREATE TABLE
DO
postgres=# exit
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ 
ls -lrth /pgData/pgsql17/data/pg_wal
total 752M
drwx------. 2 postgres postgres    6 Sep 30 21:50 summaries
-rw-------. 1 postgres postgres  16M Oct  8 16:34 000000010000000000000009
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000A
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000B
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000C
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000D
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000E
-rw-------. 1 postgres postgres  16M Oct  8 16:34 00000001000000000000000F
-rw-------. 1 postgres postgres  16M Oct  8 16:34 000000010000000000000010
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000011
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000012
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000013
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000014
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000015
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000016
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000017
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000018
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000019
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001A
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001B
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001C
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001D
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001E
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000001F
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000020
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000021
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000022
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000023
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000024
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000025
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000026
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000027
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000028
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000029
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002A
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002B
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002C
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002D
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002E
-rw-------. 1 postgres postgres  16M Oct  8 16:35 00000001000000000000002F
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000030
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000031
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000032
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000033
-rw-------. 1 postgres postgres  16M Oct  8 16:35 000000010000000000000034
-rw-------. 1 postgres postgres  16M Oct  8 16:36 000000010000000000000035
drwx------. 2 postgres postgres 4.0K Oct  8 16:36 archive_status
-rw-------. 1 postgres postgres  16M Oct  8 16:36 xlogtemp.7289
[postgres@lxicbpgdsgv01 ~]$ 

-- Now We can see Many WAL Files (Redo log files) generated, count increased from 3 WAL files to 50+ WAL files

View Archived WAL Files (Archive log files)

postgres=# SHOW archive_command;
        archive_command
-------------------------------
 cp %p /pgArch/pgsql17/arch/%f
(1 row)

postgres=#

[postgres@lxicbpgdsgv01 ~]$ 
[postgres@lxicbpgdsgv01 ~]$ ls -lrth /pgArch/pgsql17/arch/
total 976M
-rw-------. 1 postgres postgres 16M Oct  7 23:50 000000010000000000000001
-rw-------. 1 postgres postgres 16M Oct  7 23:51 000000010000000000000002
-rw-------. 1 postgres postgres 16M Oct  8 01:28 000000010000000000000003
-rw-------. 1 postgres postgres 16M Oct  8 01:28 000000010000000000000004
-rw-------. 1 postgres postgres 16M Oct  8 04:24 000000010000000000000005
-rw-------. 1 postgres postgres 16M Oct  8 16:08 000000010000000000000006
-rw-------. 1 postgres postgres 16M Oct  8 16:24 000000010000000000000007
-rw-------. 1 postgres postgres 16M Oct  8 16:25 000000010000000000000008
-rw-------. 1 postgres postgres 16M Oct  8 16:34 000000010000000000000009
-rw-------. 1 postgres postgres 16M Oct  8 16:34 00000001000000000000000A
-rw-------. 1 postgres postgres 16M Oct  8 16:34 00000001000000000000000B
-rw-------. 1 postgres postgres 16M Oct  8 16:34 00000001000000000000000C
-rw-------. 1 postgres postgres 16M Oct  8 16:34 00000001000000000000000D
-rw-------. 1 postgres postgres 16M Oct  8 16:34 00000001000000000000000E
-rw-------. 1 postgres postgres 16M Oct  8 16:34 00000001000000000000000F
-rw-------. 1 postgres postgres 16M Oct  8 16:34 000000010000000000000010
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000011
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000012
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000013
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000014
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000015
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000016
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000017
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000018
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000019
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000001A
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000001B
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000001C
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000001D
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000001E
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000001F
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000020
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000021
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000022
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000023
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000024
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000025
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000026
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000027
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000028
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000029
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000002A
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000002B
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000002C
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000002D
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000002E
-rw-------. 1 postgres postgres 16M Oct  8 16:35 00000001000000000000002F
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000030
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000031
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000032
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000033
-rw-------. 1 postgres postgres 16M Oct  8 16:35 000000010000000000000034
-rw-------. 1 postgres postgres 16M Oct  8 16:36 000000010000000000000035
-rw-------. 1 postgres postgres 16M Oct  8 16:36 000000010000000000000036
-rw-------. 1 postgres postgres 16M Oct  8 16:36 000000010000000000000037
-rw-------. 1 postgres postgres 16M Oct  8 16:36 000000010000000000000038
-rw-------. 1 postgres postgres 16M Oct  8 16:36 000000010000000000000039
-rw-------. 1 postgres postgres 16M Oct  8 16:36 00000001000000000000003A
-rw-------. 1 postgres postgres 16M Oct  8 16:36 00000001000000000000003B
-rw-------. 1 postgres postgres 16M Oct  8 16:36 00000001000000000000003C
-rw-------. 1 postgres postgres 16M Oct  8 16:36 00000001000000000000003D
[postgres@lxicbpgdsgv01 ~]$

-- WAL and Archive File Size: When archived, the exact same 16MB WAL segment file is copied as raw binary to the archive destination. Therefore, archive files always match the WAL segment size (redo log size). 

Best Practices

  • Use a dedicated mount point for pg_wal (WAL directory) – eg. /pgWal
  • Set min_wal_size to higher value in production (e.g. 8GB)
  • Keep WAL archive files on a separate mount point for better I/O and space isolation – eg. /pgArch
  • Monitor WAL archive directory regularly to avoid disk full errors

Note:

  • WAL file size is fixed at cluster init (default: 16MB). You cannot change it for an existing cluster.
  • PostgreSQL WAL Size Be Can Increased only at NEW cluster creation time via initdb (64MB)
    /usr/pgsql-17/bin/initdb –wal-segsize=64 -D /pgData/pgsql17/data

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/

Enable Archive Mode (WAL Archiving)

Enable Archive Mode in PostgreSQL 17


Table of Contents

0. Importance of Archive Log Files
1. Verify Existing Archive Mode
2. Ensure Archive Directory Exists
3. Edit postgresql.conf
4. Restart PostgreSQL
5. Verify the Configuration
6. Test Archiving Works


0. Importance of Archive Log Files

Archive log files, also known as WAL archives (Write-Ahead Log archives) , play a critical role in PostgreSQL for data protection, recovery, and replication.

A. Point-in-Time Recovery (PITR): Restore the database to a specific point in time, useful for accidental data changes or loss.
B. Continuous Backup: Works with base backups to enable robust disaster recovery.
C. Streaming Replication Support: Helps standby servers catch up if they fall behind.
D. Disaster Recovery: Enables full recovery after hardware or data corruption.
E. Data Audit & Analysis: Allows decoding WAL logs for auditing and compliance.

πŸ›‘ Important Note:

If WAL archiving is disabled and a backup is taken, you can only restore to the exact backup time, not to any point after.

1. Verify Existing Archive Mode

[postgres@lxicbpgdsgv01 ~]$ psql
psql (17.6)
Type "help" for help.

postgres=# SHOW archive_mode;
 archive_mode 
--------------
 off <--- it's off
(1 row)

postgres=# SHOW archive_command;
 archive_command 
-----------------
 (disabled) <----
(1 row)
[root@lxicbpgdsgv01 ~]# systemctl status postgresql-17
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-10-07 18:33:05 +08; 2min 26s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 5911 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 5916 (postgres)
      Tasks: 7 (limit: 15700)
     Memory: 21.3M
        CPU: 177ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€5916 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data/
             β”œβ”€5917 "postgres: logger "
             β”œβ”€5918 "postgres: checkpointer "
             β”œβ”€5919 "postgres: background writer "
             β”œβ”€5921 "postgres: walwriter "
             β”œβ”€5922 "postgres: autovacuum launcher "
             └─5923 "postgres: logical replication launcher "

Oct 07 18:33:05 lxicbpgdsgv01.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 07 18:33:05 lxicbpgdsgv01.rajasekhar.com postgres[5916]: 2025-10-07 18:33:05.392 +08 [5916] LOG:  redirecting log output to logging collector process
Oct 07 18:33:05 lxicbpgdsgv01.rajasekhar.com postgres[5916]: 2025-10-07 18:33:05.392 +08 [5916] HINT:  Future log output will appear in directory "log".
Oct 07 18:33:05 lxicbpgdsgv01.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.
[root@lxicbpgdsgv01 ~]#

Currently, there is no active archive process running in the background.

2. Ensure Archive Directory Exists

[root@lxicbpgdsgv01 ~]# mkdir -p /pgArch/pgsql17/arch/
[root@lxicbpgdsgv01 ~]# chown postgres:postgres /pgArch/pgsql17/arch/
[root@lxicbpgdsgv01 ~]# chmod 700 /pgArch/pgsql17/arch/

3. Edit postgresql.conf

[postgres@lxicbpgdsgv01 ~]$ vi /pgData/pgsql17/data/postgresql.conf

Update or add the following lines:

archive_mode = on
archive_command = 'cp %p /pgArch/pgsql17/arch/%f'

Explanation:

  • %p = Full path of WAL file
  • %f = WAL file name
  • cp %p /pgArch/pgsql17/arch/%f = Command to copy the WAL file to archive directory

4. Restart PostgreSQL

[root@lxicbpgdsgv01 ~]# systemctl status postgresql-17
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-10-07 23:48:29 +08; 18s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 7868 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 7873 (postgres)
      Tasks: 8 (limit: 15700)
     Memory: 19.0M
        CPU: 96ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€7873 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data/
             β”œβ”€7874 "postgres: logger "
             β”œβ”€7875 "postgres: checkpointer "
             β”œβ”€7876 "postgres: background writer "
             β”œβ”€7878 "postgres: walwriter "
             β”œβ”€7879 "postgres: autovacuum launcher "
             β”œβ”€7880 "postgres: archiver "  <------
             └─7881 "postgres: logical replication launcher "

Oct 07 23:48:29 lxicbpgdsgv01.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 07 23:48:29 lxicbpgdsgv01.rajasekhar.com postgres[7873]: 2025-10-07 23:48:29.503 +08 [7873] LOG:  redirecting log output to logging collector process
Oct 07 23:48:29 lxicbpgdsgv01.rajasekhar.com postgres[7873]: 2025-10-07 23:48:29.503 +08 [7873] HINT:  Future log output will appear in directory "log".
Oct 07 23:48:29 lxicbpgdsgv01.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.
[root@lxicbpgdsgv01 ~]#

Make sure the archiver process is running.

5. Verify the Configuration

[postgres@lxicbpgdsgv01 ~]$ psql -c "SHOW archive_mode;"
 archive_mode 
--------------
 on <-----------
(1 row)

[postgres@lxicbpgdsgv01 ~]$ psql -c "SHOW archive_command;"
        archive_command         
-------------------------------
 cp %p /pgArch/pgsql17/arch/%f  <-----------------
(1 row)

6. Test Archiving Works

[postgres@lxicbpgdsgv01 ~]$ psql -c "SELECT pg_switch_wal();"

Check archive folder for new WAL files:

[postgres@lxicbpgdsgv01 ~]$ ls -lrth /pgArch/pgsql17/arch/
total 16M
-rw-------. 1 postgres postgres 16M Oct  7 23:50 000000010000000000000001

[postgres@lxicbpgdsgv01 ~]$ psql -c "SELECT pg_switch_wal();"
[postgres@lxicbpgdsgv01 ~]$ ls -lrth /pgArch/pgsql17/arch/
total 32M
-rw-------. 1 postgres postgres 16M Oct  7 23:50 000000010000000000000001
-rw-------. 1 postgres postgres 16M Oct  7 23:51 000000010000000000000002

Β Archiving is working successfully.

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/

Change Data Directory

PostgreSQL 17 – Change Data Directory


0. Overview
1. Stop PostgreSQL Service
2. Create the New Directory
3. Copy Existing Data to New Location
4. Move existing data directory
5. Update PostgreSQL Configuration to Use New Data Directory
6. Reload systemd and start PostgreSQL
7. Edit postgres .bash_profile
8. Verify New Data Directory is in Use
9. Remove Old Data Directory (Optional – A week after)


0. Overview

To change the PostgreSQL 17 data directory from its default location

From: /var/lib/pgsql/17/data To: /pgData/pgsql17/data

 

1. Stop PostgreSQL Service

[postgres@lxicbpgdsgv01 ~]$ psql -c "SHOW data_directory;"
     data_directory
------------------------
 /var/lib/pgsql/17/data <---- existing data directory
(1 row)

[postgres@lxicbpgdsgv01 ~]$

[root@lxicbpgdsgv01 ~]# systemctl stop postgresql-17
[root@lxicbpgdsgv01 ~]# 
[root@lxicbpgdsgv01 ~]# ps -ef | grep postgres
root        5759    4079  0 18:09 pts/1    00:00:00 grep --color=auto postgres
[root@lxicbpgdsgv01 ~]#

2. Create the New Directory

[root@lxicbpgdsgv01 ~]# mkdir -p /pgData/pgsql17/data
[root@lxicbpgdsgv01 ~]# chown postgres:postgres /pgData/pgsql17/data
[root@lxicbpgdsgv01 ~]# chmod 700 /pgData/pgsql17/data
[root@lxicbpgdsgv01 ~]#

3. Copy Existing Data to New Location

[postgres@lxicbpgdsgv01 ~]$ nohup rsync -av --progress /var/lib/pgsql/17/data/ /pgData/pgsql17/data/ > rsync_pgdata.log 2>&1 &
[1] 5863
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ tail -f rsync_pgdata.log
pg_wal/000000010000000000000002
     16,777,216 100%   17.68MB/s    0:00:00 (xfr#1621, to-chk=3/1652)
pg_wal/archive_status/
pg_wal/summaries/
pg_xact/
pg_xact/0000
          8,192 100%    8.84kB/s    0:00:00 (xfr#1622, to-chk=0/1652)

sent 73,827,441 bytes  received 31,005 bytes  49,238,964.00 bytes/sec
total size is 73,717,583  speedup is 1.00
^C[1]+  Done                    nohup rsync -av --progress /var/lib/pgsql/17/data/ /pgData/pgsql17/data/ > rsync_pgdata.log 2>&1

[postgres@lxicbpgdsgv01 ~]$

4. Move existing data directory

[postgres@lxicbpgdsgv01 ~]$ mv /var/lib/pgsql/17/data /var/lib/pgsql/17/data_bkp_10072025
[postgres@lxicbpgdsgv01 ~]$

5. Update PostgreSQL Configuration to Use New Data Directory

[postgres@lxicbpgdsgv01 ~]$ cat /usr/lib/systemd/system/postgresql-17.service | grep -i "Environment=PGDATA"
Environment=PGDATA=/var/lib/pgsql/17/data/  <-----
[postgres@lxicbpgdsgv01 ~]$

[root@lxicbpgdsgv01 ~]# ls -ltr /usr/lib/systemd/system/postgresql-17.service
-rw-r--r--. 1 root root 1788 Aug 13 17:39 /usr/lib/systemd/system/postgresql-17.service
[root@lxicbpgdsgv01 ~]#

[root@lxicbpgdsgv01 ~]# sed -i 's|^Environment=PGDATA=.*|Environment=PGDATA=/pgData/pgsql17/data/|' /usr/lib/systemd/system/postgresql-17.service
[root@lxicbpgdsgv01 ~]#
[root@lxicbpgdsgv01 ~]# cat /usr/lib/systemd/system/postgresql-17.service | grep -i "Environment=PGDATA"
Environment=PGDATA=/pgData/pgsql17/data/ <------
[root@lxicbpgdsgv01 ~]#

6. Reload systemd and start PostgreSQL

[root@lxicbpgdsgv01 ~]# systemctl daemon-reload
[root@lxicbpgdsgv01 ~]#

[root@lxicbpgdsgv01 ~]# systemctl start postgresql-17
[root@lxicbpgdsgv01 ~]#

[root@lxicbpgdsgv01 ~]# systemctl cat postgresql-17 | grep -i Environment=PGDATA
Environment=PGDATA=/pgData/pgsql17/data/ <-----
[root@lxicbpgdsgv01 ~]#

[root@lxicbpgdsgv01 ~]# systemctl status postgresql-17
● postgresql-17.service - PostgreSQL 17 database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql-17.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-10-07 18:33:05 +08; 2min 26s ago
       Docs: https://www.postgresql.org/docs/17/static/
    Process: 5911 ExecStartPre=/usr/pgsql-17/bin/postgresql-17-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
   Main PID: 5916 (postgres)
      Tasks: 7 (limit: 15700)
     Memory: 21.3M
        CPU: 177ms
     CGroup: /system.slice/postgresql-17.service
             β”œβ”€5916 /usr/pgsql-17/bin/postgres -D /pgData/pgsql17/data/
             β”œβ”€5917 "postgres: logger "
             β”œβ”€5918 "postgres: checkpointer "
             β”œβ”€5919 "postgres: background writer "
             β”œβ”€5921 "postgres: walwriter "
             β”œβ”€5922 "postgres: autovacuum launcher "
             └─5923 "postgres: logical replication launcher "

Oct 07 18:33:05 lxicbpgdsgv01.rajasekhar.com systemd[1]: Starting PostgreSQL 17 database server...
Oct 07 18:33:05 lxicbpgdsgv01.rajasekhar.com postgres[5916]: 2025-10-07 18:33:05.392 +08 [5916] LOG:  redirecting log output to logging collector process
Oct 07 18:33:05 lxicbpgdsgv01.rajasekhar.com postgres[5916]: 2025-10-07 18:33:05.392 +08 [5916] HINT:  Future log output will appear in directory "log".
Oct 07 18:33:05 lxicbpgdsgv01.rajasekhar.com systemd[1]: Started PostgreSQL 17 database server.

7. Edit postgres .bash_profile

[postgres@lxicbpgdsgv01 ~]$ cat .bash_profile | grep -i PGDATA=
PGDATA=/var/lib/pgsql/17/data
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ sed -i 's|^PGDATA=.*|PGDATA=/pgData/pgsql17/data|' ~/.bash_profile
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ cat .bash_profile | grep -i PGDATA=
PGDATA=/pgData/pgsql17/data <-----
[postgres@lxicbpgdsgv01 ~]$ . .bash_profile <-- reload the profile
[postgres@lxicbpgdsgv01 ~]$

8. Verify New Data Directory is in Use

[postgres@lxicbpgdsgv01 ~]$ psql -c "SHOW data_directory;"
    data_directory
----------------------
 /pgData/pgsql17/data  <---- new data directory
(1 row)

[postgres@lxicbpgdsgv01 ~]$

9. Remove Old Data Directory (Optional – A week after)

[postgres@lxicbpgdsgv01 ~]$ ls -ld /var/lib/pgsql/17/data_bkp_10072025
drwx------. 20 postgres postgres 4096 Oct  7 18:20 /var/lib/pgsql/17/data_bkp_10072025
[postgres@lxicbpgdsgv01 ~]$ rm -rf /var/lib/pgsql/17/data_bkp_10072025
[postgres@lxicbpgdsgv01 ~]$

 

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/

PostgreSQL Backup and Restore Using pg_dumpall

PostgreSQL Backup and Restore Using pg_dumpall and psql

Table of Contents


0. Introduction

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:

8. Restore on Same Host

9. Restore to Another Host (Different Tablespace Paths)


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 ~]$

 

0. Introduction

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


1. Backup ALL databases

[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


8. Restore on same host


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=#


B. Restore Full Backup

[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


C. Verification

[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 ~]$


F. Restore on Target Host

[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


G. Final Verification

[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/

pg_dump & pg_restore

PostgreSQL pg_dump and pg_restore Guide

Table of Contents
___________________________________________________________________________________________________

Backup:

0. pg_dump / pg_restore –help
1. Backup Output Formats
2. Full Database Backup

3. Schema Level Backup
4. Table Level Backup
5. Object Level Backup (PostgreSQL v17 Feature)

Restore:

6. Pre-requisites for Restore
7. Full Database Restore
8. Schema Level Restore

9. Table Level Restore

___________________________________________________________________________________________________

0. pg_dump/pg_restore –help

Click to expand pg_dump –help
[postgres@pg17 ~]$ pg_dump --help
pg_dump dumps a database as a text file or to other formats.

Usage:
  pg_dump [OPTION]... [DBNAME]

General options:
  -f, --file=FILENAME          output file or directory name
  -F, --format=c|d|t|p         output file format (custom, directory, tar,
                               plain text (default))
  -j, --jobs=NUM               use this many parallel jobs to dump
  -v, --verbose                verbose mode
  -V, --version                output version information, then exit
  -Z, --compress=0-9           compression level for compressed formats
  --lock-wait-timeout=TIMEOUT  fail after waiting TIMEOUT for a table lock
  --no-sync                    do not wait for changes to be written safely to disk
  -?, --help                   show this help, then exit

Options controlling the output content:
  -a, --data-only              dump only the data, not the schema
  -b, --blobs                  include large objects in dump
  -B, --no-blobs               exclude large objects in dump
  -c, --clean                  clean (drop) database objects before recreating
  -C, --create                 include commands to create database in dump
  -e, --extension=PATTERN      dump the specified extension(s) only
  -E, --encoding=ENCODING      dump the data in encoding ENCODING
  -n, --schema=PATTERN         dump the specified schema(s) only
  -N, --exclude-schema=PATTERN do NOT dump the specified schema(s)
  -O, --no-owner               skip restoration of object ownership in
                               plain-text format
  -s, --schema-only            dump only the schema, no data
  -S, --superuser=NAME         superuser user name to use in plain-text format
  -t, --table=PATTERN          dump the specified table(s) only
  -T, --exclude-table=PATTERN  do NOT dump the specified table(s)
  -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
  --enable-row-security        enable row security (dump only content user has
                               access to)
  --exclude-table-data=PATTERN do NOT dump data for the specified table(s)
  --extra-float-digits=NUM     override default setting for extra_float_digits
  --if-exists                  use IF EXISTS when dropping objects
  --include-foreign-data=PATTERN
                               include data of foreign tables on foreign
                               servers matching PATTERN
  --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-security-labels         do not dump security label assignments
  --no-subscriptions           do not dump subscriptions
  --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
  --rows-per-insert=NROWS      number of rows per INSERT; implies --inserts
  --section=SECTION            dump named section (pre-data, data, or post-data)
  --serializable-deferrable    wait until the dump can run without anomalies
  --snapshot=SNAPSHOT          use given snapshot for the dump
  --strict-names               require table and/or schema include patterns to
                               match at least one entity each
  --use-set-session-authorization
                               use SET SESSION AUTHORIZATION commands instead of
                               ALTER OWNER commands to set ownership

Connection options:
  -d, --dbname=DBNAME      database to dump
  -h, --host=HOSTNAME      database server host or socket directory
  -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 no database name is supplied, then the PGDATABASE environment
variable value is used.

Report bugs to <pgsql-bugs@lists.postgresql.org>.
PostgreSQL home page: <https://www.postgresql.org/>
[postgres@pg17 ~]$
Click to expand pg_restore –help
[postgres@pg17 ~]$ pg_restore --help
pg_restore restores a PostgreSQL database from an archive created by pg_dump.

Usage:
  pg_restore [OPTION]... [FILE]

General options:
  -d, --dbname=NAME        connect to database name
  -f, --file=FILENAME      output file name (- for stdout)
  -F, --format=c|d|t       backup file format (should be automatic)
  -l, --list               print summarized TOC of the archive
  -v, --verbose            verbose mode
  -V, --version            output version information, then exit
  -?, --help               show this help, then exit

Options controlling the restore:
  -a, --data-only              restore only the data, no schema
  -c, --clean                  clean (drop) database objects before recreating
  -C, --create                 create the target database
  -e, --exit-on-error          exit on error, default is to continue
  -I, --index=NAME             restore named index
  -j, --jobs=NUM               use this many parallel jobs to restore
  -L, --use-list=FILENAME      use table of contents from this file for
                               selecting/ordering output
  -n, --schema=NAME            restore only objects in this schema
  -N, --exclude-schema=NAME    do not restore objects in this schema
  -O, --no-owner               skip restoration of object ownership
  -P, --function=NAME(args)    restore named function
  -s, --schema-only            restore only the schema, no data
  -S, --superuser=NAME         superuser user name to use for disabling triggers
  -t, --table=NAME             restore named relation (table, view, etc.)
  -T, --trigger=NAME           restore named trigger
  -x, --no-privileges          skip restoration of access privileges (grant/revoke)
  -1, --single-transaction     restore as a single transaction
  --disable-triggers           disable triggers during data-only restore
  --enable-row-security        enable row security
  --if-exists                  use IF EXISTS when dropping objects
  --no-comments                do not restore comments
  --no-data-for-failed-tables  do not restore data of tables that could not be
                               created
  --no-publications            do not restore publications
  --no-security-labels         do not restore security labels
  --no-subscriptions           do not restore subscriptions
  --no-table-access-method     do not restore table access methods
  --no-tablespaces             do not restore tablespace assignments
  --section=SECTION            restore named section (pre-data, data, or post-data)
  --strict-names               require table and/or schema include patterns to
                               match at least one entity each
  --use-set-session-authorization
                               use SET SESSION AUTHORIZATION commands instead of
                               ALTER OWNER commands to set ownership

Connection options:
  -h, --host=HOSTNAME      database server host or socket directory
  -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 restore

The options -I, -n, -N, -P, -t, -T, and --section can be combined and specified
multiple times to select multiple objects.

If no input file name is supplied, then standard input is used.

Report bugs to <pgsql-bugs@lists.postgresql.org>.
PostgreSQL home page: <https://www.postgresql.org/>
[postgres@pg17 ~]$

1. Backup Output Formats

A. Plain Text Format
# Using -Fp explicitly:
pg_dump -U postgres -d your_db_name -Fp -f /path/to/your_db.sql

# Shell redirect
pg_dump -U postgres -d your_db_name > /path/to/your_db.sql

B. Tar Format
pg_dump -U postgres -d your_db_name -Ft -f /path/to/your_db.tar

C. Directory Format and Parallel Backup
-- Parallel backup is only supported with -Fd
-- pg_dump will create the directory if it doesn't exist.

# Without parallelism
pg_dump -U postgres -d your_db_name -Fd -f /path/to/backup_dir/

# With parallelism
pg_dump -U postgres -d your_db_name -Fd -j8 -f /path/to/backup_dir/

D. Custom Format (Compressed binary format by default)
pg_dump -U postgres -d your_db_name -Fc -f /path/to/your_db.dump


2. Full Database Backup


A. Plain Text Format

[postgres@pg17 ~]$ nohup pg_dump -U postgres -d blpua -v > /pgBackup/pgsql15/backup/blpua/database_blpua_full.sql 2> /pgBackup/pgsql15/backup/blpua/log/database_blpua_full.log &

-- OR --

[postgres@pg17 ~]$ nohup pg_dump -U postgres -d blpua -v -Fp -f /pgBackup/pgsql15/backup/blpua/database_blpua_full1.sql > /pgBackup/pgsql15/backup/blpua/log/database_blpua_full1.log 2>&1 &

-- OR -- 

[postgres@pg17 ~]$ pg_dump -U postgres -d blpua | split -b 1G - /pgBackup/pgsql15/backup/blpua/database_blpua_split.dmp
[postgres@pg17 ~]$
[postgres@pg17 ~]$ ls -lrth /pgBackup/pgsql15/backup/blpua/database_blpua_s*
-rw-r--r--. 1 postgres postgres 1.0G Sep 30 11:03 /pgBackup/pgsql15/backup/blpua/database_blpua_split.dmpaa
-rw-r--r--. 1 postgres postgres 650M Sep 30 11:03 /pgBackup/pgsql15/backup/blpua/database_blpua_split.dmpab
[postgres@pg17 ~]$

-- OR --

[postgres@pg17 ~]$ nohup sh -c "pg_dump -U postgres -d blpua -v | gzip > /pgBackup/pgsql15/backup/blpua/database_blpua.gz" > /pgBackup/pgsql15/backup/blpua/log/database_blpua.log 2>&1 &

-- OR --

[postgres@pg17 ~]$ nohup pg_dump -U postgres -d blpua -v > /pgBackup/pgsql15/backup/blpua/database_blpua.sql 2> /pgBackup/pgsql15/backup/blpua/log/database_blpua.log & gzip /pgBackup/pgsql15/backup/blpua/database_blpua.sql


B. Tar Format

[postgres@pg17 ~]$ nohup pg_dump -U postgres -d blpua -v -Ft -f /pgBackup/pgsql15/backup/blpua/database_blpua.tar > /pgBackup/pgsql15/backup/blpua/log/blpua_tar_dump.log 2>&1 &


C. Directory Format

[postgres@pg17 ~]$ nohup pg_dump -U postgres -d blpua -v -Fd -j4 -f /pgBackup/pgsql15/backup/blpua_dir > /pgBackup/pgsql15/backup/blpua/log/blpua_dump.log 2>&1 &


D. Custome Format

[postgres@pg17 ~]$ nohup pg_dump -U postgres -d blpua -Fc -v -f /pgBackup/pgsql15/backup/blpua/database_blpua_$(date +%Y_%m_%d).dmp > /pgBackup/pgsql15/backup/blpua/log/database_blpua_$(date +%Y_%m_%d).log 2>&1 &
[postgres@pg17 ~]$ 
[postgres@pg17 ~]$ ls -lrth /pgBackup/pgsql15/backup/blpua/database_blpua*.dmp
-rw-r--r--. 1 postgres postgres 402M Sep 29 04:58 /pgBackup/pgsql15/backup/blpua/database_blpua_2025_09_29.dmp

[postgres@pg17 ~]$ ls -lrth /pgBackup/pgsql15/backup/blpua/log/database_blpua*.log
-rw-r--r--. 1 postgres postgres 2.5K Sep 29 04:58 /pgBackup/pgsql15/backup/blpua/log/database_blpua_2025_09_29.log
[postgres@pg17 ~]$


3. Schema Level Backup

[postgres@pg17 ~]$ nohup pg_dump -U postgres -d blpua -n blp -Fc -v -f /pgBackup/pgsql15/backup/blpua/schema_blp_blpua_$(date +%Y_%m_%d).dmp > /pgBackup/pgsql15/backup/blpua/log/schema_blp_blpua_$(date +%Y_%m_%d).log 2>&1 &
[1] 5472
[postgres@pg17 ~]$

[postgres@pg17 ~]$ jobs -l
[1]+  5472 Running                 nohup pg_dump -U postgres -d blpua -n blp -Fc -v -f /pgBackup/pgsql15/backup/blpua/schema_blp_blpua_$(date +%Y_%m_%d).dmp > /pgBackup/pgsql15/backup/blpua/log/schema_blp_blpua_$(date +%Y_%m_%d).log 2>&1 &
[postgres@pg17 ~]$

[postgres@pg17 ~]$ jobs -l
[1]+  5472 Done                    nohup pg_dump -U postgres -d blpua -n blp -Fc -v -f /pgBackup/pgsql15/backup/blpua/schema_blp_blpua_$(date +%Y_%m_%d).dmp > /pgBackup/pgsql15/backup/blpua/log/schema_blp_blpua_$(date +%Y_%m_%d).log 2>&1
[postgres@pg17 ~]$


[postgres@pg17 ~]$ ls -lrth /pgBackup/pgsql15/backup/blpua/schema_blp_blpua*
-rw-r--r--. 1 postgres postgres 402M Sep 30 02:09 /pgBackup/pgsql15/backup/blpua/schema_blp_blpua_2025_09_30.dmp
[postgres@pg17 ~]$ ls -lrth /pgBackup/pgsql15/backup/blpua/log/schema_blp_blpua*
-rw-r--r--. 1 postgres postgres 2.5K Sep 30 02:09 /pgBackup/pgsql15/backup/blpua/log/schema_blp_blpua_2025_09_30.log
[postgres@pg17 ~]$


4. Table Level Backup

[postgres@pg17 ~]$ nohup pg_dump -U postgres -d blpua -t blp.employees -Fc -v -f /pgBackup/pgsql15/backup/blpua/table_blp_employees_$(date +%Y_%m_%d).dmp > /pgBackup/pgsql15/backup/blpua/log/table_blp_employees_$(date +%Y_%m_%d).log 2>&1 &
[1] 5652
[postgres@pg17 ~]$ 

[postgres@pg17 ~]$ ls -lrth /pgBackup/pgsql15/backup/blpua/table_blp_employees_*
-rw-r--r--. 1 postgres postgres 62M Sep 30 02:22 /pgBackup/pgsql15/backup/blpua/table_blp_employees_2025_09_30.dmp
[postgres@pg17 ~]$ ls -lrth /pgBackup/pgsql15/backup/blpua/log/table_blp_employees_*
-rw-r--r--. 1 postgres postgres 2.0K Sep 30 02:22 /pgBackup/pgsql15/backup/blpua/log/table_blp_employees_2025_09_30.log
[postgres@pg17 ~]$


5. Object Level Backup (PostgreSQL v17 Feature)

++ filter is only for pg_dump, not pg_restore

[postgres@lxicbpgdsgv01 ~]$ cat include_tables.par
include table demo.table_1
include table demo.table_2
include table demo.table_3
[postgres@lxicbpgdsgv01 ~]$


[postgres@lxicbpgdsgv01 ~]$ pg_dump -d testdb_source --filter=include_tables.par > include_tables.sql

[postgres@lxicbpgdsgv01 ~]$ ls -lrth include_tables.sql
-rw-r--r--. 1 postgres postgres 4.5K Sep 30 22:19 include_tables.sql
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ cat include_tables.sql | grep -i "CREATE TABLE"
CREATE TABLE demo.table_1 (
CREATE TABLE demo.table_2 (
CREATE TABLE demo.table_3 (
[postgres@lxicbpgdsgv01 ~]$


[postgres@lxicbpgdsgv01 ~]$ cat exclude_tables.par
exclude table demo.table_1
exclude table demo.table_2
exclude table demo.table_3
[postgres@lxicbpgdsgv01 ~]$

[postgres@lxicbpgdsgv01 ~]$ pg_dump -d testdb_source --filter=exclude_tables.par > exclude_tables.sql
[postgres@lxicbpgdsgv01 ~]$ ls -ltr exclude_tables.sql
-rw-r--r--. 1 postgres postgres 10931 Sep 30 22:23 exclude_tables.sql
[postgres@lxicbpgdsgv01 ~]$
[postgres@lxicbpgdsgv01 ~]$ cat exclude_tables.sql | grep -i "CREATE TABLE"
CREATE TABLE demo.table_10 (
CREATE TABLE demo.table_4 (
CREATE TABLE demo.table_5 (
CREATE TABLE demo.table_6 (
CREATE TABLE demo.table_7 (
CREATE TABLE demo.table_8 (
CREATE TABLE demo.table_9 (
[postgres@lxicbpgdsgv01 ~]$


6. Pre-requisites for restore

postgres=# CREATE TABLESPACE TEST_TB LOCATION '/pgTb/pgsql15/test';
CREATE TABLESPACE
postgres=# CREATE TABLESPACE TEST_IX LOCATION '/pgIx/pgsql15/test';
CREATE TABLESPACE
postgres=#
postgres=# CREATE DATABASE TEST TABLESPACE TEST_TB;
CREATE DATABASE
postgres=#

[postgres@pg17 blpua]$ scp *.dmp postgres@192.168.2.32:/pgBackup/pgsql15/backup/test
postgres@192.168.2.32's password:
database_blpua_2025_09_29.dmp                           100%  402MB  39.9MB/s   00:10
schema_blp_blpua_2025_09_30.dmp                         100%  402MB  43.8MB/s   00:09
table_blp_employees_2025_09_30.dmp                      100%   61MB  47.0MB/s   00:01
[postgres@pg17 blpua]$


7. Full Database Restore

++ The source database uses two custom tablespaces: blpua_tbs01 and blpua_ixtbs01.
++ On the target system, I have two different tablespaces: test_tb and test_ix.
++ Unlike Oracle, PostgreSQL does not provide a direct equivalent of REMAP_TABLESPACE.
++ Therefore, to simplify the restore and ensure all objects are placed into the default tablespace (test_tb).
++ Using --no-owner --no-tablespaces in pg_restore β€” even if not specified, data still gets written to the default database tablespace. These options just help avoid errors in the log.
++ This ensures that all objects are restored to the default tablespace of the target database, regardless of their original tablespace assignments.
++ Later, we can move all indexes to the desired target tablespace using the ALTER INDEX ... SET TABLESPACE command.
postgres=# \c test
You are now connected to database "test" as user "postgres".
test=# ALTER INDEX blp.idx_employee_name SET TABLESPACE test_ix;  <--  This command physically relocates the index to the test_ix tablespace.
ALTER INDEX
test=#


[postgres@lxtrdpgdsgv01 ~]$ nohup pg_restore -U postgres -d test --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/database_blpua_2025_09_29.dmp > /pgBackup/pgsql15/backup/test/log/restore_blpua_test_$(date +%Y_%m_%d).log 2>&1 &
[1] 5300
[postgres@lxtrdpgdsgv01 ~]$

[postgres@lxtrdpgdsgv01 ~]$ cat /pgBackup/pgsql15/backup/test/log/restore_blpua_test_2025_09_30.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: creating SCHEMA "blp"
pg_restore: creating TYPE "blp.address"
pg_restore: creating TYPE "blp.employment_status"
pg_restore: creating DOMAIN "blp.positive_integer"
pg_restore: creating FUNCTION "blp.get_salary(integer)"
pg_restore: creating FUNCTION "blp.log_update()"
pg_restore: creating PROCEDURE "blp.raise_salary(integer, numeric)"
pg_restore: creating SEQUENCE "blp.emp_id_seq"
pg_restore: creating TABLE "blp.employees"
pg_restore: creating MATERIALIZED VIEW "blp.emp_summary"
pg_restore: creating SEQUENCE "blp.employees_id_seq"
pg_restore: creating SEQUENCE OWNED BY "blp.employees_id_seq"
pg_restore: creating VIEW "blp.high_paid_employees"
pg_restore: creating TABLE "blp.metrics"
pg_restore: creating TABLE "blp.metrics_high"
pg_restore: creating SEQUENCE "blp.metrics_id_seq"
pg_restore: creating TABLE "blp.metrics_low"
pg_restore: creating TABLE "blp.metrics_mid"
pg_restore: creating TABLE "blp.metrics_rest"
pg_restore: creating TABLE "blp.sales"
pg_restore: creating TABLE "blp.sales_2021"
pg_restore: creating TABLE "blp.sales_2022"
pg_restore: creating TABLE "blp.sales_2023"
pg_restore: creating TABLE "blp.sales_2024"
pg_restore: creating SEQUENCE "blp.sales_id_seq"
pg_restore: creating TABLE "blp.test_data"
pg_restore: creating SEQUENCE "blp.test_data_id_seq"
pg_restore: creating SEQUENCE OWNED BY "blp.test_data_id_seq"
pg_restore: creating TABLE ATTACH "blp.metrics_high"
pg_restore: creating TABLE ATTACH "blp.metrics_low"
pg_restore: creating TABLE ATTACH "blp.metrics_mid"
pg_restore: creating TABLE ATTACH "blp.metrics_rest"
pg_restore: creating TABLE ATTACH "blp.sales_2021"
pg_restore: creating TABLE ATTACH "blp.sales_2022"
pg_restore: creating TABLE ATTACH "blp.sales_2023"
pg_restore: creating TABLE ATTACH "blp.sales_2024"
pg_restore: creating DEFAULT "blp.employees id"
pg_restore: creating DEFAULT "blp.test_data id"
pg_restore: processing data for table "blp.employees"
pg_restore: processing data for table "blp.metrics_high"
pg_restore: processing data for table "blp.metrics_low"
pg_restore: processing data for table "blp.metrics_mid"
pg_restore: processing data for table "blp.metrics_rest"
pg_restore: processing data for table "blp.sales_2021"
pg_restore: processing data for table "blp.sales_2022"
pg_restore: processing data for table "blp.sales_2023"
pg_restore: processing data for table "blp.sales_2024"
pg_restore: processing data for table "blp.test_data"
pg_restore: executing SEQUENCE SET emp_id_seq
pg_restore: executing SEQUENCE SET employees_id_seq
pg_restore: executing SEQUENCE SET metrics_id_seq
pg_restore: executing SEQUENCE SET sales_id_seq
pg_restore: executing SEQUENCE SET test_data_id_seq
pg_restore: creating CONSTRAINT "blp.employees employees_pkey"
pg_restore: creating CONSTRAINT "blp.metrics metrics_pkey"
pg_restore: creating CONSTRAINT "blp.metrics_high metrics_high_pkey"
pg_restore: creating CONSTRAINT "blp.metrics_low metrics_low_pkey"
pg_restore: creating CONSTRAINT "blp.metrics_mid metrics_mid_pkey"
pg_restore: creating CONSTRAINT "blp.metrics_rest metrics_rest_pkey"
pg_restore: creating CONSTRAINT "blp.sales sales_pkey"
pg_restore: creating CONSTRAINT "blp.sales_2021 sales_2021_pkey"
pg_restore: creating CONSTRAINT "blp.sales_2022 sales_2022_pkey"
pg_restore: creating CONSTRAINT "blp.sales_2023 sales_2023_pkey"
pg_restore: creating CONSTRAINT "blp.sales_2024 sales_2024_pkey"
pg_restore: creating CONSTRAINT "blp.test_data test_data_pkey"
pg_restore: creating INDEX "blp.idx_employee_name"
pg_restore: creating INDEX ATTACH "blp.metrics_high_pkey"
pg_restore: creating INDEX ATTACH "blp.metrics_low_pkey"
pg_restore: creating INDEX ATTACH "blp.metrics_mid_pkey"
pg_restore: creating INDEX ATTACH "blp.metrics_rest_pkey"
pg_restore: creating INDEX ATTACH "blp.sales_2021_pkey"
pg_restore: creating INDEX ATTACH "blp.sales_2022_pkey"
pg_restore: creating INDEX ATTACH "blp.sales_2023_pkey"
pg_restore: creating INDEX ATTACH "blp.sales_2024_pkey"
pg_restore: creating TRIGGER "blp.employees employee_update_trigger"
pg_restore: creating MATERIALIZED VIEW DATA "blp.emp_summary"
[postgres@lxtrdpgdsgv01 ~]$


8. Schema Level Restore

++ pg_restore does not support schema remapping like Oracle’s REMAP_SCHEMA.
++ I want to restore schema blp --> trd. 
++ Option A: Restore Dump as it is, Then Rename <--- Best for simplicity
++ Option B: Split Dump into Schema + Data, Modify Both <--- This is more complex, but possible if you must use schema remapping.
++ This is schema dump file : /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
++ Using --no-owner --no-tablespaces in pg_restore β€” even if not specified, data still gets written to the default database tablespace. These options just help avoid errors in the log.


A. To Restore schema from own schema’s backup

postgres=# CREATE TABLESPACE ORCL_TB LOCATION '/pgTb/pgsql15/orcl';
CREATE TABLESPACE
postgres=# CREATE TABLESPACE ORCL_IX LOCATION '/pgIx/pgsql15/orcl';
CREATE TABLESPACE
postgres=#
postgres=# CREATE DATABASE ORCL TABLESPACE ORCL_TB;
CREATE DATABASE
postgres=#

-- With NO parallelism


[postgres@lxtrdpgdsgv01 ~]$ nohup pg_restore -U postgres -d orcl --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp > /pgBackup/pgsql15/backup/test/log/restore_blpua_test_$(date +%Y_%m_%d).log 2>&1 &
[1] 7344
[postgres@lxtrdpgdsgv01 ~]$

postgres=# \c orcl
You are now connected to database "orcl" as user "postgres".
orcl=# ALTER SCHEMA blp RENAME TO trd;
ALTER SCHEMA
orcl=# \dn
      List of schemas
  Name  |       Owner
--------+-------------------
 public | pg_database_owner
 trd    | postgres
(2 rows)

orcl=#


[postgres@lxtrdpgdsgv01 ~]$ cat /pgBackup/pgsql15/backup/test/log/restore_blpua_test_2025_09_30.log
nohup: ignoring input
pg_restore: connecting to database for restore
pg_restore: creating SCHEMA "blp"
pg_restore: creating TYPE "blp.address"
pg_restore: creating TYPE "blp.employment_status"
pg_restore: creating DOMAIN "blp.positive_integer"
pg_restore: creating FUNCTION "blp.get_salary(integer)"
pg_restore: creating FUNCTION "blp.log_update()"
pg_restore: creating PROCEDURE "blp.raise_salary(integer, numeric)"
pg_restore: creating SEQUENCE "blp.emp_id_seq"
pg_restore: creating TABLE "blp.employees"
pg_restore: creating MATERIALIZED VIEW "blp.emp_summary"
pg_restore: creating SEQUENCE "blp.employees_id_seq"
pg_restore: creating SEQUENCE OWNED BY "blp.employees_id_seq"
pg_restore: creating VIEW "blp.high_paid_employees"
pg_restore: creating TABLE "blp.metrics"
pg_restore: creating TABLE "blp.metrics_high"
pg_restore: creating SEQUENCE "blp.metrics_id_seq"
pg_restore: creating TABLE "blp.metrics_low"
pg_restore: creating TABLE "blp.metrics_mid"
pg_restore: creating TABLE "blp.metrics_rest"
pg_restore: creating TABLE "blp.sales"
pg_restore: creating TABLE "blp.sales_2021"
pg_restore: creating TABLE "blp.sales_2022"
pg_restore: creating TABLE "blp.sales_2023"
pg_restore: creating TABLE "blp.sales_2024"
pg_restore: creating SEQUENCE "blp.sales_id_seq"
pg_restore: creating TABLE "blp.test_data"
pg_restore: creating SEQUENCE "blp.test_data_id_seq"
pg_restore: creating SEQUENCE OWNED BY "blp.test_data_id_seq"
pg_restore: creating TABLE ATTACH "blp.metrics_high"
pg_restore: creating TABLE ATTACH "blp.metrics_low"
pg_restore: creating TABLE ATTACH "blp.metrics_mid"
pg_restore: creating TABLE ATTACH "blp.metrics_rest"
pg_restore: creating TABLE ATTACH "blp.sales_2021"
pg_restore: creating TABLE ATTACH "blp.sales_2022"
pg_restore: creating TABLE ATTACH "blp.sales_2023"
pg_restore: creating TABLE ATTACH "blp.sales_2024"
pg_restore: creating DEFAULT "blp.employees id"
pg_restore: creating DEFAULT "blp.test_data id"
pg_restore: processing data for table "blp.employees"
pg_restore: processing data for table "blp.metrics_high"
pg_restore: processing data for table "blp.metrics_low"
pg_restore: processing data for table "blp.metrics_mid"
pg_restore: processing data for table "blp.metrics_rest"
pg_restore: processing data for table "blp.sales_2021"
pg_restore: processing data for table "blp.sales_2022"
pg_restore: processing data for table "blp.sales_2023"
pg_restore: processing data for table "blp.sales_2024"
pg_restore: processing data for table "blp.test_data"
pg_restore: executing SEQUENCE SET emp_id_seq
pg_restore: executing SEQUENCE SET employees_id_seq
pg_restore: executing SEQUENCE SET metrics_id_seq
pg_restore: executing SEQUENCE SET sales_id_seq
pg_restore: executing SEQUENCE SET test_data_id_seq
pg_restore: creating CONSTRAINT "blp.employees employees_pkey"
pg_restore: creating CONSTRAINT "blp.metrics metrics_pkey"
pg_restore: creating CONSTRAINT "blp.metrics_high metrics_high_pkey"
pg_restore: creating CONSTRAINT "blp.metrics_low metrics_low_pkey"
pg_restore: creating CONSTRAINT "blp.metrics_mid metrics_mid_pkey"
pg_restore: creating CONSTRAINT "blp.metrics_rest metrics_rest_pkey"
pg_restore: creating CONSTRAINT "blp.sales sales_pkey"
pg_restore: creating CONSTRAINT "blp.sales_2021 sales_2021_pkey"
pg_restore: creating CONSTRAINT "blp.sales_2022 sales_2022_pkey"
pg_restore: creating CONSTRAINT "blp.sales_2023 sales_2023_pkey"
pg_restore: creating CONSTRAINT "blp.sales_2024 sales_2024_pkey"
pg_restore: creating CONSTRAINT "blp.test_data test_data_pkey"
pg_restore: creating INDEX "blp.idx_employee_name"
pg_restore: creating INDEX ATTACH "blp.metrics_high_pkey"
pg_restore: creating INDEX ATTACH "blp.metrics_low_pkey"
pg_restore: creating INDEX ATTACH "blp.metrics_mid_pkey"
pg_restore: creating INDEX ATTACH "blp.metrics_rest_pkey"
pg_restore: creating INDEX ATTACH "blp.sales_2021_pkey"
pg_restore: creating INDEX ATTACH "blp.sales_2022_pkey"
pg_restore: creating INDEX ATTACH "blp.sales_2023_pkey"
pg_restore: creating INDEX ATTACH "blp.sales_2024_pkey"
pg_restore: creating TRIGGER "blp.employees employee_update_trigger"
pg_restore: creating MATERIALIZED VIEW DATA "blp.emp_summary"
[postgres@lxtrdpgdsgv01 ~]$


--- OR ---

-- With parallelism 4

nohup pg_restore -U postgres -d orcl -j4 --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp > /pgBackup/pgsql15/backup/test/log/restore_blpua_test_$(date +%Y_%m_%d).log1 2>&1 &

[postgres@lxtrdpgdsgv01 ~]$ ps -ef | grep pg_restore
postgres    7089    5102  0 05:49 pts/0    00:00:00 pg_restore -U postgres -d orcl -j4 --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
postgres    7091    7089  2 05:49 pts/0    00:00:00 pg_restore -U postgres -d orcl -j4 --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
postgres    7092    7089  3 05:49 pts/0    00:00:00 pg_restore -U postgres -d orcl -j4 --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
postgres    7093    7089  2 05:49 pts/0    00:00:00 pg_restore -U postgres -d orcl -j4 --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
postgres    7094    7089  2 05:49 pts/0    00:00:00 pg_restore -U postgres -d orcl -j4 --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
postgres    7126    5736  0 05:49 pts/1    00:00:00 grep --color=auto pg_restore
[postgres@lxtrdpgdsgv01 ~]$


B. To Restore only a specific schema from Full Database Backup

Step 1: Create schema 

gebua=# CREATE SCHEMA IF NOT EXISTS blp;

Step 2: Restore Objects and Data

nohup pg_restore -U postgres -d gebua -n blp --no-owner --no-tablespaces -v /pgBackup/pgsql15/backup/test/database_blpua_2025_09_29.dmp > /pgBackup/pgsql15/backup/test/log/restore_blpua_test_$(date +%Y_%m_%d).log_full 2>&1 &


9. Table Level Restore


A. Restore Table from own table’s backup

[postgres@lxtrdpgdsgv01 ~]$ pg_restore -l /pgBackup/pgsql15/backup/test/table_blp_employees_2025_09_30.dmp
;
; Archive created at 2025-09-30 02:22:21 EDT
;     dbname: blpua
;     TOC Entries: 13
;     Compression: -1
;     Dump Version: 1.14-0
;     Format: CUSTOM
;     Integer: 4 bytes
;     Offset: 8 bytes
;     Dumped from database version: 15.13
;     Dumped by pg_dump version: 15.13
;
;
; Selected TOC Entries:
;
229; 1259 92805 TABLE blp employees postgres
228; 1259 92804 SEQUENCE blp employees_id_seq postgres
4338; 0 0 SEQUENCE OWNED BY blp employees_id_seq postgres
4181; 2604 92808 DEFAULT blp employees id postgres
4331; 0 92805 TABLE DATA blp employees postgres
4339; 0 0 SEQUENCE SET blp employees_id_seq postgres
4183; 2606 92812 CONSTRAINT blp employees employees_pkey postgres
4184; 1259 92824 INDEX blp idx_employee_name postgres
4185; 2620 92829 TRIGGER blp employees employee_update_trigger postgres
[postgres@lxtrdpgdsgv01 ~]$


Step 1: Create schema 

postgres=# \c edpua
You are now connected to database "edpua" as user "postgres".
edpua=# CREATE SCHEMA IF NOT EXISTS blp;
CREATE SCHEMA
edpua=#


Step 2: Restore Objects and Data

[postgres@lxtrdpgdsgv01 ~]$ pg_restore -U postgres -d edpua --no-tablespaces -v /pgBackup/pgsql15/backup/test/table_blp_employees_2025_09_30.dmp
pg_restore: connecting to database for restore
pg_restore: creating TABLE "blp.employees"
pg_restore: creating SEQUENCE "blp.employees_id_seq"
pg_restore: creating SEQUENCE OWNED BY "blp.employees_id_seq"
pg_restore: creating DEFAULT "blp.employees id"
pg_restore: processing data for table "blp.employees"
pg_restore: executing SEQUENCE SET employees_id_seq
pg_restore: creating CONSTRAINT "blp.employees employees_pkey"
pg_restore: creating INDEX "blp.idx_employee_name"
pg_restore: creating TRIGGER "blp.employees employee_update_trigger"
pg_restore: while PROCESSING TOC:
pg_restore: from TOC entry 4185; 2620 92829 TRIGGER employees employee_update_trigger postgres
pg_restore: error: could not execute query: ERROR:  function blp.log_update() does not exist
Command was: CREATE TRIGGER employee_update_trigger AFTER UPDATE ON blp.employees FOR EACH ROW EXECUTE FUNCTION blp.log_update();


pg_restore: warning: errors ignored on restore: 1
[postgres@lxtrdpgdsgv01 ~]$

++ PostgreSQL does not have a --ignore-errors flag, The above erros ignorable.


B. Restore Single Table data-only from Schema backup

edpua=# TRUNCATE TABLE blp.employees;
TRUNCATE TABLE
edpua=#

[postgres@lxtrdpgdsgv01 ~]$ pg_restore -U postgres -d edpua --data-only -t employees -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
pg_restore: connecting to database for restore
pg_restore: processing data for table "blp.employees"
[postgres@lxtrdpgdsgv01 ~]$

edpua=# select count(*) from blp.employees;
 5000000  <-----

edpua=#


C. Restore Single Table from Schema backup

Step 1: Create schema 

edpua=# CREATE SCHEMA blp;

Step 2: Restore Objects and Data

[postgres@lxtrdpgdsgv01 ~]$ pg_restore -U postgres -d edpua --clean -t employees -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
pg_restore: connecting to database for restore
pg_restore: dropping TABLE employees
pg_restore: creating TABLE "blp.employees"
pg_restore: processing data for table "blp.employees"
[postgres@lxtrdpgdsgv01 ~]$
[postgres@lxtrdpgdsgv01 ~]$ psql
psql (15.14)
Type "help" for help.

postgres=# \c edpua
You are now connected to database "edpua" as user "postgres".
edpua=# select count(*) from blp.employees;
  count
---------
 5000000 <----
(1 row)

edpua=#


D. Restore Single Table from Schema backup (add both -n and -t)

[postgres@lxtrdpgdsgv01 ~]$ pg_restore -U postgres -d edpua --clean -n blp -t employees -v /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
pg_restore: connecting to database for restore
pg_restore: dropping TABLE employees
pg_restore: creating TABLE "blp.employees"
pg_restore: processing data for table "blp.employees"
[postgres@lxtrdpgdsgv01 ~]$
[postgres@lxtrdpgdsgv01 ~]$ psql
psql (15.14)
Type "help" for help.

postgres=# \c edpua
You are now connected to database "edpua" as user "postgres".
edpua=# select count(*) from blp.employees;
  count
---------
 5000000 <-----
(1 row)

edpua=#


E. Restoring Using a Plain SQL File (COPY-based)

Step 1: Extracted table data from custom-format dump

[postgres@lxtrdpgdsgv01 ~]$ pg_restore -U postgres -n blp -t employees -f /pgBackup/pgsql15/backup/test/blp_employees.sql /pgBackup/pgsql15/backup/test/schema_blp_blpua_2025_09_30.dmp
[postgres@lxtrdpgdsgv01 ~]$
[postgres@lxtrdpgdsgv01 ~]$ ls -lrth /pgBackup/pgsql15/backup/test/blp_employees.sql
-rw-r--r--. 1 postgres postgres 210M Sep 30 09:17 /pgBackup/pgsql15/backup/test/blp_employees.sql
[postgres@lxtrdpgdsgv01 ~]$

[postgres@lxtrdpgdsgv01 ~]$ head -50 /pgBackup/pgsql15/backup/test/blp_employees.sql
--
-- PostgreSQL database dump
--

\restrict TthhVsS8JvVxrplYNApzHUalZpygXUqFg2pIvbSH8GTkbJ6WBNyW0JLnuuvkPdt

-- Dumped from database version 15.13
-- Dumped by pg_dump version 15.13

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: employees; Type: TABLE; Schema: blp; Owner: postgres
--

CREATE TABLE blp.employees (
    id integer NOT NULL,
    name text,
    salary numeric(10,2),
    hired_on date
);


ALTER TABLE blp.employees OWNER TO postgres;

--
-- Data for Name: employees; Type: TABLE DATA; Schema: blp; Owner: postgres
--

COPY blp.employees (id, name, salary, hired_on) FROM stdin;
1       Employee_1      70969.47        2005-06-13
2       Employee_2      94341.15        2006-12-09
3       Employee_3      101657.57       2012-07-05
4       Employee_4      54701.92        2010-01-05
5       Employee_5      104229.43       2001-06-28
6       Employee_6      95842.57        2010-10-06
7       Employee_7      50618.08        2015-06-02
[postgres@lxtrdpgdsgv01 ~]$

Step 2: Restore using psql command

postgres=# \c edpua
You are now connected to database "edpua" as user "postgres".
edpua=#
edpua=# drop table blp.employees;
DROP TABLE
edpua=# exit
[postgres@lxtrdpgdsgv01 ~]$


psql -U postgres -d edpua < /pgBackup/pgsql15/backup/test/blp_employees.sql

[postgres@lxtrdpgdsgv01 ~]$ psql -U postgres -d edpua < /pgBackup/pgsql15/backup/test/blp_employees.sql
SET
SET
SET
SET
SET
 set_config
------------

(1 row)

SET
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
COPY 5000000
[postgres@lxtrdpgdsgv01 ~]$

[postgres@lxtrdpgdsgv01 ~]$ psql
psql (15.14)
Type "help" for help.

postgres=# \c edpua
You are now connected to database "edpua" as user "postgres".
edpua=# SELECT COUNT(*) FROM blp.employees;
  count
---------
 5000000 <-----
(1 row)

edpua=#

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/

PostgreSQL Tablespace

PostgreSQL Tablespace Management

Table of Contents

___________________________________________________________________________________________________

0. Introduction
1. How big can a PostgreSQL tablespace grow?
2. Create a Tablespace
3. Create a Database with default tablespace
4. Create Tables on Data tablspace
5. Crate Index on Index tablespaces
6. Create a Dedicated Tablespace for Temp
7. Assign Temp Tablespace to a Database
8. Check Tablespace OIDs
9. Move Table Between Tablespaces
10. Verify Database Directory (Filesystem)
11. Rename tablespace
12. Drop Tablespace
13. Change ownership for Tablespace
14. Verify Symbolic Links
15. How to find tablespace size
___________________________________________________________________________________________________


0. Introduction

What is a Tablespace?

--> Tablespace is a logical structure in which objects are stored.

--> A tablespace is simply a physical storage location on disk where PostgreSQL stores database objects (tables, indexes, etc.). 

--> By default database objects are stored in the current default tablespace of the database.

List tablespaces:

\db+ or select * from pg_tablespace;

 

Types of Tablespaces: Default Tablespaces and Non-Default Tablespaces
I. Default Tablespaces

These come built-in with PostgreSQL:

pg_global – for shared system data
pg_default – for regular user data (tables, indexes, etc.)
Featurepg_defaultpg_global
PurposeStores regular user dataStores global system data
Used by default?Yes, for tables/indexesNo, only used internally
Can store user tables?YesNo
Location$PGDATA/base/$PGDATA/global/
Droppable?NoNo
II. Non-Default Tablespaces :

--> These are created by users to store data in custom locations.
--> Useful for managing storage better (e.g., putting large tables on faster disks).


1. How big can a PostgreSQL tablespace grow?

There is no fixed maximum size for a tablespace in PostgreSQL itself.
The limit depends on your operating system and filesystem where the tablespace directory is located.

For example:

On modern filesystems like ext4 or XFS, a single file can be several terabytes (TB) or even petabytes (PB).
PostgreSQL breaks large tables into multiple files (each typically up to 1 GB) internally, so extremely large tablespaces are supported.
Your disk/storage capacity is the main practical limit.


2. Create a Tablespace

[root@pg17 ~]# mkdir -p /pgData/pgsql15/edbua_tbs01
[root@pg17 ~]# mkdir -p /pgData/pgsql15/edbua_tbs02
[root@pg17 ~]# mkdir -p /pgData/pgsql15/edbua_ixtbs01
[root@pg17 ~]# mkdir -p /pgData/pgsql15/edbua_temptbs01
[root@pg17 ~]# chown postgres:postgres /pgData/pgsql15/edbua*
[root@pg17 ~]# chmod 700 /pgData/pgsql15/edbua*
[root@pg17 ~]#

[root@pg17 ~]# su - postgres
[postgres@pg17 ~]$ psql
psql (15.13)
Type "help" for help.

postgres=# CREATE TABLESPACE edbua_tbs01 LOCATION '/pgData/pgsql15/edbua_tbs01';
CREATE TABLESPACE
postgres=# CREATE TABLESPACE edbua_tbs02 LOCATION '/pgData/pgsql15/edbua_tbs02';
CREATE TABLESPACE
postgres=# CREATE TABLESPACE edbua_ixtbs01 LOCATION '/pgData/pgsql15/edbua_ixtbs01';
CREATE TABLESPACE
postgres=# 


3. Create a Database with default tablespace

postgres=# CREATE DATABASE edbua TABLESPACE edbua_tbs01;
CREATE DATABASE
postgres=# 
postgres=# SELECT oid, datname, dattablespace, datistemplate, datdba FROM pg_database WHERE datname = 'edbua';
  oid  | datname | dattablespace | datistemplate | datdba
-------+---------+---------------+---------------+--------
 92666 | edbua   |         92662 | f             |     10
(1 row)

postgres=#


4. Create Tables on Data tablspace

postgres=# \c edbua
You are now connected to database "edbua" as user "postgres".
edbua=# CREATE TABLE emp01 (id int, name text) TABLESPACE edbua_tbs01;
CREATE TABLE
edbua=# CREATE TABLE emp02 (id int, name text) TABLESPACE edbua_tbs01;
CREATE TABLE
edbua=# CREATE TABLE emp03 (id int, name text) TABLESPACE edbua_tbs01;
CREATE TABLE
edbua=#


5. Create Index on Index tablespaces

edbua=# CREATE INDEX emp01_ix ON emp01(name) TABLESPACE edbua_ixtbs01;
CREATE INDEX
edbua=# CREATE INDEX emp02_ix ON emp02(name) TABLESPACE edbua_ixtbs01;
CREATE INDEX
edbua=# CREATE INDEX emp03_ix ON emp03(name) TABLESPACE edbua_ixtbs01;
CREATE INDEX
edbua=# SELECT c.oid, c.relname, c.relkind, t.spcname AS tablespace, c.relfilenode
edbua-# FROM pg_class c
edbua-# LEFT JOIN pg_tablespace t ON c.reltablespace = t.oid
edbua-# WHERE c.relname IN ('emp01','emp02','emp03','emp01_ix','emp02_ix','emp03_ix');
  oid  | relname  | relkind |  tablespace   | relfilenode
-------+----------+---------+---------------+-------------
 92685 | emp01    | r       |               |       92685
 92690 | emp02    | r       |               |       92690
 92695 | emp03    | r       |               |       92695
 92700 | emp01_ix | i       | edbua_ixtbs01 |       92700
 92701 | emp02_ix | i       | edbua_ixtbs01 |       92701
 92702 | emp03_ix | i       | edbua_ixtbs01 |       92702
(6 rows)

edbua=#

If a table or index is created in the database’s default tablespace, PostgreSQL does not explicitly record the tablespace in pg_class.reltablespace.

But when it’s created in a non-default tablespace, PostgreSQL records that tablespace OID in pg_class.reltablespace.

If you want to always see the tablespace name (even when it's the default)

edbua=# SELECT
edbua-#     c.oid,
edbua-#     c.relname,
edbua-#     c.relkind,
edbua-#     COALESCE(t1.spcname, t2.spcname) AS tablespace,
edbua-#     c.relfilenode
edbua-# FROM pg_class c
edbua-# LEFT JOIN pg_tablespace t1 ON c.reltablespace = t1.oid
edbua-# LEFT JOIN pg_database d ON d.datname = current_database()
edbua-# LEFT JOIN pg_tablespace t2 ON d.dattablespace = t2.oid
edbua-# WHERE c.relname IN ('emp01','emp02','emp03','emp01_ix','emp02_ix','emp03_ix');
  oid  | relname  | relkind |  tablespace   | relfilenode
-------+----------+---------+---------------+-------------
 92685 | emp01    | r       | edbua_tbs01   |       92685
 92690 | emp02    | r       | edbua_tbs01   |       92690
 92695 | emp03    | r       | edbua_tbs01   |       92695
 92700 | emp01_ix | i       | edbua_ixtbs01 |       92700
 92701 | emp02_ix | i       | edbua_ixtbs01 |       92701
 92702 | emp03_ix | i       | edbua_ixtbs01 |       92702
(6 rows)

edbua=#

pg_tblspc/<tbs_oid>/PG_15_<catalog_version>/<db_oid>/<relfilenode>

edbua=# SELECT relname, pg_relation_filepath(oid) AS filepath
edbua-# FROM pg_class
edbua-# WHERE relname IN ('emp01','emp02','emp03','emp01_ix','emp02_ix','emp03_ix');
 relname  |                  filepath
----------+---------------------------------------------
 emp01    | pg_tblspc/92662/PG_15_202209061/92666/92685
 emp02    | pg_tblspc/92662/PG_15_202209061/92666/92690
 emp03    | pg_tblspc/92662/PG_15_202209061/92666/92695
 emp01_ix | pg_tblspc/92664/PG_15_202209061/92666/92700
 emp02_ix | pg_tblspc/92664/PG_15_202209061/92666/92701
 emp03_ix | pg_tblspc/92664/PG_15_202209061/92666/92702
(6 rows)

edbua=#


6. Create a Dedicated Tablespace for Temp

postgres=# CREATE TABLESPACE edbua_temptbs01 LOCATION '/pgData/pgsql15/edbua_temptbs01';
CREATE TABLESPACE
postgres=#


7. Assign Temp Tablespace to a Database

postgres=# ALTER DATABASE edbua SET temp_tablespaces = edbua_temptbs01;
ALTER DATABASE
postgres=#

postgres=# \c edbua
You are now connected to database "edbua" as user "postgres".
edbua=# 

edbua=# CREATE TEMP TABLE emp_tmp (id int, name text);
CREATE TABLE
edbua=#
edbua=# SELECT c.oid, c.relname, t.spcname, pg_relation_filepath(c.oid)
edbua-# FROM pg_class c
edbua-# LEFT JOIN pg_tablespace t ON c.reltablespace = t.oid
edbua-# WHERE c.relname = 'emp_tmp';
  oid  | relname |     spcname     |              pg_relation_filepath
-------+---------+-----------------+------------------------------------------------
 92705 | emp_tmp | edbua_temptbs01 | pg_tblspc/92665/PG_15_202209061/92666/t4_92705
(1 row)

edbua=#

pg_tblspc/<tbs_oid>/PG_15_<catalog_version>/<db_oid>/<relfilenode>


8. Check Tablespace OIDs

edbua=# SELECT oid, spcname AS tablespace_name, pg_tablespace_location(oid) AS location FROM pg_tablespace ORDER BY oid;
  oid  | tablespace_name |            location
-------+-----------------+---------------------------------
  1663 | pg_default      |
  1664 | pg_global       |
 24581 | dell_ts_data    | /u01/data/dell_ts_data
 24582 | dell_ts_index   | /u01/data/dell_ts_index
 24594 | dell_tbs        | /pgData/pgsql15/data
 24597 | trd_tb01        | /pgData/pgsql15/data/trd_tb01
 24598 | trd_ix01        | /pgData/pgsql15/data/trd_ix01
 32787 | geb_tb          | /pgData/pgsql15/pgtb/geb_tb
 32788 | geb_ix          | /pgData/pgsql15/pgix/geb_ix
 92662 | edbua_tbs01     | /pgData/pgsql15/edbua_tbs01
 92663 | edbua_tbs02     | /pgData/pgsql15/edbua_tbs02
 92664 | edbua_ixtbs01   | /pgData/pgsql15/edbua_ixtbs01
 92665 | edbua_temptbs01 | /pgData/pgsql15/edbua_temptbs01
(13 rows)

edbua=#


9. Move Table Between Tablespaces

edbua=# ALTER TABLE emp01 SET TABLESPACE edbua_tbs02;
ALTER TABLE
edbua=# ALTER TABLE emp02 SET TABLESPACE edbua_tbs02;
ALTER TABLE
edbua=# ALTER TABLE emp03 SET TABLESPACE edbua_tbs02;
ALTER TABLE
edbua=#

pg_tblspc/<tbs_oid>/PG_15_<catalog_version>/<db_oid>/<relfilenode>

edbua=# select pg_relation_filepath('emp01');
            pg_relation_filepath
---------------------------------------------
 pg_tblspc/92663/PG_15_202209061/92666/92710
(1 row)

edbua=# 

edbua=# SELECT relname, pg_relation_filepath(oid) AS filepath
FROM pg_class
WHERE relname IN ('emp01','emp02','emp03','emp01_ix','emp02_ix','emp03_ix');
 relname  |                  filepath
----------+---------------------------------------------
 emp01    | pg_tblspc/92663/PG_15_202209061/92666/92710
 emp02    | pg_tblspc/92663/PG_15_202209061/92666/92713
 emp03    | pg_tblspc/92663/PG_15_202209061/92666/92716
 emp01_ix | pg_tblspc/92664/PG_15_202209061/92666/92700
 emp02_ix | pg_tblspc/92664/PG_15_202209061/92666/92701
 emp03_ix | pg_tblspc/92664/PG_15_202209061/92666/92702
(6 rows)

edbua=#

Important: Indexes do not move automatically when you move a table.
They remain in their original tablespace (edbua_ixtbs01 in this case).
If you want indexes in edbua_tbs02, you must explicitly run:

edbua=# ALTER INDEX emp01_ix SET TABLESPACE edbua_tbs02;
ALTER INDEX
edbua=# ALTER INDEX emp02_ix SET TABLESPACE edbua_tbs02;
ALTER INDEX
edbua=# ALTER INDEX emp03_ix SET TABLESPACE edbua_tbs02;
ALTER INDEX
edbua=#
edbua=# SELECT c.relname, t.spcname AS tablespace, pg_relation_filepath(c.oid)
edbua-# FROM pg_class c
edbua-# LEFT JOIN pg_tablespace t ON c.reltablespace = t.oid
edbua-# WHERE c.relname IN ('emp01','emp02','emp03','emp01_ix','emp02_ix','emp03_ix');
 relname  | tablespace  |            pg_relation_filepath
----------+-------------+---------------------------------------------
 emp01_ix | edbua_tbs02 | pg_tblspc/92663/PG_15_202209061/92666/92719
 emp02_ix | edbua_tbs02 | pg_tblspc/92663/PG_15_202209061/92666/92720
 emp03_ix | edbua_tbs02 | pg_tblspc/92663/PG_15_202209061/92666/92721
 emp01    | edbua_tbs02 | pg_tblspc/92663/PG_15_202209061/92666/92710
 emp02    | edbua_tbs02 | pg_tblspc/92663/PG_15_202209061/92666/92713
 emp03    | edbua_tbs02 | pg_tblspc/92663/PG_15_202209061/92666/92716
(6 rows)

edbua=#

edbua=# SELECT
edbua-#     c.relname,
edbua-#     COALESCE(t1.spcname, t2.spcname) AS tablespace,
edbua-#     pg_catalog.pg_tablespace_location(COALESCE(c.reltablespace, d.dattablespace)) AS tablespace_path,
edbua-#     current_setting('data_directory') AS data_directory,
edbua-#     CASE
edbua-#         WHEN c.reltablespace = 0 THEN
edbua-#             current_setting('data_directory') || '/base/' || d.oid || '/' || c.relfilenode
edbua-#         ELSE
edbua-#             pg_catalog.pg_tablespace_location(c.reltablespace) || '/PG_' ||
edbua-#             split_part(split_part(version(), ' ', 2), '.', 1) || '_' ||
edbua-#             '202209061/' || d.oid || '/' || c.relfilenode
edbua-#     END AS full_path_guess
edbua-# FROM pg_class c
edbua-# LEFT JOIN pg_tablespace t1 ON c.reltablespace = t1.oid
edbua-# LEFT JOIN pg_database d ON d.datname = current_database()
edbua-# LEFT JOIN pg_tablespace t2 ON d.dattablespace = t2.oid
edbua-# WHERE c.relname IN ('emp01','emp02','emp03','emp01_ix','emp02_ix','emp03_ix');
 relname  | tablespace  |       tablespace_path       |    data_directory    |                     full_path_guess
----------+-------------+-----------------------------+----------------------+---------------------------------------------------------
 emp01_ix | edbua_tbs02 | /pgData/pgsql15/edbua_tbs02 | /pgData/pgsql15/data | /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92719
 emp02_ix | edbua_tbs02 | /pgData/pgsql15/edbua_tbs02 | /pgData/pgsql15/data | /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92720
 emp03_ix | edbua_tbs02 | /pgData/pgsql15/edbua_tbs02 | /pgData/pgsql15/data | /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92721
 emp01    | edbua_tbs02 | /pgData/pgsql15/edbua_tbs02 | /pgData/pgsql15/data | /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92710
 emp02    | edbua_tbs02 | /pgData/pgsql15/edbua_tbs02 | /pgData/pgsql15/data | /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92713
 emp03    | edbua_tbs02 | /pgData/pgsql15/edbua_tbs02 | /pgData/pgsql15/data | /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92716
(6 rows)

edbua=#


10. Verify Database Directory (Filesystem)

edbua=# SELECT oid, datname FROM pg_database WHERE datname = current_database();
  oid  | datname
-------+---------
 92666 | edbua
(1 row)

edbua=#

[root@pg17 ~]# ls -ltr /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/*
-rw-------. 1 postgres postgres    0 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92710
-rw-------. 1 postgres postgres    0 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92711
-rw-------. 1 postgres postgres 8192 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92712
-rw-------. 1 postgres postgres    0 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92713
-rw-------. 1 postgres postgres    0 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92714
-rw-------. 1 postgres postgres 8192 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92715
-rw-------. 1 postgres postgres    0 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92716
-rw-------. 1 postgres postgres    0 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92717
-rw-------. 1 postgres postgres 8192 Sep 23 00:14 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92718
-rw-------. 1 postgres postgres 8192 Sep 23 00:52 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92719
-rw-------. 1 postgres postgres 8192 Sep 23 00:52 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92720
-rw-------. 1 postgres postgres 8192 Sep 23 00:52 /pgData/pgsql15/edbua_tbs02/PG_15_202209061/92666/92721
[root@pg17 ~]#


Issue: Why are there 12 files when I have only 6 objects?

created only: 3 tables: emp01, emp02, emp03 & 3 indexes: emp01_ix, emp02_ix, emp03_ix

But in the tablespace directory, we're seeing 12 files: 3 tables + 3 indexes + 3 TOAST tables + 3 TOAST indexes

edbua=# SELECT
edbua-#     c.relname,
edbua-#     c.relfilenode,
edbua-#     c.relkind,
edbua-#     n.nspname AS schema,
edbua-#     t.spcname AS tablespace
edbua-# FROM
edbua-#     pg_class c
edbua-# JOIN
edbua-#     pg_namespace n ON n.oid = c.relnamespace
edbua-# LEFT JOIN
edbua-#     pg_tablespace t ON c.reltablespace = t.oid
edbua-# WHERE
edbua-#     c.reltablespace = (SELECT oid FROM pg_tablespace WHERE spcname = 'edbua_tbs02')
edbua-# ORDER BY
edbua-#     c.relfilenode;
       relname        | relfilenode | relkind |  schema  | tablespace
----------------------+-------------+---------+----------+-------------
 emp01                |       92710 | r       | public   | edbua_tbs02
 pg_toast_92685       |       92711 | t       | pg_toast | edbua_tbs02
 pg_toast_92685_index |       92712 | i       | pg_toast | edbua_tbs02
 emp02                |       92713 | r       | public   | edbua_tbs02
 pg_toast_92690       |       92714 | t       | pg_toast | edbua_tbs02
 pg_toast_92690_index |       92715 | i       | pg_toast | edbua_tbs02
 emp03                |       92716 | r       | public   | edbua_tbs02
 pg_toast_92695       |       92717 | t       | pg_toast | edbua_tbs02
 pg_toast_92695_index |       92718 | i       | pg_toast | edbua_tbs02
 emp01_ix             |       92719 | i       | public   | edbua_tbs02
 emp02_ix             |       92720 | i       | public   | edbua_tbs02
 emp03_ix             |       92721 | i       | public   | edbua_tbs02
(12 rows)

edbua=#


11. Rename tablespace

edbua=# ALTER TABLESPACE edbua_tbs02 RENAME TO edbua_tbs03;
ALTER TABLESPACE
edbua=#

edbua=# \db+ edbua*
                                                List of tablespaces
      Name       |  Owner   |            Location             | Access privileges | Options |  Size   | Description
-----------------+----------+---------------------------------+-------------------+---------+---------+-------------
 edbua_ixtbs01   | postgres | /pgData/pgsql15/edbua_ixtbs01   |                   |         | 6 bytes |
 edbua_tbs01     | postgres | /pgData/pgsql15/edbua_tbs01     |                   |         | 7789 kB |
 edbua_tbs03     | postgres | /pgData/pgsql15/edbua_tbs02     |                   |         | 48 kB   |
 edbua_temptbs01 | postgres | /pgData/pgsql15/edbua_temptbs01 |                   |         | 6 bytes |
(4 rows)

edbua=#


12. Drop Tablespace

edbua=# drop tablespace edbua_tbs03;
ERROR:  tablespace "edbua_tbs03" is not empty
edbua=#

edbua=# SELECT
edbua-#   CASE
edbua-#     WHEN c.relkind = 'r' THEN
edbua-#       format('ALTER TABLE %I.%I SET TABLESPACE edbua_tbs01;', n.nspname, c.relname)
edbua-#     WHEN c.relkind = 'i' THEN
edbua-#       format('ALTER INDEX %I.%I SET TABLESPACE edbua_tbs01;', n.nspname, c.relname)
edbua-#     WHEN c.relkind = 'S' THEN
edbua-#       format('ALTER SEQUENCE %I.%I SET TABLESPACE edbua_tbs01;', n.nspname, c.relname)
edbua-#   END AS alter_statement
edbua-# FROM pg_class c
edbua-# JOIN pg_namespace n ON n.oid = c.relnamespace
edbua-# WHERE c.reltablespace = (SELECT oid FROM pg_tablespace WHERE spcname = 'edbua_tbs03')
edbua-#   AND c.relkind IN ('r', 'i', 'S')
edbua-#   AND n.nspname NOT IN ('pg_catalog', 'pg_toast', 'information_schema')
edbua-# ORDER BY n.nspname, c.relname;
                     alter_statement
---------------------------------------------------------
 ALTER TABLE public.emp01 SET TABLESPACE edbua_tbs01;
 ALTER INDEX public.emp01_ix SET TABLESPACE edbua_tbs01;
 ALTER TABLE public.emp02 SET TABLESPACE edbua_tbs01;
 ALTER INDEX public.emp02_ix SET TABLESPACE edbua_tbs01;
 ALTER TABLE public.emp03 SET TABLESPACE edbua_tbs01;
 ALTER INDEX public.emp03_ix SET TABLESPACE edbua_tbs01;
(6 rows)

edbua=#

edbua=# ALTER TABLE public.emp01 SET TABLESPACE edbua_tbs01;
 ALTER INDEX public.emp02_ix SET TABLESPACE edbua_tbs01;
 ALTER TABLE public.emp03 SET TABLESPACE edbua_tbs01;
 ALTER INDEX public.emp03_ix SET TABLESPACE edbua_tbs01;ALTER TABLE
edbua=#  ALTER INDEX public.emp01_ix SET TABLESPACE edbua_tbs01;
ALTER INDEX
edbua=#  ALTER TABLE public.emp02 SET TABLESPACE edbua_tbs01;
ALTER TABLE
edbua=#  ALTER INDEX public.emp02_ix SET TABLESPACE edbua_tbs01;
ALTER INDEX
edbua=#  ALTER TABLE public.emp03 SET TABLESPACE edbua_tbs01;
ALTER TABLE
edbua=#  ALTER INDEX public.emp03_ix SET TABLESPACE edbua_tbs01;
ALTER INDEX
edbua=#

edbua=# drop tablespace edbua_tbs03;
DROP TABLESPACE
edbua=# \db+ edbua*
                                                List of tablespaces
      Name       |  Owner   |            Location             | Access privileges | Options |  Size   | Description
-----------------+----------+---------------------------------+-------------------+---------+---------+-------------
 edbua_ixtbs01   | postgres | /pgData/pgsql15/edbua_ixtbs01   |                   |         | 6 bytes |
 edbua_tbs01     | postgres | /pgData/pgsql15/edbua_tbs01     |                   |         | 7837 kB |
 edbua_temptbs01 | postgres | /pgData/pgsql15/edbua_temptbs01 |                   |         | 6 bytes |
(3 rows)

edbua=#


13. Change ownership for Tablespace

edbua=# ALTER TABLESPACE edbua_tbs01 OWNER TO teja;
ALTER TABLESPACE
edbua=# \db+ edbua*
                                                List of tablespaces
      Name       |  Owner   |            Location             | Access privileges | Options |  Size   | Description
-----------------+----------+---------------------------------+-------------------+---------+---------+-------------
 edbua_ixtbs01   | postgres | /pgData/pgsql15/edbua_ixtbs01   |                   |         | 6 bytes |
 edbua_tbs01     | teja     | /pgData/pgsql15/edbua_tbs01     |                   |         | 7837 kB |
 edbua_temptbs01 | postgres | /pgData/pgsql15/edbua_temptbs01 |                   |         | 6 bytes |
(3 rows)

edbua=# ALTER TABLESPACE edbua_tbs01 OWNER TO postgres;
ALTER TABLESPACE
edbua=# \db+ edbua*
                                                List of tablespaces
      Name       |  Owner   |            Location             | Access privileges | Options |  Size   | Description
-----------------+----------+---------------------------------+-------------------+---------+---------+-------------
 edbua_ixtbs01   | postgres | /pgData/pgsql15/edbua_ixtbs01   |                   |         | 6 bytes |
 edbua_tbs01     | postgres | /pgData/pgsql15/edbua_tbs01     |                   |         | 7837 kB |
 edbua_temptbs01 | postgres | /pgData/pgsql15/edbua_temptbs01 |                   |         | 6 bytes |
(3 rows)

edbua=#


14. Verify Symbolic Links

edbua=# show data_directory;
    data_directory
----------------------
 /pgData/pgsql15/data  <----
(1 row)

edbua=#

[root@pg17 pg_tblspc]# ls -ltr /pgData/pgsql15/data/pg_tblspc/*
lrwxrwxrwx. 1 postgres postgres 22 Aug 18 06:36 /pgData/pgsql15/data/pg_tblspc/24581 -> /u01/data/dell_ts_data
lrwxrwxrwx. 1 postgres postgres 23 Aug 18 06:36 /pgData/pgsql15/data/pg_tblspc/24582 -> /u01/data/dell_ts_index
lrwxrwxrwx. 1 postgres postgres 20 Sep  3 09:52 /pgData/pgsql15/data/pg_tblspc/24594 -> /pgData/pgsql15/data
lrwxrwxrwx. 1 postgres postgres 29 Sep  3 11:55 /pgData/pgsql15/data/pg_tblspc/24597 -> /pgData/pgsql15/data/trd_tb01
lrwxrwxrwx. 1 postgres postgres 29 Sep  3 11:55 /pgData/pgsql15/data/pg_tblspc/24598 -> /pgData/pgsql15/data/trd_ix01
lrwxrwxrwx. 1 postgres postgres 27 Sep  4 05:59 /pgData/pgsql15/data/pg_tblspc/32787 -> /pgData/pgsql15/pgtb/geb_tb
lrwxrwxrwx. 1 postgres postgres 27 Sep  4 06:03 /pgData/pgsql15/data/pg_tblspc/32788 -> /pgData/pgsql15/pgix/geb_ix
lrwxrwxrwx. 1 postgres postgres 27 Sep 20 07:20 /pgData/pgsql15/data/pg_tblspc/92662 -> /pgData/pgsql15/edbua_tbs01
lrwxrwxrwx. 1 postgres postgres 29 Sep 20 07:21 /pgData/pgsql15/data/pg_tblspc/92664 -> /pgData/pgsql15/edbua_ixtbs01
lrwxrwxrwx. 1 postgres postgres 31 Sep 20 07:21 /pgData/pgsql15/data/pg_tblspc/92665 -> /pgData/pgsql15/edbua_temptbs01
[root@pg17 pg_tblspc]#


15. How to find tablespace size

edbua=# SELECT spcname, pg_size_pretty(pg_tablespace_size(spcname)) AS size FROM pg_tablespace;
     spcname     |  size
-----------------+---------
 pg_default      | 1660 MB
 pg_global       | 571 kB
 dell_ts_data    | 7761 kB
 dell_ts_index   | 16 kB
 dell_tbs        | 0 bytes
 trd_tb01        | 1615 MB
 trd_ix01        | 2648 kB
 geb_tb          | 13 GB
 geb_ix          | 8950 MB
 edbua_ixtbs01   | 6 bytes
 edbua_temptbs01 | 6 bytes
 edbua_tbs01     | 7837 kB
(12 rows)

edbua=#
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

PostgreSQL pg_hba.conf

Host-Based Authentication (pg_hba.conf)

Table of Contents


1. What is pg_hba.conf?
2. Authentication Methods in pg_hba.conf
3. Create Database and User
4. Contents of pg_hba.conf
5. Play with peer
6. Play with trust
7. Play with reject
8. Restrict by User
9. Restrict by Network
10. Verify logs



1. What is pg_hba.conf?

HBA = Host-Based Authentication.
Location: usually inside PostgreSQL data directory (/var/lib/pgsql/<version>/data/pg_hba.conf or /pgData/pgsql15/data/pg_hba.conf depending on your setup).



Format:

# TYPE  DATABASE  USER  ADDRESS        METHOD
TYPE: local, host, hostssl, hostnossl
DATABASE: which DBs (e.g. all, postgres, mydb)
USER: which roles (e.g. all, myuser)
ADDRESS: client IP/CIDR (127.0.0.1/32, 192.168.2.0/24)
METHOD: authentication method (trust, md5, scram-sha-256, peer, reject, cert)

OPTIONS	: optional settings (e.g., clientcert=1)


2. Authentication Methods in pg_hba.conf

trust:
--- > No password needed. Anyone who can connect to the server is trusted.
--- > Use: testing only.
--- > Not secure in production.

Example:

host    all    all    127.0.0.1/32    trust

md5
--- > Password required, stored as MD5 hash.
--- > Legacy support. Weaker security, avoid if possible.

Example:

host    all    all    127.0.0.1/32    md5

scram-sha-256
--- > Password required, stored as salted SCRAM-SHA-256 hash.
--- > Stronger than MD5.
--- > Recommended method for production.

Example:

host    all    all    127.0.0.1/32    scram-sha-256


peer
--- > Works for local connections only.
--- > The OS user name must match the PostgreSQL role.
--- > Good for local scripts/services under same user.

Example:

local   all    all                     peer


reject
--- > Explicitly denies access.
----> Useful for blocking unwanted connections (like a firewall rule).

Example:

host    all    all    0.0.0.0/0       reject


cert
---> Requires SSL/TLS client certificate.
---> PostgreSQL role must match certificate username.
---> Very secure for enterprise / production with SSL.

Example:
hostssl all   all    192.168.1.0/24   cert clientcert=1


3. Create Database and User

postgres=# CREATE USER teja WITH PASSWORD 'teja123';
CREATE ROLE
postgres=# CREATE DATABASE orcl OWNER teja;
CREATE DATABASE
postgres=#


4. Contents of pg_hba.conf

[postgres@pg17 ~]$ cat /pgData/pgsql15/data/pg_hba.conf
# TYPE  DATABASE         USER            ADDRESS                METHOD

# Allow local peer access for postgres
local   all             postgres                                peer

# Allow local password access for all
local   all             all                                     scram-sha-256

[postgres@pg17 ~]$


5. Play with peer

Works for local connections only. The OS user name must match the PostgreSQL role.

[postgres@pg17 ~]$ cat /pgData/pgsql15/data/pg_hba.conf
# TYPE  DATABASE         USER            ADDRESS                METHOD

# Allow local peer access for postgres

local   all             postgres                                peer


# Allow local password access for all
local   all             all                                     scram-sha-256

[postgres@pg17 ~]$

[postgres@pg17 ~]$ psql -U teja -d orcl
 Password for user teja: <---- it's asking password 

psql (15.13)
Type "help" for help.

orcl=> exit
[postgres@pg17 ~]$

 Password Not asking for user postgres 
[postgres@pg17 ~]$ psql -U postgres -d orcl
psql (15.13)
Type "help" for help.

orcl=#


6. Play with trust

No password needed. Anyone who can connect to the server is trusted.
Use: testing only. Not secure in production.

Change pg_hba.conf:

[postgres@pg17 ~]$ cat /pgData/pgsql15/data/pg_hba.conf
# TYPE  DATABASE         USER            ADDRESS                METHOD

# Allow local peer access for postgres
local   all             postgres                                peer

# Allow local password access for all

local   all             all                                     trust

[postgres@pg17 ~]$

[postgres@pg17 ~]$ /usr/pgsql-15/bin/pg_ctl reload -D /pgData/pgsql15/data/
server signaled
[postgres@pg17 ~]$ psql -U teja -d orcl  <--- It won’t ask for a password. 
psql (15.13)
Type "help" for help.

orcl=>


7. Play with reject

[postgres@pg17 ~]$ cat /pgData/pgsql15/data/pg_hba.conf
# TYPE  DATABASE         USER            ADDRESS                METHOD

# Allow local peer access for postgres
local   all             postgres                                peer

# Allow local password access for all

local   all             all                                     reject

[postgres@pg17 ~]$

[postgres@pg17 ~]$ /usr/pgsql-15/bin/pg_ctl reload -D /pgData/pgsql15/data/
server signaled
[postgres@pg17 ~]$ psql -U teja -d orcl

psql: error: connection to server on socket "/run/postgresql/.s.PGSQL.5432" failed: FATAL:  pg_hba.conf rejects connection for host "[local]", user "teja", database "orcl", no encryption

[postgres@pg17 ~]$


8. Restrict by User

Allow only user teja, block everyone else:

[postgres@pg17 ~]$ cat /pgData/pgsql15/data/pg_hba.conf
# TYPE  DATABASE         USER            ADDRESS                METHOD

# Allow local peer access for postgres
local   all             postgres                                peer

# Allow local password access for all
local   all             all                                     trust

# Allow IPv4 localhost

host    orcl            teja             192.168.2.31/32         scram-sha-256
host    orcl            all              192.168.2.31/32         reject


[postgres@pg17 ~]$

[postgres@pg17 ~]$ /usr/pgsql-15/bin/pg_ctl reload -D /pgData/pgsql15/data/
server signaled
[postgres@pg17 ~]$ psql -U teja -d orcl -h 192.168.2.31
Password for user teja:
psql (15.13)
Type "help" for help.

orcl=> \conninfo
You are connected to database "orcl" as user "teja" on host "192.168.2.31" at port "5432".
orcl=>
orcl=> exit
[postgres@pg17 ~]$


[postgres@pg17 ~]$ psql -U postgres -d orcl -h 192.168.2.31

psql: error: connection to server at "192.168.2.31", port 5432 failed: FATAL:  pg_hba.conf rejects connection for host "192.168.2.31", user "postgres", database "orcl", no encryption

[postgres@pg17 ~]$


Notice: Only user Teja able to connect where as user postgres not able to connect


9. Restrict by Network

We want to block connections from IP 192.168.2.0/24 

[postgres@pg17 ~]$ cat /pgData/pgsql15/data/pg_hba.conf
# TYPE  DATABASE         USER            ADDRESS                METHOD

# Allow local peer access for postgres
local   all             postgres                                peer

# Allow local password access for all
local   all             all                                     trust

# Allow IPv4 localhost

host    all             all             192.168.2.0/24          reject

[postgres@pg17 ~]$

[postgres@pg17 ~]$ /usr/pgsql-15/bin/pg_ctl reload -D /pgData/pgsql15/data/
server signaled
[postgres@pg17 ~]$ 
[postgres@pg17 ~]$ psql -U teja -d orcl -h 192.168.2.31

psql: error: connection to server at "192.168.2.31", port 5432 failed: FATAL:  pg_hba.conf rejects connection for host "192.168.2.31", user "teja", database "orcl", no encryption

[postgres@pg17 ~]$


10. Verify logs

postgres=# SELECT * FROM pg_hba_file_rules;
 line_number | type  | database | user_name  |   address    |     netmask     |  auth_method  | options | error
-------------+-------+----------+------------+--------------+-----------------+---------------+---------+-------
           4 | local | {all}    | {postgres} |              |                 | peer          |         |
           7 | local | {all}    | {all}      |              |                 | trust         |         |
          11 | host  | {orcl}   | {teja}     | 192.168.2.31 | 255.255.255.255 | scram-sha-256 |         |
          12 | host  | {orcl}   | {all}      | 192.168.2.31 | 255.255.255.255 | reject        |         |
(4 rows)

postgres=#

[postgres@pg17 ~]$ tail -f /pgData/pgsql15/data/log/postgresql-Tue.log
2025-09-16 04:08:37.244 EDT [8294] LOG:  database system was shut down at 2025-09-16 04:08:32 EDT
2025-09-16 04:08:37.251 EDT [8289] LOG:  database system is ready to accept connections
2025-09-16 04:11:27.459 EDT [8289] LOG:  received SIGHUP, reloading configuration files
2025-09-16 04:11:31.842 EDT [8401] FATAL:  pg_hba.conf rejects connection for host "[local]", user "teja", database "orcl", no encryption
2025-09-16 04:13:37.568 EDT [8292] LOG:  checkpoint starting: time
2025-09-16 04:13:37.573 EDT [8292] LOG:  checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.002 s, sync=0.002 s, total=0.006 s; sync files=2, longest=0.001 s, average=0.001 s; distance=0 kB, estimate=0 kB
2025-09-16 04:16:15.863 EDT [8289] LOG:  received SIGHUP, reloading configuration files
2025-09-16 04:16:52.318 EDT [8474] FATAL:  pg_hba.conf rejects connection for host "192.168.2.31", user "teja", database "orcl", no encryption
2025-09-16 04:27:15.932 EDT [8289] LOG:  received SIGHUP, reloading configuration files
2025-09-16 04:27:50.593 EDT [8613] FATAL:  pg_hba.conf rejects connection for host "192.168.2.31", user "postgres", database "orcl", no encryption

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/

Install PostgreSQL Using Source Code

How to Install PostgreSQL 13 Using Source Code on Linux 7

Table of Contents
___________________________________________________________________________________________________

1. Install required packages
2. Download the source code tar file
3. Extract tar file
4. configure –help
5. Create postgres user and required directories
6. Configure postgreSQL
7. Build postgreSQL using make command
8. Install postgreSQL using make install command
9. Build contrib module using make command (optional)
10. Install contrib module using make install command (optional)
11. Validation
12. Change binary owner to postgres
13. Initialize postgreSQL data directory using postgres user
14. Validate the postgreSQL data directory
15. Start postgreSQL database as postgres user
16. Setting the postgres User Environment Variables
17. Create postgreSQL DB and test the installation

___________________________________________________________________________________________________


1. Install required packages

[root@pcs1 ~]# dhclient
[root@pcs1 ~]# yum install readline-devel
Loaded plugins: langpacks, ulninfo
ol7_UEKR4                                                                                                                                                                                                             | 3.0 kB  00:00:00
ol7_latest                                                                                                                                                                                                            | 3.6 kB  00:00:00
(1/4): ol7_UEKR4/x86_64/updateinfo                                                                                                                                                                                    | 107 kB  00:00:00
(2/4): ol7_latest/x86_64/updateinfo                                                                                                                                                                                   | 3.4 MB  00:00:03
(3/4): ol7_UEKR4/x86_64/primary_db                                                                                                                                                                                    |  18 MB  00:00:11
(4/4): ol7_latest/x86_64/primary_db                                                                                                                                                                                   |  37 MB  00:00:12
Resolving Dependencies
--> Running transaction check
---> Package readline-devel.x86_64 0:6.2-11.el7 will be installed
--> Processing Dependency: readline = 6.2-11.el7 for package: readline-devel-6.2-11.el7.x86_64
--> Processing Dependency: ncurses-devel for package: readline-devel-6.2-11.el7.x86_64
--> Running transaction check
---> Package ncurses-devel.x86_64 0:5.9-14.20130511.el7_4 will be installed
---> Package readline.x86_64 0:6.2-10.el7 will be updated
---> Package readline.x86_64 0:6.2-11.el7 will be an update
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================================================================================================================================================================================
 Package                                                   Arch                                              Version                                                             Repository                                             Size
=============================================================================================================================================================================================================================================
Installing:
 readline-devel                                            x86_64                                            6.2-11.el7                                                          ol7_latest                                            138 k
Installing for dependencies:
 ncurses-devel                                             x86_64                                            5.9-14.20130511.el7_4                                               ol7_latest                                            712 k
Updating for dependencies:
 readline                                                  x86_64                                            6.2-11.el7                                                          ol7_latest                                            193 k

Transaction Summary
=============================================================================================================================================================================================================================================
Install  1 Package  (+1 Dependent package)
Upgrade             ( 1 Dependent package)

Total download size: 1.0 M
Is this ok [y/d/N]: y
Downloading packages:
No Presto metadata available for ol7_latest
(1/3): readline-6.2-11.el7.x86_64.rpm                                                                                                                                                                                 | 193 kB  00:00:00
(2/3): readline-devel-6.2-11.el7.x86_64.rpm                                                                                                                                                                           | 138 kB  00:00:00
(3/3): ncurses-devel-5.9-14.20130511.el7_4.x86_64.rpm                                                                                                                                                                 | 712 kB  00:00:00
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                        1.0 MB/s | 1.0 MB  00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : ncurses-devel-5.9-14.20130511.el7_4.x86_64                                                                                                                                                                                1/4
  Updating   : readline-6.2-11.el7.x86_64                                                                                                                                                                                                2/4
  Installing : readline-devel-6.2-11.el7.x86_64                                                                                                                                                                                          3/4
  Cleanup    : readline-6.2-10.el7.x86_64                                                                                                                                                                                                4/4
  Verifying  : readline-devel-6.2-11.el7.x86_64                                                                                                                                                                                          1/4
  Verifying  : readline-6.2-11.el7.x86_64                                                                                                                                                                                                2/4
  Verifying  : ncurses-devel-5.9-14.20130511.el7_4.x86_64                                                                                                                                                                                3/4
  Verifying  : readline-6.2-10.el7.x86_64                                                                                                                                                                                                4/4

Installed:
  readline-devel.x86_64 0:6.2-11.el7

Dependency Installed:
  ncurses-devel.x86_64 0:5.9-14.20130511.el7_4

Dependency Updated:
  readline.x86_64 0:6.2-11.el7

Complete!
[root@pcs1 ~]#

[root@pcs1 ~]# yum install -y zlib-devel
Loaded plugins: langpacks, ulninfo
Resolving Dependencies
--> Running transaction check
---> Package zlib-devel.x86_64 0:1.2.7-19.el7_9 will be installed
--> Processing Dependency: zlib = 1.2.7-19.el7_9 for package: zlib-devel-1.2.7-19.el7_9.x86_64
--> Running transaction check
---> Package zlib.x86_64 0:1.2.7-17.el7 will be updated
---> Package zlib.x86_64 0:1.2.7-19.el7_9 will be an update
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================================================================================================================================================================================
 Package                                                  Arch                                                 Version                                                        Repository                                                Size
=============================================================================================================================================================================================================================================
Installing:
 zlib-devel                                               x86_64                                               1.2.7-19.el7_9                                                 ol7_latest                                                50 k
Updating for dependencies:
 zlib                                                     x86_64                                               1.2.7-19.el7_9                                                 ol7_latest                                                89 k

Transaction Summary
=============================================================================================================================================================================================================================================
Install  1 Package
Upgrade             ( 1 Dependent package)

Total download size: 139 k
Downloading packages:
No Presto metadata available for ol7_latest
(1/2): zlib-devel-1.2.7-19.el7_9.x86_64.rpm                                                                                                                                                                           |  50 kB  00:00:00
(2/2): zlib-1.2.7-19.el7_9.x86_64.rpm                                                                                                                                                                                 |  89 kB  00:00:00
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                        159 kB/s | 139 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : zlib-1.2.7-19.el7_9.x86_64                                                                                                                                                                                                1/3
  Installing : zlib-devel-1.2.7-19.el7_9.x86_64                                                                                                                                                                                          2/3
  Cleanup    : zlib-1.2.7-17.el7.x86_64                                                                                                                                                                                                  3/3
  Verifying  : zlib-devel-1.2.7-19.el7_9.x86_64                                                                                                                                                                                          1/3
  Verifying  : zlib-1.2.7-19.el7_9.x86_64                                                                                                                                                                                                2/3
  Verifying  : zlib-1.2.7-17.el7.x86_64                                                                                                                                                                                                  3/3

Installed:
  zlib-devel.x86_64 0:1.2.7-19.el7_9

Dependency Updated:
  zlib.x86_64 0:1.2.7-19.el7_9

Complete!
[root@pcs1 ~]#
[root@pcs1 ~]#

[root@pcs1 ~]# yum install -y install gcc
Loaded plugins: langpacks, ulninfo
No package install available.
Resolving Dependencies
--> Running transaction check
---> Package gcc.x86_64 0:4.8.5-28.0.1.el7 will be updated
--> Processing Dependency: gcc = 4.8.5-28.0.1.el7 for package: gcc-gfortran-4.8.5-28.0.1.el7.x86_64
--> Processing Dependency: gcc = 4.8.5-28.0.1.el7 for package: libquadmath-devel-4.8.5-28.0.1.el7.x86_64
--> Processing Dependency: gcc = 4.8.5-28.0.1.el7 for package: gcc-c++-4.8.5-28.0.1.el7.x86_64
---> Package gcc.x86_64 0:4.8.5-44.0.3.el7 will be an update
--> Processing Dependency: cpp = 4.8.5-44.0.3.el7 for package: gcc-4.8.5-44.0.3.el7.x86_64
--> Processing Dependency: libgomp = 4.8.5-44.0.3.el7 for package: gcc-4.8.5-44.0.3.el7.x86_64
--> Processing Dependency: libgcc >= 4.8.5-44.0.3.el7 for package: gcc-4.8.5-44.0.3.el7.x86_64
--> Running transaction check
---> Package cpp.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package cpp.x86_64 0:4.8.5-44.0.3.el7 will be an update
---> Package gcc-c++.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package gcc-c++.x86_64 0:4.8.5-44.0.3.el7 will be an update
--> Processing Dependency: libstdc++ = 4.8.5-44.0.3.el7 for package: gcc-c++-4.8.5-44.0.3.el7.x86_64
--> Processing Dependency: libstdc++-devel = 4.8.5-44.0.3.el7 for package: gcc-c++-4.8.5-44.0.3.el7.x86_64
---> Package gcc-gfortran.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package gcc-gfortran.x86_64 0:4.8.5-44.0.3.el7 will be an update
--> Processing Dependency: libgfortran = 4.8.5-44.0.3.el7 for package: gcc-gfortran-4.8.5-44.0.3.el7.x86_64
--> Processing Dependency: libquadmath = 4.8.5-44.0.3.el7 for package: gcc-gfortran-4.8.5-44.0.3.el7.x86_64
---> Package libgcc.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package libgcc.x86_64 0:4.8.5-44.0.3.el7 will be an update
---> Package libgomp.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package libgomp.x86_64 0:4.8.5-44.0.3.el7 will be an update
---> Package libquadmath-devel.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package libquadmath-devel.x86_64 0:4.8.5-44.0.3.el7 will be an update
--> Running transaction check
---> Package libgfortran.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package libgfortran.x86_64 0:4.8.5-44.0.3.el7 will be an update
---> Package libquadmath.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package libquadmath.x86_64 0:4.8.5-44.0.3.el7 will be an update
---> Package libstdc++.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package libstdc++.x86_64 0:4.8.5-44.0.3.el7 will be an update
---> Package libstdc++-devel.x86_64 0:4.8.5-28.0.1.el7 will be updated
---> Package libstdc++-devel.x86_64 0:4.8.5-44.0.3.el7 will be an update
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================================================================================================================================================================================
 Package                                                       Arch                                               Version                                                       Repository                                              Size
=============================================================================================================================================================================================================================================
Updating:
 gcc                                                           x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                              16 M
Updating for dependencies:
 cpp                                                           x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             5.9 M
 gcc-c++                                                       x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             7.2 M
 gcc-gfortran                                                  x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             6.7 M
 libgcc                                                        x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             103 k
 libgfortran                                                   x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             301 k
 libgomp                                                       x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             159 k
 libquadmath                                                   x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             191 k
 libquadmath-devel                                             x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                              54 k
 libstdc++                                                     x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             306 k
 libstdc++-devel                                               x86_64                                             4.8.5-44.0.3.el7                                              ol7_latest                                             1.5 M

Transaction Summary
=============================================================================================================================================================================================================================================
Upgrade  1 Package (+10 Dependent packages)

Total download size: 39 M
Downloading packages:
No Presto metadata available for ol7_latest
(1/11): gcc-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                               |  16 MB  00:00:04
(2/11): cpp-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                               | 5.9 MB  00:00:05
(3/11): gcc-c++-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                           | 7.2 MB  00:00:01
(4/11): libgcc-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                            | 103 kB  00:00:00
(5/11): libgfortran-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                       | 301 kB  00:00:00
(6/11): libgomp-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                           | 159 kB  00:00:00
(7/11): libquadmath-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                       | 191 kB  00:00:00
(8/11): libquadmath-devel-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                 |  54 kB  00:00:00
(9/11): libstdc++-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                         | 306 kB  00:00:00
(10/11): gcc-gfortran-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                     | 6.7 MB  00:00:02
(11/11): libstdc++-devel-4.8.5-44.0.3.el7.x86_64.rpm                                                                                                                                                                  | 1.5 MB  00:00:00
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                        5.0 MB/s |  39 MB  00:00:07
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : libgcc-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                           1/22
  Updating   : libquadmath-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                      2/22
  Updating   : libstdc++-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                        3/22
  Updating   : libstdc++-devel-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                  4/22
  Updating   : libgfortran-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                      5/22
  Updating   : cpp-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                              6/22
  Updating   : libgomp-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                          7/22
  Updating   : gcc-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                              8/22
  Updating   : libquadmath-devel-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                9/22
  Updating   : gcc-gfortran-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                    10/22
  Updating   : gcc-c++-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                         11/22
  Cleanup    : gcc-c++-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                         12/22
  Cleanup    : gcc-gfortran-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                    13/22
  Cleanup    : libquadmath-devel-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                               14/22
  Cleanup    : libstdc++-devel-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                 15/22
  Cleanup    : gcc-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                             16/22
  Cleanup    : libgfortran-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                     17/22
  Cleanup    : libstdc++-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                       18/22
  Cleanup    : libgcc-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                          19/22
  Cleanup    : libquadmath-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                     20/22
  Cleanup    : cpp-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                             21/22
  Cleanup    : libgomp-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                         22/22
  Verifying  : gcc-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                              1/22
  Verifying  : libquadmath-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                      2/22
  Verifying  : libstdc++-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                        3/22
  Verifying  : gcc-gfortran-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                     4/22
  Verifying  : libgomp-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                          5/22
  Verifying  : libstdc++-devel-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                  6/22
  Verifying  : libquadmath-devel-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                7/22
  Verifying  : gcc-c++-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                          8/22
  Verifying  : libgfortran-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                      9/22
  Verifying  : libgcc-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                          10/22
  Verifying  : cpp-4.8.5-44.0.3.el7.x86_64                                                                                                                                                                                             11/22
  Verifying  : gcc-gfortran-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                    12/22
  Verifying  : libgomp-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                         13/22
  Verifying  : libgcc-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                          14/22
  Verifying  : libstdc++-devel-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                 15/22
  Verifying  : gcc-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                             16/22
  Verifying  : cpp-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                             17/22
  Verifying  : libquadmath-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                     18/22
  Verifying  : gcc-c++-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                         19/22
  Verifying  : libgfortran-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                     20/22
  Verifying  : libstdc++-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                                       21/22
  Verifying  : libquadmath-devel-4.8.5-28.0.1.el7.x86_64                                                                                                                                                                               22/22

Updated:
  gcc.x86_64 0:4.8.5-44.0.3.el7

Dependency Updated:
  cpp.x86_64 0:4.8.5-44.0.3.el7         gcc-c++.x86_64 0:4.8.5-44.0.3.el7           gcc-gfortran.x86_64 0:4.8.5-44.0.3.el7 libgcc.x86_64 0:4.8.5-44.0.3.el7          libgfortran.x86_64 0:4.8.5-44.0.3.el7 libgomp.x86_64 0:4.8.5-44.0.3.el7
  libquadmath.x86_64 0:4.8.5-44.0.3.el7 libquadmath-devel.x86_64 0:4.8.5-44.0.3.el7 libstdc++.x86_64 0:4.8.5-44.0.3.el7    libstdc++-devel.x86_64 0:4.8.5-44.0.3.el7

Complete!
[root@pcs1 ~]#

[root@pcs1 ~]# yum install -y make
Loaded plugins: langpacks, ulninfo
Resolving Dependencies
--> Running transaction check
---> Package make.x86_64 1:3.82-23.el7 will be updated
---> Package make.x86_64 1:3.82-24.el7 will be an update
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================================================================================================================================================================================
 Package                                              Arch                                                   Version                                                        Repository                                                  Size
=============================================================================================================================================================================================================================================
Updating:
 make                                                 x86_64                                                 1:3.82-24.el7                                                  ol7_latest                                                 420 k

Transaction Summary
=============================================================================================================================================================================================================================================
Upgrade  1 Package

Total download size: 420 k
Downloading packages:
No Presto metadata available for ol7_latest
make-3.82-24.el7.x86_64.rpm                                                                                                                                                                                           | 420 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : 1:make-3.82-24.el7.x86_64                                                                                                                                                                                                 1/2
  Cleanup    : 1:make-3.82-23.el7.x86_64                                                                                                                                                                                                 2/2
  Verifying  : 1:make-3.82-24.el7.x86_64                                                                                                                                                                                                 1/2
  Verifying  : 1:make-3.82-23.el7.x86_64                                                                                                                                                                                                 2/2

Updated:
  make.x86_64 1:3.82-24.el7

Complete!
[root@pcs1 ~]#


2. Download the source code tar file

wget https://ftp.postgresql.org/pub/source/v13.3/postgresql-13.3.tar.gz

OR Download and then copy to server using winscp.

https://ftp.postgresql.org/pub/source/v13.3/postgresql-13.3.tar.gz


3. Extract tar file

[root@pcs1 ~]# tar -xvf postgresql-13.3.tar.gz
[root@pcs1 ~]#
-rw-r--r--. 1 root root 27610951 May 11  2021 postgresql-13.3.tar.gz
drwxrwxrwx. 6 1107 1107     4096 Dec 23 00:40 postgresql-13.3
[root@pcs1 ~]#



4. configure –help ..choose the options according to your needs.

[root@pcs1 ~]# cd postgresql-13.3/
[root@pcs1 postgresql-13.3]# ./configure --help
`configure' configures PostgreSQL 13.3 to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

Configuration:
  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print `checking ...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local/pgsql]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [PREFIX]

By default, `make install' will install all the files in
`/usr/local/pgsql/bin', `/usr/local/pgsql/lib' etc.  You can specify
an installation prefix other than `/usr/local/pgsql' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR            user executables [EPREFIX/bin]
  --sbindir=DIR           system admin executables [EPREFIX/sbin]
  --libexecdir=DIR        program executables [EPREFIX/libexec]
  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
  --libdir=DIR            object code libraries [EPREFIX/lib]
  --includedir=DIR        C header files [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR           info documentation [DATAROOTDIR/info]
  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR            man documentation [DATAROOTDIR/man]
  --docdir=DIR            documentation root [DATAROOTDIR/doc/postgresql]
  --htmldir=DIR           html documentation [DOCDIR]
  --dvidir=DIR            dvi documentation [DOCDIR]
  --pdfdir=DIR            pdf documentation [DOCDIR]
  --psdir=DIR             ps documentation [DOCDIR]

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --disable-integer-datetimes
                          obsolete option, no longer supported
  --enable-nls[=LANGUAGES]
                          enable Native Language Support
  --disable-rpath         do not embed shared library search path in
                          executables
  --disable-spinlocks     do not use spinlocks
  --disable-atomics       do not use atomic operations
  --enable-debug          build with debugging symbols (-g)
  --enable-profiling      build with profiling enabled
  --enable-coverage       build with coverage testing instrumentation
  --enable-dtrace         build with DTrace support
  --enable-tap-tests      enable TAP tests (requires Perl and IPC::Run)
  --enable-depend         turn on automatic dependency tracking
  --enable-cassert        enable assertion checks (for debugging)
  --disable-thread-safety disable thread-safety in client libraries
  --disable-largefile     omit support for large files

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-extra-version=STRING
                          append STRING to version
  --with-template=NAME    override operating system template
  --with-includes=DIRS    look for additional header files in DIRS
  --with-libraries=DIRS   look for additional libraries in DIRS
  --with-libs=DIRS        alternative spelling of --with-libraries
  --with-pgport=PORTNUM   set default port number [5432]
  --with-blocksize=BLOCKSIZE
                          set table block size in kB [8]
  --with-segsize=SEGSIZE  set table segment size in GB [1]
  --with-wal-blocksize=BLOCKSIZE
                          set WAL block size in kB [8]
  --with-CC=CMD           set compiler (deprecated)
  --with-llvm             build with LLVM based JIT support
  --with-icu              build with ICU support
  --with-tcl              build Tcl modules (PL/Tcl)
  --with-tclconfig=DIR    tclConfig.sh is in DIR
  --with-perl             build Perl modules (PL/Perl)
  --with-python           build Python modules (PL/Python)
  --with-gssapi           build with GSSAPI support
  --with-krb-srvnam=NAME  default service principal name in Kerberos (GSSAPI)
                          [postgres]
  --with-pam              build with PAM support
  --with-bsd-auth         build with BSD Authentication support
  --with-ldap             build with LDAP support
  --with-bonjour          build with Bonjour support
  --with-openssl          build with OpenSSL support
  --with-selinux          build with SELinux support
  --with-systemd          build with systemd support
  --without-readline      do not use GNU Readline nor BSD Libedit for editing
  --with-libedit-preferred
                          prefer BSD Libedit over GNU Readline
  --with-uuid=LIB         build contrib/uuid-ossp using LIB (bsd,e2fs,ossp)
  --with-ossp-uuid        obsolete spelling of --with-uuid=ossp
  --with-libxml           build with XML support
  --with-libxslt          use XSLT support when building contrib/xml2
  --with-system-tzdata=DIR
                          use system time zone data in DIR
  --without-zlib          do not use Zlib
  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L if you have libraries in a
              nonstandard directory 
  LIBS        libraries to pass to the linker, e.g. -l
  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I if
              you have headers in a nonstandard directory 
  CXX         C++ compiler command
  CXXFLAGS    C++ compiler flags
  LLVM_CONFIG path to llvm-config command
  CLANG       path to clang compiler to generate bitcode
  CPP         C preprocessor
  PKG_CONFIG  path to pkg-config utility
  PKG_CONFIG_PATH
              directories to add to pkg-config's search path
  PKG_CONFIG_LIBDIR
              path overriding pkg-config's built-in search path
  ICU_CFLAGS  C compiler flags for ICU, overriding pkg-config
  ICU_LIBS    linker flags for ICU, overriding pkg-config
  XML2_CONFIG path to xml2-config utility
  XML2_CFLAGS C compiler flags for XML2, overriding pkg-config
  XML2_LIBS   linker flags for XML2, overriding pkg-config
  LDFLAGS_EX  extra linker flags for linking executables only
  LDFLAGS_SL  extra linker flags for linking shared libraries only
  PERL        Perl program
  PYTHON      Python program
  MSGFMT      msgfmt program for NLS
  TCLSH       Tcl interpreter program (tclsh)

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to <pgsql-bugs@lists.postgresql.org>.
PostgreSQL home page: <https://www.postgresql.org/>.
[root@pcs1 postgresql-13.3]#


5. Create postgres user and required directories

[root@pcs1 ~]# useradd -d /home/postgres/ postgres
[root@pcs1 ~]# passwd postgres
Changing password for user postgres.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
[root@pcs1 ~]#
[root@pcs1 ~]# id postgres
uid=54322(postgres) gid=54323(postgres) groups=54323(postgres)
[root@pcs1 ~]#

[root@pcs1 ~]# mkdir -p /u01/app/postgres/13.3
[root@pcs1 ~]# mkdir -p /u02/app/psql/13.3/DATA


6. Configure PostgreSQL

[root@pcs1 ~]# cd postgresql-13.3
[root@pcs1 postgresql-13.3]# ls -ltr
total 744
-rw-r--r--.  1 1107 1107   1213 May 11  2021 README
-rw-r--r--.  1 1107 1107   1665 May 11  2021 Makefile
-rw-r--r--.  1 1107 1107    277 May 11  2021 HISTORY
-rw-r--r--.  1 1107 1107   4278 May 11  2021 GNUmakefile.in
-rw-r--r--.  1 1107 1107   1192 May 11  2021 COPYRIGHT
-rw-r--r--.  1 1107 1107  82388 May 11  2021 configure.in
-rwxr-xr-x.  1 1107 1107 568656 May 11  2021 configure
-rw-r--r--.  1 1107 1107    490 May 11  2021 aclocal.m4
drwxrwxrwx. 57 1107 1107   4096 May 11  2021 contrib
drwxrwxrwx.  2 1107 1107   4096 May 11  2021 config
drwxrwxrwx.  3 1107 1107     87 May 11  2021 doc
-rw-r--r--.  1 1107 1107  63684 May 11  2021 INSTALL
drwxrwxrwx. 16 1107 1107   4096 May 11  2021 src
[root@pcs1 postgresql-13.3]# ./configure --prefix=/u01/app/postgres/13.3 --with-pgport=5432
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking which template to use... linux
checking whether NLS is wanted... no
checking for default port number... 5432
checking for block size... 8kB
checking for segment size... 1GB
checking for WAL block size... 8kB
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for gcc option to accept ISO C99... -std=gnu99
checking for g++... g++
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for gawk... gawk
checking whether gcc -std=gnu99 supports -Wdeclaration-after-statement, for CFLAGS... yes
checking whether gcc -std=gnu99 supports -Werror=vla, for CFLAGS... yes
checking whether gcc -std=gnu99 supports -Wendif-labels, for CFLAGS... yes
checking whether g++ supports -Wendif-labels, for CXXFLAGS... yes
checking whether gcc -std=gnu99 supports -Wmissing-format-attribute, for CFLAGS... yes
checking whether g++ supports -Wmissing-format-attribute, for CXXFLAGS... yes
checking whether gcc -std=gnu99 supports -Wimplicit-fallthrough=3, for CFLAGS... no
checking whether g++ supports -Wimplicit-fallthrough=3, for CXXFLAGS... no
checking whether gcc -std=gnu99 supports -Wformat-security, for CFLAGS... yes
checking whether g++ supports -Wformat-security, for CXXFLAGS... yes
checking whether gcc -std=gnu99 supports -fno-strict-aliasing, for CFLAGS... yes
checking whether g++ supports -fno-strict-aliasing, for CXXFLAGS... yes
checking whether gcc -std=gnu99 supports -fwrapv, for CFLAGS... yes
checking whether g++ supports -fwrapv, for CXXFLAGS... yes
checking whether gcc -std=gnu99 supports -fexcess-precision=standard, for CFLAGS... yes
checking whether g++ supports -fexcess-precision=standard, for CXXFLAGS... no
checking whether gcc -std=gnu99 supports -funroll-loops, for CFLAGS_VECTOR... yes
checking whether gcc -std=gnu99 supports -ftree-vectorize, for CFLAGS_VECTOR... yes
checking whether gcc -std=gnu99 supports -Wunused-command-line-argument, for NOT_THE_CFLAGS... no
checking whether gcc -std=gnu99 supports -Wformat-truncation, for NOT_THE_CFLAGS... no
checking whether gcc -std=gnu99 supports -Wstringop-truncation, for NOT_THE_CFLAGS... no
checking whether the C compiler still works... yes
checking how to run the C preprocessor... gcc -std=gnu99 -E
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
checking allow thread-safe client libraries... yes
checking whether to build with ICU support... no
checking whether to build with Tcl... no
checking whether to build Perl modules... no
checking whether to build Python modules... no
checking whether to build with GSSAPI support... no
checking whether to build with PAM support... no
checking whether to build with BSD Authentication support... no
checking whether to build with LDAP support... no
checking whether to build with Bonjour support... no
checking whether to build with OpenSSL support... no
checking whether to build with SELinux support... no
checking whether to build with systemd support... no
checking whether to build with XML support... no
checking for ld used by GCC... /usr/bin/ld
checking if the linker (/usr/bin/ld) is GNU ld... yes
checking for ranlib... ranlib
checking for strip... strip
checking whether it is possible to strip libraries... yes
checking for ar... ar
checking for a BSD-compatible install... /usr/bin/install -c
checking for tar... /usr/bin/tar
checking whether ln -s works... yes
checking for a thread-safe mkdir -p... /usr/bin/mkdir -p
checking for bison... /usr/bin/bison
configure: using bison (GNU Bison) 3.0.4
checking for flex... /usr/bin/flex
configure: using flex 2.5.37
checking for perl... /usr/bin/perl
configure: using perl 5.16.3
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking whether gcc -std=gnu99 is Clang... no
checking whether pthreads work with -pthread... yes
checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE
checking whether more special flags are required for pthreads... no
checking for PTHREAD_PRIO_INHERIT... yes
checking pthread.h usability... yes
checking pthread.h presence... yes
checking for pthread.h... yes
checking for strerror_r... yes
checking for getpwuid_r... yes
checking for gethostbyname_r... yes
checking whether strerror_r returns int... no
checking for main in -lm... yes
checking for library containing setproctitle... no
checking for library containing dlopen... -ldl
checking for library containing socket... none required
checking for library containing shl_load... no
checking for library containing getopt_long... none required
checking for library containing shm_open... -lrt
checking for library containing shm_unlink... none required
checking for library containing clock_gettime... none required
checking for library containing fdatasync... none required
checking for library containing sched_yield... none required
checking for library containing gethostbyname_r... none required
checking for library containing shmget... none required
checking for library containing backtrace_symbols... none required
checking for library containing readline... -lreadline
checking for inflate in -lz... yes
checking for stdbool.h that conforms to C99... yes
checking for _Bool... yes
checking atomic.h usability... no
checking atomic.h presence... no
checking for atomic.h... no
checking copyfile.h usability... no
checking copyfile.h presence... no
checking for copyfile.h... no
checking execinfo.h usability... yes
checking execinfo.h presence... yes
checking for execinfo.h... yes
checking getopt.h usability... yes
checking getopt.h presence... yes
checking for getopt.h... yes
checking ifaddrs.h usability... yes
checking ifaddrs.h presence... yes
checking for ifaddrs.h... yes
checking langinfo.h usability... yes
checking langinfo.h presence... yes
checking for langinfo.h... yes
checking mbarrier.h usability... no
checking mbarrier.h presence... no
checking for mbarrier.h... no
checking poll.h usability... yes
checking poll.h presence... yes
checking for poll.h... yes
checking sys/epoll.h usability... yes
checking sys/epoll.h presence... yes
checking for sys/epoll.h... yes
checking sys/event.h usability... no
checking sys/event.h presence... no
checking for sys/event.h... no
checking sys/ipc.h usability... yes
checking sys/ipc.h presence... yes
checking for sys/ipc.h... yes
checking sys/prctl.h usability... yes
checking sys/prctl.h presence... yes
checking for sys/prctl.h... yes
checking sys/procctl.h usability... no
checking sys/procctl.h presence... no
checking for sys/procctl.h... no
checking sys/pstat.h usability... no
checking sys/pstat.h presence... no
checking for sys/pstat.h... no
checking sys/resource.h usability... yes
checking sys/resource.h presence... yes
checking for sys/resource.h... yes
checking sys/select.h usability... yes
checking sys/select.h presence... yes
checking for sys/select.h... yes
checking sys/sem.h usability... yes
checking sys/sem.h presence... yes
checking for sys/sem.h... yes
checking sys/shm.h usability... yes
checking sys/shm.h presence... yes
checking for sys/shm.h... yes
checking sys/sockio.h usability... no
checking sys/sockio.h presence... no
checking for sys/sockio.h... no
checking sys/tas.h usability... no
checking sys/tas.h presence... no
checking for sys/tas.h... no
checking sys/un.h usability... yes
checking sys/un.h presence... yes
checking for sys/un.h... yes
checking termios.h usability... yes
checking termios.h presence... yes
checking for termios.h... yes
checking ucred.h usability... no
checking ucred.h presence... no
checking for ucred.h... no
checking wctype.h usability... yes
checking wctype.h presence... yes
checking for wctype.h... yes
checking for net/if.h... yes
checking for sys/ucred.h... no
checking for netinet/tcp.h... yes
checking readline/readline.h usability... yes
checking readline/readline.h presence... yes
checking for readline/readline.h... yes
checking readline/history.h usability... yes
checking readline/history.h presence... yes
checking for readline/history.h... yes
checking zlib.h usability... yes
checking zlib.h presence... yes
checking for zlib.h... yes
checking whether byte ordering is bigendian... no
checking for inline... inline
checking for printf format archetype... gnu_printf
checking for __func__... yes
checking for _Static_assert... yes
checking for typeof... typeof
checking for __builtin_types_compatible_p... yes
checking for __builtin_constant_p... yes
checking for __builtin_unreachable... yes
checking for computed goto support... yes
checking for struct tm.tm_zone... yes
checking for union semun... no
checking for struct sockaddr_un... yes
checking for struct sockaddr_storage... yes
checking for struct sockaddr_storage.ss_family... yes
checking for struct sockaddr_storage.__ss_family... no
checking for struct sockaddr_storage.ss_len... no
checking for struct sockaddr_storage.__ss_len... no
checking for struct sockaddr.sa_len... no
checking for struct addrinfo... yes
checking for locale_t... yes
checking for C/C++ restrict keyword... __restrict
checking for struct cmsgcred... no
checking for struct option... yes
checking for z_streamp... yes
checking whether assembler supports x86_64 popcntq... yes
checking for special C compiler options needed for large files... no
checking for _FILE_OFFSET_BITS value needed for large files... no
checking size of off_t... 8
checking size of bool... 1
checking for int timezone... yes
checking types of arguments for accept()... int, int, struct sockaddr *, socklen_t *
checking whether gettimeofday takes only one argument... no
checking for wcstombs_l declaration... no
checking for backtrace_symbols... yes
checking for clock_gettime... yes
checking for copyfile... no
checking for fdatasync... yes
checking for getifaddrs... yes
checking for getpeerucred... no
checking for getrlimit... yes
checking for kqueue... no
checking for mbstowcs_l... no
checking for memset_s... no
checking for poll... yes
checking for posix_fallocate... yes
checking for ppoll... yes
checking for pstat... no
checking for pthread_is_threaded_np... no
checking for readlink... yes
checking for setproctitle... no
checking for setproctitle_fast... no
checking for setsid... yes
checking for shm_open... yes
checking for strchrnul... yes
checking for strsignal... yes
checking for symlink... yes
checking for sync_file_range... yes
checking for uselocale... yes
checking for wcstombs_l... no
checking for __builtin_bswap16... yes
checking for __builtin_bswap32... yes
checking for __builtin_bswap64... yes
checking for __builtin_clz... yes
checking for __builtin_ctz... yes
checking for __builtin_popcount... yes
checking for _LARGEFILE_SOURCE value needed for large files... no
checking how gcc -std=gnu99 reports undeclared, standard C functions... error
checking for posix_fadvise... yes
checking whether posix_fadvise is declared... yes
checking whether fdatasync is declared... yes
checking whether strlcat is declared... no
checking whether strlcpy is declared... no
checking whether strnlen is declared... yes
checking whether F_FULLFSYNC is declared... no
checking whether RTLD_GLOBAL is declared... yes
checking whether RTLD_NOW is declared... yes
checking for struct sockaddr_in6... yes
checking for PS_STRINGS... no
checking for dlopen... yes
checking for explicit_bzero... no
checking for fls... no
checking for getopt... yes
checking for getpeereid... no
checking for getrusage... yes
checking for inet_aton... yes
checking for link... yes
checking for mkdtemp... yes
checking for pread... yes
checking for pwrite... yes
checking for random... yes
checking for srandom... yes
checking for strlcat... no
checking for strlcpy... no
checking for strnlen... yes
checking for strtof... yes
checking for unsetenv... yes
checking for getaddrinfo... yes
checking for getopt_long... yes
checking for syslog... yes
checking syslog.h usability... yes
checking syslog.h presence... yes
checking for syslog.h... yes
checking for opterr... yes
checking for optreset... no
checking for strtoll... yes
checking for strtoull... yes
checking whether strtoll is declared... yes
checking whether strtoull is declared... yes
checking for rl_completion_append_character... yes
checking for rl_completion_suppress_quote... yes
checking for rl_filename_quote_characters... yes
checking for rl_filename_quoting_function... yes
checking for rl_completion_matches... yes
checking for rl_filename_completion_function... yes
checking for rl_reset_screen_size... yes
checking for append_history... yes
checking for history_truncate_file... yes
checking test program... ok
checking whether long int is 64 bits... yes
checking for __builtin_mul_overflow... no
checking size of void *... 8
checking size of size_t... 8
checking size of long... 8
checking alignment of short... 2
checking alignment of int... 4
checking alignment of long... 8
checking alignment of double... 8
checking for int8... no
checking for uint8... no
checking for int64... no
checking for uint64... no
checking for __int128... yes
checking for __int128 alignment bug... ok
checking alignment of PG_INT128_TYPE... 16
checking for builtin __sync char locking functions... yes
checking for builtin __sync int32 locking functions... yes
checking for builtin __sync int32 atomic operations... yes
checking for builtin __sync int64 atomic operations... yes
checking for builtin __atomic int32 atomic operations... yes
checking for builtin __atomic int64 atomic operations... yes
checking for __get_cpuid... yes
checking for __cpuid... no
checking for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=... no
checking for _mm_crc32_u8 and _mm_crc32_u32 with CFLAGS=-msse4.2... yes
checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=... no
checking for __crc32cb, __crc32ch, __crc32cw, and __crc32cd with CFLAGS=-march=armv8-a+crc... no
checking which CRC-32C implementation to use... SSE 4.2 with runtime check
checking for library containing sem_init... -lpthread
checking which semaphore API to use... unnamed POSIX
checking for /dev/urandom... yes
checking which random number source to use... /dev/urandom
checking for xmllint... /usr/bin/xmllint
checking for xsltproc... /usr/bin/xsltproc
checking for fop... no
checking for dbtoepub... no
checking thread safety of required library functions... yes
checking whether gcc -std=gnu99 supports -Wl,--as-needed... yes
configure: using compiler=gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44.0.3)
configure: using CFLAGS=-Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2
configure: using CPPFLAGS= -D_GNU_SOURCE
configure: using LDFLAGS=  -Wl,--as-needed
configure: creating ./config.status
config.status: creating GNUmakefile
config.status: creating src/Makefile.global
config.status: creating src/include/pg_config.h
config.status: creating src/include/pg_config_ext.h
config.status: creating src/interfaces/ecpg/include/ecpg_config.h
config.status: linking src/backend/port/tas/dummy.s to src/backend/port/tas.s
config.status: linking src/backend/port/posix_sema.c to src/backend/port/pg_sema.c
config.status: linking src/backend/port/sysv_shmem.c to src/backend/port/pg_shmem.c
config.status: linking src/include/port/linux.h to src/include/pg_config_os.h
config.status: linking src/makefiles/Makefile.linux to src/Makefile.port
[root@pcs1 postgresql-13.3]#


7. Build postgreSQL using make command

[root@pcs1 postgresql-13.3]#
[root@pcs1 postgresql-13.3]# ls -ltr
total 1216
-rw-r--r--.  1 1107 1107   1213 May 11  2021 README
-rw-r--r--.  1 1107 1107   1665 May 11  2021 Makefile  -------
-rw-r--r--.  1 1107 1107    277 May 11  2021 HISTORY
-rw-r--r--.  1 1107 1107   4278 May 11  2021 GNUmakefile.in
-rw-r--r--.  1 1107 1107   1192 May 11  2021 COPYRIGHT
-rw-r--r--.  1 1107 1107  82388 May 11  2021 configure.in
-rwxr-xr-x.  1 1107 1107 568656 May 11  2021 configure
-rw-r--r--.  1 1107 1107    490 May 11  2021 aclocal.m4
drwxrwxrwx. 57 1107 1107   4096 May 11  2021 contrib
drwxrwxrwx.  2 1107 1107   4096 May 11  2021 config
drwxrwxrwx.  3 1107 1107     87 May 11  2021 doc
-rw-r--r--.  1 1107 1107  63684 May 11  2021 INSTALL
-rwxr-xr-x.  1 root root  40104 Dec 23 00:40 config.status
-rw-r--r--.  1 root root   4278 Dec 23 00:40 GNUmakefile
drwxrwxrwx. 16 1107 1107   4096 Dec 23 00:40 src
-rw-r--r--.  1 root root 433580 Dec 23 00:40 config.log
[root@pcs1 postgresql-13.3]#
[root@pcs1 postgresql-13.3]# which make
/usr/bin/make
[root@pcs1 postgresql-13.3]#
[root@pcs1 postgresql-13.3]# make
..
..
..
make -C test/perl all
make[2]: Entering directory `/root/postgresql-13.3/src/test/perl'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/root/postgresql-13.3/src/test/perl'
make[1]: Leaving directory `/root/postgresql-13.3/src'
make -C config all
make[1]: Entering directory `/root/postgresql-13.3/config'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/root/postgresql-13.3/config'
All of PostgreSQL successfully made. Ready to install.   <---------------------
[root@pcs1 postgresql-13.3]#


8. Install postgreSQL using make install command

[root@pcs1 postgresql-13.3]# pwd
/root/postgresql-13.3
[root@pcs1 postgresql-13.3]# ls -ltr /u01/app/postgres/13.3/
total 0   <--------
[root@pcs1 postgresql-13.3]#
[root@pcs1 postgresql-13.3]# make install
make -C ./src/backend generated-headers
make[1]: Entering directory `/root/postgresql-13.3/src/backend'
make -C catalog distprep generated-header-symlinks
make[2]: Entering directory `/root/postgresql-13.3/src/backend/catalog'
make[2]: Nothing to be done for `distprep'.
make[2]: Nothing to be done for `generated-header-symlinks'.
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/catalog'
make -C utils distprep generated-header-symlinks
make[2]: Entering directory `/root/postgresql-13.3/src/backend/utils'
make[2]: Nothing to be done for `distprep'.
make[2]: Nothing to be done for `generated-header-symlinks'.
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/utils'
make[1]: Leaving directory `/root/postgresql-13.3/src/backend'
make -C src install
make[1]: Entering directory `/root/postgresql-13.3/src'
make -C common install
make[2]: Entering directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644  libpgcommon.a '/u01/app/postgres/13.3/lib/libpgcommon.a'
/usr/bin/install -c -m 644  libpgcommon_shlib.a '/u01/app/postgres/13.3/lib/libpgcommon_shlib.a'
make[2]: Leaving directory `/root/postgresql-13.3/src/common'
make -C port install
make[2]: Entering directory `/root/postgresql-13.3/src/port'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644  libpgport.a '/u01/app/postgres/13.3/lib/libpgport.a'
/usr/bin/install -c -m 644  libpgport_shlib.a '/u01/app/postgres/13.3/lib/libpgport_shlib.a'
make[2]: Leaving directory `/root/postgresql-13.3/src/port'
make -C timezone install
make[2]: Entering directory `/root/postgresql-13.3/src/timezone'
make -C ../../src/port all
make[3]: Entering directory `/root/postgresql-13.3/src/port'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../src/common all
make[3]: Entering directory `/root/postgresql-13.3/src/common'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share'
./zic -d '/u01/app/postgres/13.3/share/timezone'  ./data/tzdata.zi
make -C tznames install
make[3]: Entering directory `/root/postgresql-13.3/src/timezone/tznames'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/timezonesets'
/usr/bin/install -c -m 644 ./Africa.txt ./America.txt ./Antarctica.txt ./Asia.txt ./Atlantic.txt ./Australia.txt ./Etc.txt ./Europe.txt ./Indian.txt ./Pacific.txt '/u01/app/postgres/13.3/share/timezonesets'
/usr/bin/install -c -m 644 ./Default ./Australia ./India '/u01/app/postgres/13.3/share/timezonesets'
make[3]: Leaving directory `/root/postgresql-13.3/src/timezone/tznames'
make[2]: Leaving directory `/root/postgresql-13.3/src/timezone'
make -C backend install
make[2]: Entering directory `/root/postgresql-13.3/src/backend'
make -C ../../src/port all
make[3]: Entering directory `/root/postgresql-13.3/src/port'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../src/common all
make[3]: Entering directory `/root/postgresql-13.3/src/common'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/common'
make -C catalog distprep generated-header-symlinks
make[3]: Entering directory `/root/postgresql-13.3/src/backend/catalog'
make[3]: Nothing to be done for `distprep'.
make[3]: Nothing to be done for `generated-header-symlinks'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/catalog'
make -C utils distprep generated-header-symlinks
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils'
make[3]: Nothing to be done for `distprep'.
make[3]: Nothing to be done for `generated-header-symlinks'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils'
make -C access all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/access'
make -C brin all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/brin'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/brin'
make -C common all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/common'
make -C gin all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/gin'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/gin'
make -C gist all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/gist'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/gist'
make -C hash all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/hash'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/hash'
make -C heap all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/heap'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/heap'
make -C index all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/index'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/index'
make -C nbtree all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/nbtree'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/nbtree'
make -C rmgrdesc all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/rmgrdesc'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/rmgrdesc'
make -C spgist all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/spgist'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/spgist'
make -C table all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/table'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/table'
make -C tablesample all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/tablesample'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/tablesample'
make -C transam all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/transam'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/transam'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/access'
make -C bootstrap all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/bootstrap'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/bootstrap'
make -C catalog all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/catalog'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/catalog'
make -C parser all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/parser'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/parser'
make -C commands all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/commands'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/commands'
make -C executor all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/executor'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/executor'
make -C foreign all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/foreign'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/foreign'
make -C lib all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/lib'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/lib'
make -C libpq all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/libpq'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/libpq'
make -C main all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/main'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/main'
make -C nodes all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/nodes'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/nodes'
make -C optimizer all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/optimizer'
make -C geqo all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/geqo'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/geqo'
make -C path all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/path'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/path'
make -C plan all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/plan'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/plan'
make -C prep all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/prep'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/prep'
make -C util all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/util'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/util'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer'
make -C partitioning all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/partitioning'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/partitioning'
make -C port all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/port'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/port'
make -C postmaster all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/postmaster'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/postmaster'
make -C regex all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/regex'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/regex'
make -C replication all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/replication'
make -C logical all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/replication/logical'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/replication/logical'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/replication'
make -C rewrite all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/rewrite'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/rewrite'
make -C statistics all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/statistics'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/statistics'
make -C storage all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/storage'
make -C buffer all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/buffer'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/buffer'
make -C file all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/file'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/file'
make -C freespace all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/freespace'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/freespace'
make -C ipc all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/ipc'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/ipc'
make -C large_object all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/large_object'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/large_object'
make -C lmgr all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/lmgr'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/lmgr'
make -C page all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/page'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/page'
make -C smgr all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/smgr'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/smgr'
make -C sync all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/sync'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/sync'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/storage'
make -C tcop all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/tcop'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/tcop'
make -C tsearch all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/tsearch'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/tsearch'
make -C utils all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils'
make -C adt all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/adt'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/adt'
make -C cache all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/cache'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/cache'
make -C error all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/error'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/error'
make -C fmgr all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/fmgr'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/fmgr'
make -C hash all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/hash'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/hash'
make -C init all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/init'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/init'
make -C mb all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb'
make -C misc all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/misc'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/misc'
make -C mmgr all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/mmgr'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mmgr'
make -C resowner all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/resowner'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/resowner'
make -C sort all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/sort'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/sort'
make -C time all
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/time'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/time'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils'
make -C ../../src/timezone all
make[3]: Entering directory `/root/postgresql-13.3/src/timezone'
make -C ../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make[3]: Leaving directory `/root/postgresql-13.3/src/timezone'
make -C jit all
make[3]: Entering directory `/root/postgresql-13.3/src/backend/jit'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/jit'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin' '/u01/app/postgres/13.3/share'
/usr/bin/install -c  postgres '/u01/app/postgres/13.3/bin/postgres'
ln -s postgres '/u01/app/postgres/13.3/bin/postmaster'
make -C access install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/access'
make -C brin install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/brin'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/brin'
make -C common install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/common'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/common'
make -C gin install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/gin'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/gin'
make -C gist install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/gist'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/gist'
make -C hash install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/hash'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/hash'
make -C heap install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/heap'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/heap'
make -C index install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/index'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/index'
make -C nbtree install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/nbtree'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/nbtree'
make -C rmgrdesc install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/rmgrdesc'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/rmgrdesc'
make -C spgist install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/spgist'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/spgist'
make -C table install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/table'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/table'
make -C tablesample install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/tablesample'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/tablesample'
make -C transam install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/access/transam'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/access/transam'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/access'
make -C bootstrap install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/bootstrap'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/bootstrap'
make -C catalog install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/catalog'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/catalog'
make -C parser install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/parser'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/parser'
make -C commands install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/commands'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/commands'
make -C executor install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/executor'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/executor'
make -C foreign install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/foreign'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/foreign'
make -C lib install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/lib'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/lib'
make -C libpq install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/libpq'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/libpq'
make -C main install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/main'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/main'
make -C nodes install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/nodes'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/nodes'
make -C optimizer install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/optimizer'
make -C geqo install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/geqo'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/geqo'
make -C path install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/path'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/path'
make -C plan install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/plan'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/plan'
make -C prep install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/prep'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/prep'
make -C util install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/optimizer/util'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer/util'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/optimizer'
make -C partitioning install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/partitioning'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/partitioning'
make -C port install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/port'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/port'
make -C postmaster install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/postmaster'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/postmaster'
make -C regex install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/regex'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/regex'
make -C replication install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/replication'
make -C logical install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/replication/logical'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/replication/logical'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/replication'
make -C rewrite install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/rewrite'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/rewrite'
make -C statistics install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/statistics'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/statistics'
make -C storage install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/storage'
make -C buffer install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/buffer'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/buffer'
make -C file install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/file'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/file'
make -C freespace install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/freespace'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/freespace'
make -C ipc install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/ipc'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/ipc'
make -C large_object install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/large_object'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/large_object'
make -C lmgr install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/lmgr'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/lmgr'
make -C page install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/page'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/page'
make -C smgr install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/smgr'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/smgr'
make -C sync install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/storage/sync'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/storage/sync'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/storage'
make -C tcop install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/tcop'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/tcop'
make -C tsearch install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/tsearch'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/tsearch'
make -C utils install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils'
make -C adt install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/adt'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/adt'
make -C cache install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/cache'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/cache'
make -C error install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/error'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/error'
make -C fmgr install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/fmgr'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/fmgr'
make -C hash install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/hash'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/hash'
make -C init install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/init'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/init'
make -C mb install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb'
make -C misc install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/misc'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/misc'
make -C mmgr install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/mmgr'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mmgr'
make -C resowner install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/resowner'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/resowner'
make -C sort install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/sort'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/sort'
make -C time install
make[4]: Entering directory `/root/postgresql-13.3/src/backend/utils/time'
make[4]: Nothing to be done for `install'.
make[4]: Leaving directory `/root/postgresql-13.3/src/backend/utils/time'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils'
make -C ../../src/timezone install
make[3]: Entering directory `/root/postgresql-13.3/src/timezone'
make -C ../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share'
./zic -d '/u01/app/postgres/13.3/share/timezone'  ./data/tzdata.zi
make -C tznames install
make[4]: Entering directory `/root/postgresql-13.3/src/timezone/tznames'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/timezonesets'
/usr/bin/install -c -m 644 ./Africa.txt ./America.txt ./Antarctica.txt ./Asia.txt ./Atlantic.txt ./Australia.txt ./Etc.txt ./Europe.txt ./Indian.txt ./Pacific.txt '/u01/app/postgres/13.3/share/timezonesets'
/usr/bin/install -c -m 644 ./Default ./Australia ./India '/u01/app/postgres/13.3/share/timezonesets'
make[4]: Leaving directory `/root/postgresql-13.3/src/timezone/tznames'
make[3]: Leaving directory `/root/postgresql-13.3/src/timezone'
make -C jit install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/jit'
make[3]: Nothing to be done for `install'.
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/jit'
make -C catalog install-data
make[3]: Entering directory `/root/postgresql-13.3/src/backend/catalog'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share'
/usr/bin/install -c -m 644 `for f in ./postgres.bki; do test -r $f && echo $f && break; done` '/u01/app/postgres/13.3/share/postgres.bki'
/usr/bin/install -c -m 644 ./system_views.sql '/u01/app/postgres/13.3/share/system_views.sql'
/usr/bin/install -c -m 644 ./information_schema.sql '/u01/app/postgres/13.3/share/information_schema.sql'
/usr/bin/install -c -m 644 ./sql_features.txt '/u01/app/postgres/13.3/share/sql_features.txt'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/catalog'
make -C tsearch install-data
make[3]: Entering directory `/root/postgresql-13.3/src/backend/tsearch'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share' '/u01/app/postgres/13.3/share/tsearch_data'
/usr/bin/install -c -m 644 ./dicts/synonym_sample.syn ./dicts/thesaurus_sample.ths ./dicts/hunspell_sample.affix ./dicts/ispell_sample.affix ./dicts/ispell_sample.dict ./dicts/hunspell_sample_long.affix ./dicts/hunspell_sample_long.dict ./dicts/hunspell_sample_num.affix ./dicts/hunspell_sample_num.dict '/u01/app/postgres/13.3/share/tsearch_data/'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/tsearch'
make -C utils install-data
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share'
/usr/bin/install -c -m 644 ./errcodes.txt '/u01/app/postgres/13.3/share/errcodes.txt'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils'
/usr/bin/install -c -m 644 ./libpq/pg_hba.conf.sample '/u01/app/postgres/13.3/share/pg_hba.conf.sample'
/usr/bin/install -c -m 644 ./libpq/pg_ident.conf.sample '/u01/app/postgres/13.3/share/pg_ident.conf.sample'
/usr/bin/install -c -m 644 ./utils/misc/postgresql.conf.sample '/u01/app/postgres/13.3/share/postgresql.conf.sample'
make[2]: Leaving directory `/root/postgresql-13.3/src/backend'
make -C backend/utils/mb/conversion_procs install
make[2]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs'
make -C cyrillic_and_mic install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/cyrillic_and_mic'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  cyrillic_and_mic.so '/u01/app/postgres/13.3/lib/cyrillic_and_mic.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/cyrillic_and_mic'
make -C euc_cn_and_mic install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc_cn_and_mic'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  euc_cn_and_mic.so '/u01/app/postgres/13.3/lib/euc_cn_and_mic.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc_cn_and_mic'
make -C euc_jp_and_sjis install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  euc_jp_and_sjis.so '/u01/app/postgres/13.3/lib/euc_jp_and_sjis.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc_jp_and_sjis'
make -C euc_kr_and_mic install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc_kr_and_mic'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  euc_kr_and_mic.so '/u01/app/postgres/13.3/lib/euc_kr_and_mic.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc_kr_and_mic'
make -C euc_tw_and_big5 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc_tw_and_big5'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  euc_tw_and_big5.so '/u01/app/postgres/13.3/lib/euc_tw_and_big5.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc_tw_and_big5'
make -C latin2_and_win1250 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/latin2_and_win1250'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  latin2_and_win1250.so '/u01/app/postgres/13.3/lib/latin2_and_win1250.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/latin2_and_win1250'
make -C latin_and_mic install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/latin_and_mic'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  latin_and_mic.so '/u01/app/postgres/13.3/lib/latin_and_mic.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/latin_and_mic'
make -C utf8_and_big5 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_big5'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_big5.so '/u01/app/postgres/13.3/lib/utf8_and_big5.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_big5'
make -C utf8_and_cyrillic install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_cyrillic.so '/u01/app/postgres/13.3/lib/utf8_and_cyrillic.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_cyrillic'
make -C utf8_and_euc_cn install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_euc_cn.so '/u01/app/postgres/13.3/lib/utf8_and_euc_cn.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_cn'
make -C utf8_and_euc_jp install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_euc_jp.so '/u01/app/postgres/13.3/lib/utf8_and_euc_jp.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_jp'
make -C utf8_and_euc_kr install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_euc_kr.so '/u01/app/postgres/13.3/lib/utf8_and_euc_kr.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_kr'
make -C utf8_and_euc_tw install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_euc_tw.so '/u01/app/postgres/13.3/lib/utf8_and_euc_tw.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc_tw'
make -C utf8_and_gb18030 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_gb18030'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_gb18030.so '/u01/app/postgres/13.3/lib/utf8_and_gb18030.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_gb18030'
make -C utf8_and_gbk install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_gbk'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_gbk.so '/u01/app/postgres/13.3/lib/utf8_and_gbk.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_gbk'
make -C utf8_and_iso8859 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_iso8859'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_iso8859.so '/u01/app/postgres/13.3/lib/utf8_and_iso8859.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_iso8859'
make -C utf8_and_iso8859_1 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_iso8859_1.so '/u01/app/postgres/13.3/lib/utf8_and_iso8859_1.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1'
make -C utf8_and_johab install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_johab'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_johab.so '/u01/app/postgres/13.3/lib/utf8_and_johab.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_johab'
make -C utf8_and_sjis install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_sjis'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_sjis.so '/u01/app/postgres/13.3/lib/utf8_and_sjis.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_sjis'
make -C utf8_and_win install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_win'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_win.so '/u01/app/postgres/13.3/lib/utf8_and_win.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_win'
make -C utf8_and_uhc install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_uhc'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_uhc.so '/u01/app/postgres/13.3/lib/utf8_and_uhc.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_uhc'
make -C utf8_and_euc2004 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc2004'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_euc2004.so '/u01/app/postgres/13.3/lib/utf8_and_euc2004.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_euc2004'
make -C utf8_and_sjis2004 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  utf8_and_sjis2004.so '/u01/app/postgres/13.3/lib/utf8_and_sjis2004.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/utf8_and_sjis2004'
make -C euc2004_sjis2004 install
make[3]: Entering directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc2004_sjis2004'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  euc2004_sjis2004.so '/u01/app/postgres/13.3/lib/euc2004_sjis2004.so'
make[3]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs/euc2004_sjis2004'
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/utils/mb/conversion_procs'
make -C backend/snowball install
make[2]: Entering directory `/root/postgresql-13.3/src/backend/snowball'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share' '/u01/app/postgres/13.3/share/tsearch_data'
/usr/bin/install -c -m 755  dict_snowball.so '/u01/app/postgres/13.3/lib/dict_snowball.so'
/usr/bin/install -c -m 644 snowball_create.sql '/u01/app/postgres/13.3/share'
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/snowball'
make -C include install
make[2]: Entering directory `/root/postgresql-13.3/src/include'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include/libpq' '/u01/app/postgres/13.3/include/internal/libpq'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include/server'/access '/u01/app/postgres/13.3/include/server'/bootstrap '/u01/app/postgres/13.3/include/server'/catalog '/u01/app/postgres/13.3/include/server'/commands '/u01/app/postgres/13.3/include/server'/common '/u01/app/postgres/13.3/include/server'/datatype '/u01/app/postgres/13.3/include/server'/executor '/u01/app/postgres/13.3/include/server'/fe_utils '/u01/app/postgres/13.3/include/server'/foreign '/u01/app/postgres/13.3/include/server'/jit '/u01/app/postgres/13.3/include/server'/lib '/u01/app/postgres/13.3/include/server'/libpq '/u01/app/postgres/13.3/include/server'/mb '/u01/app/postgres/13.3/include/server'/nodes '/u01/app/postgres/13.3/include/server'/optimizer '/u01/app/postgres/13.3/include/server'/parser '/u01/app/postgres/13.3/include/server'/partitioning '/u01/app/postgres/13.3/include/server'/postmaster '/u01/app/postgres/13.3/include/server'/regex '/u01/app/postgres/13.3/include/server'/replication '/u01/app/postgres/13.3/include/server'/rewrite '/u01/app/postgres/13.3/include/server'/statistics '/u01/app/postgres/13.3/include/server'/storage '/u01/app/postgres/13.3/include/server'/tcop '/u01/app/postgres/13.3/include/server'/snowball '/u01/app/postgres/13.3/include/server'/snowball/libstemmer '/u01/app/postgres/13.3/include/server'/tsearch '/u01/app/postgres/13.3/include/server'/tsearch/dicts '/u01/app/postgres/13.3/include/server'/utils '/u01/app/postgres/13.3/include/server'/port '/u01/app/postgres/13.3/include/server'/port/atomics '/u01/app/postgres/13.3/include/server'/port/win32 '/u01/app/postgres/13.3/include/server'/port/win32_msvc '/u01/app/postgres/13.3/include/server'/port/win32_msvc/sys '/u01/app/postgres/13.3/include/server'/port/win32/arpa '/u01/app/postgres/13.3/include/server'/port/win32/netinet '/u01/app/postgres/13.3/include/server'/port/win32/sys '/u01/app/postgres/13.3/include/server'/portability
/usr/bin/install -c -m 644 ./postgres_ext.h   '/u01/app/postgres/13.3/include'
/usr/bin/install -c -m 644 ./libpq/libpq-fs.h '/u01/app/postgres/13.3/include/libpq'
/usr/bin/install -c -m 644 pg_config.h     '/u01/app/postgres/13.3/include'
/usr/bin/install -c -m 644 pg_config_ext.h '/u01/app/postgres/13.3/include'
/usr/bin/install -c -m 644 pg_config_os.h  '/u01/app/postgres/13.3/include'
/usr/bin/install -c -m 644 ./pg_config_manual.h '/u01/app/postgres/13.3/include'
/usr/bin/install -c -m 644 ./c.h            '/u01/app/postgres/13.3/include/internal'
/usr/bin/install -c -m 644 ./port.h         '/u01/app/postgres/13.3/include/internal'
/usr/bin/install -c -m 644 ./postgres_fe.h  '/u01/app/postgres/13.3/include/internal'
/usr/bin/install -c -m 644 ./libpq/pqcomm.h '/u01/app/postgres/13.3/include/internal/libpq'
/usr/bin/install -c -m 644 pg_config.h     '/u01/app/postgres/13.3/include/server'
/usr/bin/install -c -m 644 pg_config_ext.h '/u01/app/postgres/13.3/include/server'
/usr/bin/install -c -m 644 pg_config_os.h  '/u01/app/postgres/13.3/include/server'
/usr/bin/install -c -m 644 utils/errcodes.h '/u01/app/postgres/13.3/include/server/utils'
/usr/bin/install -c -m 644 utils/fmgroids.h '/u01/app/postgres/13.3/include/server/utils'
/usr/bin/install -c -m 644 utils/fmgrprotos.h '/u01/app/postgres/13.3/include/server/utils'
cp ./*.h '/u01/app/postgres/13.3/include/server'/
for dir in access bootstrap catalog commands common datatype executor fe_utils foreign jit lib libpq mb nodes optimizer parser partitioning postmaster regex replication rewrite statistics storage tcop snowball snowball/libstemmer tsearch tsearch/dicts utils port port/atomics port/win32 port/win32_msvc port/win32_msvc/sys port/win32/arpa port/win32/netinet port/win32/sys portability; do \
  cp ./$dir/*.h '/u01/app/postgres/13.3/include/server'/$dir/ || exit; \
done
cd '/u01/app/postgres/13.3/include/server' && chmod 644 *.h
for dir in access bootstrap catalog commands common datatype executor fe_utils foreign jit lib libpq mb nodes optimizer parser partitioning postmaster regex replication rewrite statistics storage tcop snowball snowball/libstemmer tsearch tsearch/dicts utils port port/atomics port/win32 port/win32_msvc port/win32_msvc/sys port/win32/arpa port/win32/netinet port/win32/sys portability; do \
  cd '/u01/app/postgres/13.3/include/server'/$dir || exit; \
  chmod 644 *.h || exit; \
done
make[2]: Leaving directory `/root/postgresql-13.3/src/include'
make -C interfaces install
make[2]: Entering directory `/root/postgresql-13.3/src/interfaces'
make -C libpq install
make[3]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib' '/u01/app/postgres/13.3/lib/pkgconfig'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include' '/u01/app/postgres/13.3/include/internal' '/u01/app/postgres/13.3/share'
/usr/bin/install -c -m 755  libpq.so.5.13 '/u01/app/postgres/13.3/lib/libpq.so.5.13'
cd '/u01/app/postgres/13.3/lib' && \
rm -f libpq.so.5 && \
ln -s libpq.so.5.13 libpq.so.5
cd '/u01/app/postgres/13.3/lib' && \
rm -f libpq.so && \
ln -s libpq.so.5.13 libpq.so
/usr/bin/install -c -m 644  libpq.a '/u01/app/postgres/13.3/lib/libpq.a'
/usr/bin/install -c -m 644 libpq.pc '/u01/app/postgres/13.3/lib/pkgconfig/libpq.pc'
/usr/bin/install -c -m 644 ./libpq-fe.h '/u01/app/postgres/13.3/include'
/usr/bin/install -c -m 644 ./libpq-events.h '/u01/app/postgres/13.3/include'
/usr/bin/install -c -m 644 ./libpq-int.h '/u01/app/postgres/13.3/include/internal'
/usr/bin/install -c -m 644 ./pqexpbuffer.h '/u01/app/postgres/13.3/include/internal'
/usr/bin/install -c -m 644 ./pg_service.conf.sample '/u01/app/postgres/13.3/share/pg_service.conf.sample'
make[3]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ecpg install
make[3]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg'
make -C include install
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/include'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include' '/u01/app/postgres/13.3/include/informix/esql'
/usr/bin/install -c -m 644 ./ecpgerrno.h ./ecpglib.h ./ecpgtype.h ./sqlca.h ./sql3types.h ./ecpg_informix.h ./pgtypes_error.h ./pgtypes_numeric.h ./pgtypes_timestamp.h ./pgtypes_date.h ./pgtypes_interval.h ./pgtypes.h ./sqlda.h ./sqlda-compat.h ./sqlda-native.h '/u01/app/postgres/13.3/include/'
/usr/bin/install -c -m 644 ./datetime.h ./decimal.h ./sqltypes.h '/u01/app/postgres/13.3/include/informix/esql/'
/usr/bin/install -c -m 644 ../../../../src/interfaces/ecpg/include/ecpg_config.h '/u01/app/postgres/13.3/include'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/include'
make -C pgtypeslib install
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/pgtypeslib'
make -C ../../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib' '/u01/app/postgres/13.3/lib/pkgconfig'
/usr/bin/install -c -m 755  libpgtypes.so.3.13 '/u01/app/postgres/13.3/lib/libpgtypes.so.3.13'
cd '/u01/app/postgres/13.3/lib' && \
rm -f libpgtypes.so.3 && \
ln -s libpgtypes.so.3.13 libpgtypes.so.3
cd '/u01/app/postgres/13.3/lib' && \
rm -f libpgtypes.so && \
ln -s libpgtypes.so.3.13 libpgtypes.so
/usr/bin/install -c -m 644  libpgtypes.a '/u01/app/postgres/13.3/lib/libpgtypes.a'
/usr/bin/install -c -m 644 libpgtypes.pc '/u01/app/postgres/13.3/lib/pkgconfig/libpgtypes.pc'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/pgtypeslib'
make -C ecpglib install
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/ecpglib'
make -C ../../../../src/interfaces/libpq all
make[5]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[6]: Entering directory `/root/postgresql-13.3/src/port'
make[6]: Nothing to be done for `all'.
make[6]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[6]: Entering directory `/root/postgresql-13.3/src/common'
make[6]: Nothing to be done for `all'.
make[6]: Leaving directory `/root/postgresql-13.3/src/common'
make[5]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../../src/interfaces/ecpg/pgtypeslib all
make[5]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/pgtypeslib'
make -C ../../../../src/port all
make[6]: Entering directory `/root/postgresql-13.3/src/port'
make[6]: Nothing to be done for `all'.
make[6]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../../src/common all
make[6]: Entering directory `/root/postgresql-13.3/src/common'
make[6]: Nothing to be done for `all'.
make[6]: Leaving directory `/root/postgresql-13.3/src/common'
make[5]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/pgtypeslib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib' '/u01/app/postgres/13.3/lib/pkgconfig'
/usr/bin/install -c -m 755  libecpg.so.6.13 '/u01/app/postgres/13.3/lib/libecpg.so.6.13'
cd '/u01/app/postgres/13.3/lib' && \
rm -f libecpg.so.6 && \
ln -s libecpg.so.6.13 libecpg.so.6
cd '/u01/app/postgres/13.3/lib' && \
rm -f libecpg.so && \
ln -s libecpg.so.6.13 libecpg.so
/usr/bin/install -c -m 644  libecpg.a '/u01/app/postgres/13.3/lib/libecpg.a'
/usr/bin/install -c -m 644 libecpg.pc '/u01/app/postgres/13.3/lib/pkgconfig/libecpg.pc'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/ecpglib'
make -C compatlib install
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/compatlib'
make -C ../../../../src/interfaces/ecpg/ecpglib all
make[5]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/ecpglib'
make -C ../../../../src/interfaces/libpq all
make[6]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[7]: Entering directory `/root/postgresql-13.3/src/port'
make[7]: Nothing to be done for `all'.
make[7]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[7]: Entering directory `/root/postgresql-13.3/src/common'
make[7]: Nothing to be done for `all'.
make[7]: Leaving directory `/root/postgresql-13.3/src/common'
make[6]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../../src/interfaces/ecpg/pgtypeslib all
make[6]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/pgtypeslib'
make -C ../../../../src/port all
make[7]: Entering directory `/root/postgresql-13.3/src/port'
make[7]: Nothing to be done for `all'.
make[7]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../../src/common all
make[7]: Entering directory `/root/postgresql-13.3/src/common'
make[7]: Nothing to be done for `all'.
make[7]: Leaving directory `/root/postgresql-13.3/src/common'
make[6]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/pgtypeslib'
make[5]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/ecpglib'
make -C ../../../../src/interfaces/ecpg/pgtypeslib all
make[5]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/pgtypeslib'
make -C ../../../../src/port all
make[6]: Entering directory `/root/postgresql-13.3/src/port'
make[6]: Nothing to be done for `all'.
make[6]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../../src/common all
make[6]: Entering directory `/root/postgresql-13.3/src/common'
make[6]: Nothing to be done for `all'.
make[6]: Leaving directory `/root/postgresql-13.3/src/common'
make[5]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/pgtypeslib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib' '/u01/app/postgres/13.3/lib/pkgconfig'
/usr/bin/install -c -m 755  libecpg_compat.so.3.13 '/u01/app/postgres/13.3/lib/libecpg_compat.so.3.13'
cd '/u01/app/postgres/13.3/lib' && \
rm -f libecpg_compat.so.3 && \
ln -s libecpg_compat.so.3.13 libecpg_compat.so.3
cd '/u01/app/postgres/13.3/lib' && \
rm -f libecpg_compat.so && \
ln -s libecpg_compat.so.3.13 libecpg_compat.so
/usr/bin/install -c -m 644  libecpg_compat.a '/u01/app/postgres/13.3/lib/libecpg_compat.a'
/usr/bin/install -c -m 644 libecpg_compat.pc '/u01/app/postgres/13.3/lib/pkgconfig/libecpg_compat.pc'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/compatlib'
make -C preproc install
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/ecpg/preproc'
make -C ../../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  ecpg '/u01/app/postgres/13.3/bin'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg/preproc'
make[3]: Leaving directory `/root/postgresql-13.3/src/interfaces/ecpg'
make[2]: Leaving directory `/root/postgresql-13.3/src/interfaces'
make -C backend/replication/libpqwalreceiver install
make[2]: Entering directory `/root/postgresql-13.3/src/backend/replication/libpqwalreceiver'
make -C ../../../../src/interfaces/libpq all
make[3]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make[3]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  libpqwalreceiver.so '/u01/app/postgres/13.3/lib/libpqwalreceiver.so'
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/replication/libpqwalreceiver'
make -C backend/replication/pgoutput install
make[2]: Entering directory `/root/postgresql-13.3/src/backend/replication/pgoutput'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  pgoutput.so '/u01/app/postgres/13.3/lib/pgoutput.so'
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/replication/pgoutput'
make -C fe_utils install
make[2]: Entering directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644  libpgfeutils.a '/u01/app/postgres/13.3/lib/libpgfeutils.a'
make[2]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
make -C bin install
make[2]: Entering directory `/root/postgresql-13.3/src/bin'
make -C initdb install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/initdb'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/fe_utils all
make[4]: Entering directory `/root/postgresql-13.3/src/fe_utils'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  initdb '/u01/app/postgres/13.3/bin/initdb'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/initdb'
make -C pg_archivecleanup install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_archivecleanup'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_archivecleanup '/u01/app/postgres/13.3/bin/pg_archivecleanup'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_archivecleanup'
make -C pg_basebackup install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_basebackup'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/fe_utils all
make[4]: Entering directory `/root/postgresql-13.3/src/fe_utils'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_basebackup '/u01/app/postgres/13.3/bin/pg_basebackup'
/usr/bin/install -c  pg_receivewal '/u01/app/postgres/13.3/bin/pg_receivewal'
/usr/bin/install -c  pg_recvlogical '/u01/app/postgres/13.3/bin/pg_recvlogical'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_basebackup'
make -C pg_checksums install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_checksums'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_checksums '/u01/app/postgres/13.3/bin/pg_checksums'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_checksums'
make -C pg_config install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_config'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c -m 755 pg_config '/u01/app/postgres/13.3/bin/pg_config'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_config'
make -C pg_controldata install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_controldata'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_controldata '/u01/app/postgres/13.3/bin/pg_controldata'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_controldata'
make -C pg_ctl install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_ctl'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_ctl '/u01/app/postgres/13.3/bin/pg_ctl'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_ctl'
make -C pg_dump install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_dump'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/fe_utils all
make[4]: Entering directory `/root/postgresql-13.3/src/fe_utils'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_dump '/u01/app/postgres/13.3/bin'/pg_dump
/usr/bin/install -c  pg_restore '/u01/app/postgres/13.3/bin'/pg_restore
/usr/bin/install -c  pg_dumpall '/u01/app/postgres/13.3/bin'/pg_dumpall
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_dump'
make -C pg_resetwal install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_resetwal'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_resetwal '/u01/app/postgres/13.3/bin/pg_resetwal'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_resetwal'
make -C pg_rewind install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_rewind'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_rewind '/u01/app/postgres/13.3/bin/pg_rewind'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_rewind'
make -C pg_test_fsync install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_test_fsync'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_test_fsync '/u01/app/postgres/13.3/bin/pg_test_fsync'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_test_fsync'
make -C pg_test_timing install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_test_timing'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_test_timing '/u01/app/postgres/13.3/bin/pg_test_timing'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_test_timing'
make -C pg_upgrade install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_upgrade'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/fe_utils all
make[4]: Entering directory `/root/postgresql-13.3/src/fe_utils'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_upgrade '/u01/app/postgres/13.3/bin/pg_upgrade'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_upgrade'
make -C pg_verifybackup install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_verifybackup'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/fe_utils all
make[4]: Entering directory `/root/postgresql-13.3/src/fe_utils'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_verifybackup '/u01/app/postgres/13.3/bin/pg_verifybackup'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_verifybackup'
make -C pg_waldump install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pg_waldump'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_waldump '/u01/app/postgres/13.3/bin/pg_waldump'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pg_waldump'
make -C pgbench install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/pgbench'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/fe_utils all
make[4]: Entering directory `/root/postgresql-13.3/src/fe_utils'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pgbench '/u01/app/postgres/13.3/bin/pgbench'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/pgbench'
make -C psql install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/psql'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/fe_utils all
make[4]: Entering directory `/root/postgresql-13.3/src/fe_utils'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin' '/u01/app/postgres/13.3/share'
/usr/bin/install -c  psql '/u01/app/postgres/13.3/bin/psql'
/usr/bin/install -c -m 644 ./psqlrc.sample '/u01/app/postgres/13.3/share/psqlrc.sample'
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/psql'
make -C scripts install
make[3]: Entering directory `/root/postgresql-13.3/src/bin/scripts'
make -C ../../../src/interfaces/libpq all
make[4]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[5]: Entering directory `/root/postgresql-13.3/src/port'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[5]: Entering directory `/root/postgresql-13.3/src/common'
make[5]: Nothing to be done for `all'.
make[5]: Leaving directory `/root/postgresql-13.3/src/common'
make[4]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../src/fe_utils all
make[4]: Entering directory `/root/postgresql-13.3/src/fe_utils'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/fe_utils'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  createdb   '/u01/app/postgres/13.3/bin'/createdb
/usr/bin/install -c  dropdb     '/u01/app/postgres/13.3/bin'/dropdb
/usr/bin/install -c  createuser '/u01/app/postgres/13.3/bin'/createuser
/usr/bin/install -c  dropuser   '/u01/app/postgres/13.3/bin'/dropuser
/usr/bin/install -c  clusterdb  '/u01/app/postgres/13.3/bin'/clusterdb
/usr/bin/install -c  vacuumdb   '/u01/app/postgres/13.3/bin'/vacuumdb
/usr/bin/install -c  reindexdb  '/u01/app/postgres/13.3/bin'/reindexdb
/usr/bin/install -c  pg_isready '/u01/app/postgres/13.3/bin'/pg_isready
make[3]: Leaving directory `/root/postgresql-13.3/src/bin/scripts'
make[2]: Leaving directory `/root/postgresql-13.3/src/bin'
make -C pl install
make[2]: Entering directory `/root/postgresql-13.3/src/pl'
make -C plpgsql install
make[3]: Entering directory `/root/postgresql-13.3/src/pl/plpgsql'
make -C src install
make[4]: Entering directory `/root/postgresql-13.3/src/pl/plpgsql/src'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  plpgsql.so '/u01/app/postgres/13.3/lib/plpgsql.so'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include/server'
/usr/bin/install -c -m 644 ./plpgsql.control ./plpgsql--1.0.sql '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 './plpgsql.h' '/u01/app/postgres/13.3/include/server'
make[4]: Leaving directory `/root/postgresql-13.3/src/pl/plpgsql/src'
make[3]: Leaving directory `/root/postgresql-13.3/src/pl/plpgsql'
make[2]: Leaving directory `/root/postgresql-13.3/src/pl'
make -C makefiles install
make[2]: Entering directory `/root/postgresql-13.3/src/makefiles'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib/pgxs/src/makefiles'
/usr/bin/install -c -m 644 ./pgxs.mk '/u01/app/postgres/13.3/lib/pgxs/src/makefiles/'
make[2]: Leaving directory `/root/postgresql-13.3/src/makefiles'
make -C test/regress install
make[2]: Entering directory `/root/postgresql-13.3/src/test/regress'
make -C ../../../src/port all
make[3]: Entering directory `/root/postgresql-13.3/src/port'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[3]: Entering directory `/root/postgresql-13.3/src/common'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/common'
make -C ../../../contrib/spi
make[3]: Entering directory `/root/postgresql-13.3/contrib/spi'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/contrib/spi'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib/pgxs/src/test/regress'
/usr/bin/install -c  pg_regress '/u01/app/postgres/13.3/lib/pgxs/src/test/regress/pg_regress'
make[2]: Leaving directory `/root/postgresql-13.3/src/test/regress'
make -C test/isolation install
make[2]: Entering directory `/root/postgresql-13.3/src/test/isolation'
make -C ../../../src/interfaces/libpq all
make[3]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[4]: Entering directory `/root/postgresql-13.3/src/port'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[4]: Entering directory `/root/postgresql-13.3/src/common'
make[4]: Nothing to be done for `all'.
make[4]: Leaving directory `/root/postgresql-13.3/src/common'
make[3]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[3]: Entering directory `/root/postgresql-13.3/src/port'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[3]: Entering directory `/root/postgresql-13.3/src/common'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/common'
make[2]: Leaving directory `/root/postgresql-13.3/src/test/isolation'
make -C test/perl install
make[2]: Entering directory `/root/postgresql-13.3/src/test/perl'
make[2]: Nothing to be done for `install'.
make[2]: Leaving directory `/root/postgresql-13.3/src/test/perl'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib/pgxs/src'
/usr/bin/install -c -m 644 Makefile.global '/u01/app/postgres/13.3/lib/pgxs/src/Makefile.global'
/usr/bin/install -c -m 644 Makefile.port '/u01/app/postgres/13.3/lib/pgxs/src/Makefile.port'
/usr/bin/install -c -m 644 ./Makefile.shlib '/u01/app/postgres/13.3/lib/pgxs/src/Makefile.shlib'
/usr/bin/install -c -m 644 ./nls-global.mk '/u01/app/postgres/13.3/lib/pgxs/src/nls-global.mk'
make[1]: Leaving directory `/root/postgresql-13.3/src'
make -C config install
make[1]: Entering directory `/root/postgresql-13.3/config'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib/pgxs/config'
/usr/bin/install -c -m 755 ./install-sh '/u01/app/postgres/13.3/lib/pgxs/config/install-sh'
/usr/bin/install -c -m 755 ./missing '/u01/app/postgres/13.3/lib/pgxs/config/missing'
make[1]: Leaving directory `/root/postgresql-13.3/config'
PostgreSQL installation complete.  <-----
[root@pcs1 postgresql-13.3]#

[root@pcs1 postgresql-13.3]# ls -ltr /u01/app/postgres/13.3/
total 16
drwxr-xr-x. 6 root root 4096 Dec 23 01:01 include
drwxr-xr-x. 2 root root 4096 Dec 23 01:01 bin
drwxr-xr-x. 6 root root 4096 Dec 23 01:01 share
drwxr-xr-x. 4 root root 4096 Dec 23 01:01 lib
[root@pcs1 postgresql-13.3]#


9. Build contrib module using make command (optional)

[root@pcs1 postgresql-13.3]# pwd
/root/postgresql-13.3
[root@pcs1 postgresql-13.3]#

[root@pcs1 postgresql-13.3]# ls -ltr
total 1216
-rw-r--r--.  1 1107 1107   1213 May 11  2021 README
-rw-r--r--.  1 1107 1107   1665 May 11  2021 Makefile
-rw-r--r--.  1 1107 1107    277 May 11  2021 HISTORY
-rw-r--r--.  1 1107 1107   4278 May 11  2021 GNUmakefile.in
-rw-r--r--.  1 1107 1107   1192 May 11  2021 COPYRIGHT
-rw-r--r--.  1 1107 1107  82388 May 11  2021 configure.in
-rwxr-xr-x.  1 1107 1107 568656 May 11  2021 configure
-rw-r--r--.  1 1107 1107    490 May 11  2021 aclocal.m4
drwxrwxrwx. 57 1107 1107   4096 May 11  2021 contrib
drwxrwxrwx.  2 1107 1107   4096 May 11  2021 config
drwxrwxrwx.  3 1107 1107     87 May 11  2021 doc
-rw-r--r--.  1 1107 1107  63684 May 11  2021 INSTALL
-rwxr-xr-x.  1 root root  40104 Dec 23 00:40 config.status
-rw-r--r--.  1 root root   4278 Dec 23 00:40 GNUmakefile
drwxrwxrwx. 16 1107 1107   4096 Dec 23 00:40 src
-rw-r--r--.  1 root root 433580 Dec 23 00:40 config.log
[root@pcs1 postgresql-13.3]# cd contrib/
[root@pcs1 contrib]# ls -ltr
total 196
-rw-r--r--. 1 1107 1107 1131 May 11  2021 README
-rw-r--r--. 1 1107 1107 1461 May 11  2021 Makefile
-rw-r--r--. 1 1107 1107   85 May 11  2021 contrib-global.mk
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 unaccent
drwxrwxrwx. 2 1107 1107   74 May 11  2021 tcn
drwxrwxrwx. 2 1107 1107 4096 May 11  2021 sslinfo
drwxrwxrwx. 2 1107 1107   60 May 11  2021 pg_standby
drwxrwxrwx. 2 1107 1107 4096 May 11  2021 pg_prewarm
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 hstore
drwxrwxrwx. 6 1107 1107 4096 May 11  2021 dblink
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 bool_plperl
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 adminpack
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 xml2
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 tsm_system_time
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 tsm_system_rows
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 test_decoding
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 tablefunc
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 sepgsql
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 pg_visibility
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 pg_trgm
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 pgstattuple
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 pg_stat_statements
drwxrwxrwx. 2 1107 1107 4096 May 11  2021 pg_freespacemap
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 pgcrypto
drwxrwxrwx. 4 1107 1107   90 May 11  2021 passwordcheck
drwxrwxrwx. 3 1107 1107   67 May 11  2021 oid2name
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 ltree_plpython
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 ltree
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 lo
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 jsonb_plpython
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 jsonb_plperl
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 isn
drwxrwxrwx. 6 1107 1107 4096 May 11  2021 intarray
drwxrwxrwx. 2 1107 1107   95 May 11  2021 intagg
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 hstore_plpython
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 hstore_plperl
drwxrwxrwx. 7 1107 1107 4096 May 11  2021 file_fdw
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 dict_xsyn
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 citext
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 btree_gist
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 btree_gin
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 bloom
drwxrwxrwx. 2 1107 1107   44 May 11  2021 auto_explain
drwxrwxrwx. 2 1107 1107   42 May 11  2021 auth_delay
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 amcheck
drwxrwxrwx. 3 1107 1107   67 May 11  2021 vacuumlo
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 uuid-ossp
drwxrwxrwx. 3 1107 1107   47 May 11  2021 start-scripts
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 postgres_fdw
drwxrwxrwx. 2 1107 1107 4096 May 11  2021 pgrowlocks
drwxrwxrwx. 2 1107 1107 4096 May 11  2021 pg_buffercache
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 pageinspect
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 fuzzystrmatch
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 earthdistance
drwxrwxrwx. 4 1107 1107 4096 May 11  2021 dict_int
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 seg
drwxrwxrwx. 5 1107 1107 4096 May 11  2021 cube
drwxrwxrwx. 2 1107 1107 4096 Dec 23 00:54 spi
[root@pcs1 contrib]#
[root@pcs1 contrib]# make
make -C ../src/backend generated-headers
make[1]: Entering directory `/root/postgresql-13.3/src/backend'
make -C catalog distprep generated-header-symlinks
make[2]: Entering directory `/root/postgresql-13.3/src/backend/catalog'
make[2]: Nothing to be done for `distprep'.
make[2]: Nothing to be done for `generated-header-symlinks'.
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/catalog'
make -C utils distprep generated-header-symlinks
make[2]: Entering directory `/root/postgresql-13.3/src/backend/utils'
make[2]: Nothing to be done for `distprep'.
make[2]: Nothing to be done for `generated-header-symlinks'.
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/utils'
make[1]: Leaving directory `/root/postgresql-13.3/src/backend'
make -C adminpack all
make[1]: Entering directory `/root/postgresql-13.3/contrib/adminpack'
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -I../../src/interfaces/libpq -I. -I. -I../../src/include  -D_GNU_SOURCE   -c -o adminpack.o adminpack.c
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -shared -o adminpack.so  adminpack.o -L../../src/port -L../../src/common    -Wl,--as-needed -Wl,-rpath,'/u01/app/postgres/13.3/lib',--enable-new-dtags
make[1]: Leaving directory `/root/postgresql-13.3/contrib/adminpack'
make -C amcheck all
make[1]: Entering directory `/root/postgresql-13.3/contrib/amcheck'
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -I. -I. -I../../src/include  -D_GNU_SOURCE   -c -o verify_nbtree.o verify_nbtree.c
..
..
..
make[1]: Entering directory `/root/postgresql-13.3/contrib/unaccent'
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -I. -I. -I../../src/include  -D_GNU_SOURCE   -c -o unaccent.o unaccent.c
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -fPIC -shared -o unaccent.so  unaccent.o -L../../src/port -L../../src/common    -Wl,--as-needed -Wl,-rpath,'/u01/app/postgres/13.3/lib',--enable-new-dtags
make[1]: Leaving directory `/root/postgresql-13.3/contrib/unaccent'
make -C vacuumlo all
make[1]: Entering directory `/root/postgresql-13.3/contrib/vacuumlo'
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2 -I../../src/interfaces/libpq -I. -I. -I../../src/include  -D_GNU_SOURCE   -c -o vacuumlo.o vacuumlo.c
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2  vacuumlo.o -L../../src/common -lpgcommon -L../../src/port -lpgport -L../../src/interfaces/libpq -lpq -L../../src/port -L../../src/common   -Wl,--as-needed -Wl,-rpath,'/u01/app/postgres/13.3/lib',--enable-new-dtags   -lpgcommon -lpgport -lpthread -lz -lreadline -lrt -ldl -lm  -o vacuumlo
make[1]: Leaving directory `/root/postgresql-13.3/contrib/vacuumlo'
[root@pcs1 contrib]#


10. Install contrib module using make install command (optional)

[root@pcs1 contrib]# pwd
/root/postgresql-13.3/contrib
[root@pcs1 contrib]#
[root@pcs1 contrib]# make install
make -C ../src/backend generated-headers
make[1]: Entering directory `/root/postgresql-13.3/src/backend'
make -C catalog distprep generated-header-symlinks
make[2]: Entering directory `/root/postgresql-13.3/src/backend/catalog'
make[2]: Nothing to be done for `distprep'.
make[2]: Nothing to be done for `generated-header-symlinks'.
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/catalog'
make -C utils distprep generated-header-symlinks
make[2]: Entering directory `/root/postgresql-13.3/src/backend/utils'
make[2]: Nothing to be done for `distprep'.
make[2]: Nothing to be done for `generated-header-symlinks'.
make[2]: Leaving directory `/root/postgresql-13.3/src/backend/utils'
make[1]: Leaving directory `/root/postgresql-13.3/src/backend'
make -C adminpack install
make[1]: Entering directory `/root/postgresql-13.3/contrib/adminpack'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  adminpack.so '/u01/app/postgres/13.3/lib/adminpack.so'
/usr/bin/install -c -m 644 ./adminpack.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./adminpack--1.0.sql ./adminpack--1.0--1.1.sql ./adminpack--1.1--2.0.sql ./adminpack--2.0--2.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/adminpack'
make -C amcheck install
make[1]: Entering directory `/root/postgresql-13.3/contrib/amcheck'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  amcheck.so '/u01/app/postgres/13.3/lib/amcheck.so'
/usr/bin/install -c -m 644 ./amcheck.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./amcheck--1.1--1.2.sql ./amcheck--1.0--1.1.sql ./amcheck--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/amcheck'
make -C auth_delay install
make[1]: Entering directory `/root/postgresql-13.3/contrib/auth_delay'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  auth_delay.so '/u01/app/postgres/13.3/lib/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/auth_delay'
make -C auto_explain install
make[1]: Entering directory `/root/postgresql-13.3/contrib/auto_explain'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  auto_explain.so '/u01/app/postgres/13.3/lib/auto_explain.so'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/auto_explain'
make -C bloom install
make[1]: Entering directory `/root/postgresql-13.3/contrib/bloom'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  bloom.so '/u01/app/postgres/13.3/lib/bloom.so'
/usr/bin/install -c -m 644 ./bloom.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./bloom--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/bloom'
make -C btree_gin install
make[1]: Entering directory `/root/postgresql-13.3/contrib/btree_gin'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  btree_gin.so '/u01/app/postgres/13.3/lib/btree_gin.so'
/usr/bin/install -c -m 644 ./btree_gin.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./btree_gin--1.0.sql ./btree_gin--1.0--1.1.sql ./btree_gin--1.1--1.2.sql ./btree_gin--1.2--1.3.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/btree_gin'
make -C btree_gist install
make[1]: Entering directory `/root/postgresql-13.3/contrib/btree_gist'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  btree_gist.so '/u01/app/postgres/13.3/lib/btree_gist.so'
/usr/bin/install -c -m 644 ./btree_gist.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./btree_gist--1.0--1.1.sql ./btree_gist--1.1--1.2.sql ./btree_gist--1.2.sql ./btree_gist--1.2--1.3.sql ./btree_gist--1.3--1.4.sql ./btree_gist--1.4--1.5.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/btree_gist'
make -C citext install
make[1]: Entering directory `/root/postgresql-13.3/contrib/citext'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644 ./citext.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./citext--1.4.sql ./citext--1.5--1.6.sql ./citext--1.4--1.5.sql ./citext--1.3--1.4.sql ./citext--1.2--1.3.sql ./citext--1.1--1.2.sql ./citext--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 755  citext.so '/u01/app/postgres/13.3/lib/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/citext'
make -C cube install
make[1]: Entering directory `/root/postgresql-13.3/contrib/cube'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  cube.so '/u01/app/postgres/13.3/lib/cube.so'
/usr/bin/install -c -m 644 ./cube.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./cube--1.2.sql ./cube--1.2--1.3.sql ./cube--1.3--1.4.sql ./cube--1.1--1.2.sql ./cube--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include/server/extension/cube/'
/usr/bin/install -c -m 644   ./cubedata.h '/u01/app/postgres/13.3/include/server/extension/cube/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/cube'
make -C dblink install
make[1]: Entering directory `/root/postgresql-13.3/contrib/dblink'
make -C ../../src/interfaces/libpq all
make[2]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[3]: Entering directory `/root/postgresql-13.3/src/port'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[3]: Entering directory `/root/postgresql-13.3/src/common'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/common'
make[2]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  dblink.so '/u01/app/postgres/13.3/lib/dblink.so'
/usr/bin/install -c -m 644 ./dblink.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./dblink--1.2.sql ./dblink--1.1--1.2.sql ./dblink--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/dblink'
make -C dict_int install
make[1]: Entering directory `/root/postgresql-13.3/contrib/dict_int'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  dict_int.so '/u01/app/postgres/13.3/lib/dict_int.so'
/usr/bin/install -c -m 644 ./dict_int.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./dict_int--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/dict_int'
make -C dict_xsyn install
make[1]: Entering directory `/root/postgresql-13.3/contrib/dict_xsyn'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/tsearch_data'
/usr/bin/install -c -m 755  dict_xsyn.so '/u01/app/postgres/13.3/lib/dict_xsyn.so'
/usr/bin/install -c -m 644 ./dict_xsyn.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./dict_xsyn--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./xsyn_sample.rules '/u01/app/postgres/13.3/share/tsearch_data/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/dict_xsyn'
make -C earthdistance install
make[1]: Entering directory `/root/postgresql-13.3/contrib/earthdistance'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644 ./earthdistance.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./earthdistance--1.1.sql ./earthdistance--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 755  earthdistance.so '/u01/app/postgres/13.3/lib/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/earthdistance'
make -C file_fdw install
make[1]: Entering directory `/root/postgresql-13.3/contrib/file_fdw'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644 ./file_fdw.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./file_fdw--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 755  file_fdw.so '/u01/app/postgres/13.3/lib/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/file_fdw'
make -C fuzzystrmatch install
make[1]: Entering directory `/root/postgresql-13.3/contrib/fuzzystrmatch'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  fuzzystrmatch.so '/u01/app/postgres/13.3/lib/fuzzystrmatch.so'
/usr/bin/install -c -m 644 ./fuzzystrmatch.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./fuzzystrmatch--1.1.sql ./fuzzystrmatch--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/fuzzystrmatch'
make -C hstore install
make[1]: Entering directory `/root/postgresql-13.3/contrib/hstore'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  hstore.so '/u01/app/postgres/13.3/lib/hstore.so'
/usr/bin/install -c -m 644 ./hstore.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./hstore--1.4.sql ./hstore--1.6--1.7.sql ./hstore--1.5--1.6.sql ./hstore--1.4--1.5.sql ./hstore--1.3--1.4.sql ./hstore--1.2--1.3.sql ./hstore--1.1--1.2.sql ./hstore--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include/server/extension/hstore/'
/usr/bin/install -c -m 644   ./hstore.h '/u01/app/postgres/13.3/include/server/extension/hstore/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/hstore'
make -C intagg install
make[1]: Entering directory `/root/postgresql-13.3/contrib/intagg'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 644 ./intagg.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./intagg--1.1.sql ./intagg--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/intagg'
make -C intarray install
make[1]: Entering directory `/root/postgresql-13.3/contrib/intarray'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  _int.so '/u01/app/postgres/13.3/lib/_int.so'
/usr/bin/install -c -m 644 ./intarray.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./intarray--1.2--1.3.sql ./intarray--1.2.sql ./intarray--1.1--1.2.sql ./intarray--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/intarray'
make -C isn install
make[1]: Entering directory `/root/postgresql-13.3/contrib/isn'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644 ./isn.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./isn--1.1.sql ./isn--1.1--1.2.sql ./isn--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 755  isn.so '/u01/app/postgres/13.3/lib/'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include/server/extension/isn/'
/usr/bin/install -c -m 644  ./isn.h '/u01/app/postgres/13.3/include/server/extension/isn/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/isn'
make -C lo install
make[1]: Entering directory `/root/postgresql-13.3/contrib/lo'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644 ./lo.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./lo--1.1.sql ./lo--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 755  lo.so '/u01/app/postgres/13.3/lib/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/lo'
make -C ltree install
make[1]: Entering directory `/root/postgresql-13.3/contrib/ltree'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  ltree.so '/u01/app/postgres/13.3/lib/ltree.so'
/usr/bin/install -c -m 644 ./ltree.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./ltree--1.1--1.2.sql ./ltree--1.1.sql ./ltree--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include/server/extension/ltree/'
/usr/bin/install -c -m 644   ./ltree.h '/u01/app/postgres/13.3/include/server/extension/ltree/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/ltree'
make -C oid2name install
make[1]: Entering directory `/root/postgresql-13.3/contrib/oid2name'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  oid2name '/u01/app/postgres/13.3/bin'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/oid2name'
make -C pageinspect install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pageinspect'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pageinspect.so '/u01/app/postgres/13.3/lib/pageinspect.so'
/usr/bin/install -c -m 644 ./pageinspect.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pageinspect--1.7--1.8.sql ./pageinspect--1.6--1.7.sql ./pageinspect--1.5.sql ./pageinspect--1.5--1.6.sql ./pageinspect--1.4--1.5.sql ./pageinspect--1.3--1.4.sql ./pageinspect--1.2--1.3.sql ./pageinspect--1.1--1.2.sql ./pageinspect--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pageinspect'
make -C passwordcheck install
make[1]: Entering directory `/root/postgresql-13.3/contrib/passwordcheck'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  passwordcheck.so '/u01/app/postgres/13.3/lib/passwordcheck.so'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/passwordcheck'
make -C pg_buffercache install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pg_buffercache'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pg_buffercache.so '/u01/app/postgres/13.3/lib/pg_buffercache.so'
/usr/bin/install -c -m 644 ./pg_buffercache.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pg_buffercache--1.2.sql ./pg_buffercache--1.2--1.3.sql ./pg_buffercache--1.1--1.2.sql ./pg_buffercache--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pg_buffercache'
make -C pg_freespacemap install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pg_freespacemap'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pg_freespacemap.so '/u01/app/postgres/13.3/lib/pg_freespacemap.so'
/usr/bin/install -c -m 644 ./pg_freespacemap.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pg_freespacemap--1.1.sql ./pg_freespacemap--1.1--1.2.sql ./pg_freespacemap--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pg_freespacemap'
make -C pg_prewarm install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pg_prewarm'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pg_prewarm.so '/u01/app/postgres/13.3/lib/pg_prewarm.so'
/usr/bin/install -c -m 644 ./pg_prewarm.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pg_prewarm--1.1--1.2.sql ./pg_prewarm--1.1.sql ./pg_prewarm--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pg_prewarm'
make -C pg_standby install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pg_standby'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  pg_standby '/u01/app/postgres/13.3/bin'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pg_standby'
make -C pg_stat_statements install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pg_stat_statements'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pg_stat_statements.so '/u01/app/postgres/13.3/lib/pg_stat_statements.so'
/usr/bin/install -c -m 644 ./pg_stat_statements.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pg_stat_statements--1.4.sql ./pg_stat_statements--1.7--1.8.sql ./pg_stat_statements--1.6--1.7.sql ./pg_stat_statements--1.5--1.6.sql ./pg_stat_statements--1.4--1.5.sql ./pg_stat_statements--1.3--1.4.sql ./pg_stat_statements--1.2--1.3.sql ./pg_stat_statements--1.1--1.2.sql ./pg_stat_statements--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pg_stat_statements'
make -C pg_trgm install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pg_trgm'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pg_trgm.so '/u01/app/postgres/13.3/lib/pg_trgm.so'
/usr/bin/install -c -m 644 ./pg_trgm.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pg_trgm--1.4--1.5.sql ./pg_trgm--1.3--1.4.sql ./pg_trgm--1.3.sql ./pg_trgm--1.2--1.3.sql ./pg_trgm--1.1--1.2.sql ./pg_trgm--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pg_trgm'
make -C pgcrypto install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pgcrypto'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pgcrypto.so '/u01/app/postgres/13.3/lib/pgcrypto.so'
/usr/bin/install -c -m 644 ./pgcrypto.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pgcrypto--1.3.sql ./pgcrypto--1.2--1.3.sql ./pgcrypto--1.1--1.2.sql ./pgcrypto--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pgcrypto'
make -C pgrowlocks install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pgrowlocks'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pgrowlocks.so '/u01/app/postgres/13.3/lib/pgrowlocks.so'
/usr/bin/install -c -m 644 ./pgrowlocks.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pgrowlocks--1.2.sql ./pgrowlocks--1.1--1.2.sql ./pgrowlocks--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pgrowlocks'
make -C pgstattuple install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pgstattuple'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pgstattuple.so '/u01/app/postgres/13.3/lib/pgstattuple.so'
/usr/bin/install -c -m 644 ./pgstattuple.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pgstattuple--1.4.sql ./pgstattuple--1.4--1.5.sql ./pgstattuple--1.3--1.4.sql ./pgstattuple--1.2--1.3.sql ./pgstattuple--1.1--1.2.sql ./pgstattuple--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pgstattuple'
make -C pg_visibility install
make[1]: Entering directory `/root/postgresql-13.3/contrib/pg_visibility'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  pg_visibility.so '/u01/app/postgres/13.3/lib/pg_visibility.so'
/usr/bin/install -c -m 644 ./pg_visibility.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./pg_visibility--1.1.sql ./pg_visibility--1.1--1.2.sql ./pg_visibility--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/pg_visibility'
make -C postgres_fdw install
make[1]: Entering directory `/root/postgresql-13.3/contrib/postgres_fdw'
make -C ../../src/interfaces/libpq all
make[2]: Entering directory `/root/postgresql-13.3/src/interfaces/libpq'
make -C ../../../src/port all
make[3]: Entering directory `/root/postgresql-13.3/src/port'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/port'
make -C ../../../src/common all
make[3]: Entering directory `/root/postgresql-13.3/src/common'
make[3]: Nothing to be done for `all'.
make[3]: Leaving directory `/root/postgresql-13.3/src/common'
make[2]: Leaving directory `/root/postgresql-13.3/src/interfaces/libpq'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  postgres_fdw.so '/u01/app/postgres/13.3/lib/postgres_fdw.so'
/usr/bin/install -c -m 644 ./postgres_fdw.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./postgres_fdw--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/postgres_fdw'
make -C seg install
make[1]: Entering directory `/root/postgresql-13.3/contrib/seg'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  seg.so '/u01/app/postgres/13.3/lib/seg.so'
/usr/bin/install -c -m 644 ./seg.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./seg--1.1.sql ./seg--1.1--1.2.sql ./seg--1.2--1.3.sql ./seg--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/include/server/extension/seg/'
/usr/bin/install -c -m 644   ./segdata.h '/u01/app/postgres/13.3/include/server/extension/seg/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/seg'
make -C spi install
make[1]: Entering directory `/root/postgresql-13.3/contrib/spi'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/doc//extension'
/usr/bin/install -c -m 644 ./autoinc.control ./insert_username.control ./moddatetime.control ./refint.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./autoinc--1.0.sql ./insert_username--1.0.sql ./moddatetime--1.0.sql ./refint--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 755  autoinc.so insert_username.so moddatetime.so refint.so '/u01/app/postgres/13.3/lib/'
/usr/bin/install -c -m 644 ./autoinc.example ./insert_username.example ./moddatetime.example ./refint.example '/u01/app/postgres/13.3/share/doc//extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/spi'
make -C tablefunc install
make[1]: Entering directory `/root/postgresql-13.3/contrib/tablefunc'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644 ./tablefunc.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./tablefunc--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 755  tablefunc.so '/u01/app/postgres/13.3/lib/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/tablefunc'
make -C tcn install
make[1]: Entering directory `/root/postgresql-13.3/contrib/tcn'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 644 ./tcn.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./tcn--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 755  tcn.so '/u01/app/postgres/13.3/lib/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/tcn'
make -C test_decoding install
make[1]: Entering directory `/root/postgresql-13.3/contrib/test_decoding'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/install -c -m 755  test_decoding.so '/u01/app/postgres/13.3/lib/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/test_decoding'
make -C tsm_system_rows install
make[1]: Entering directory `/root/postgresql-13.3/contrib/tsm_system_rows'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  tsm_system_rows.so '/u01/app/postgres/13.3/lib/tsm_system_rows.so'
/usr/bin/install -c -m 644 ./tsm_system_rows.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./tsm_system_rows--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/tsm_system_rows'
make -C tsm_system_time install
make[1]: Entering directory `/root/postgresql-13.3/contrib/tsm_system_time'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/install -c -m 755  tsm_system_time.so '/u01/app/postgres/13.3/lib/tsm_system_time.so'
/usr/bin/install -c -m 644 ./tsm_system_time.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./tsm_system_time--1.0.sql  '/u01/app/postgres/13.3/share/extension/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/tsm_system_time'
make -C unaccent install
make[1]: Entering directory `/root/postgresql-13.3/contrib/unaccent'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/lib'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/extension'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/share/tsearch_data'
/usr/bin/install -c -m 755  unaccent.so '/u01/app/postgres/13.3/lib/unaccent.so'
/usr/bin/install -c -m 644 ./unaccent.control '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./unaccent--1.1.sql ./unaccent--1.0--1.1.sql  '/u01/app/postgres/13.3/share/extension/'
/usr/bin/install -c -m 644 ./unaccent.rules '/u01/app/postgres/13.3/share/tsearch_data/'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/unaccent'
make -C vacuumlo install
make[1]: Entering directory `/root/postgresql-13.3/contrib/vacuumlo'
/usr/bin/mkdir -p '/u01/app/postgres/13.3/bin'
/usr/bin/install -c  vacuumlo '/u01/app/postgres/13.3/bin'
make[1]: Leaving directory `/root/postgresql-13.3/contrib/vacuumlo'
[root@pcs1 contrib]#


11. Validation

[root@pcs1 ~]# cd /u01/app/postgres/13.3/bin/
[root@pcs1 bin]# ls -ltr
total 12760
-rwxr-xr-x. 1 root root 8289176 Dec 23 01:01 postgres
lrwxrwxrwx. 1 root root       8 Dec 23 01:01 postmaster -> postgres
-rwxr-xr-x. 1 root root  972200 Dec 23 01:01 ecpg
-rwxr-xr-x. 1 root root  142688 Dec 23 01:01 initdb
-rwxr-xr-x. 1 root root   48696 Dec 23 01:01 pg_archivecleanup
-rwxr-xr-x. 1 root root  131440 Dec 23 01:01 pg_basebackup
-rwxr-xr-x. 1 root root   93464 Dec 23 01:01 pg_receivewal
-rwxr-xr-x. 1 root root   94040 Dec 23 01:01 pg_recvlogical
-rwxr-xr-x. 1 root root   67240 Dec 23 01:01 pg_checksums
-rwxr-xr-x. 1 root root   43136 Dec 23 01:01 pg_config
-rwxr-xr-x. 1 root root   61632 Dec 23 01:01 pg_controldata
-rwxr-xr-x. 1 root root   77280 Dec 23 01:01 pg_ctl
-rwxr-xr-x. 1 root root  431760 Dec 23 01:01 pg_dump
-rwxr-xr-x. 1 root root  192456 Dec 23 01:01 pg_restore
-rwxr-xr-x. 1 root root  114352 Dec 23 01:01 pg_dumpall
-rwxr-xr-x. 1 root root   71696 Dec 23 01:01 pg_resetwal
-rwxr-xr-x. 1 root root  138560 Dec 23 01:01 pg_rewind
-rwxr-xr-x. 1 root root   49424 Dec 23 01:01 pg_test_fsync
-rwxr-xr-x. 1 root root   43504 Dec 23 01:01 pg_test_timing
-rwxr-xr-x. 1 root root  154184 Dec 23 01:01 pg_upgrade
-rwxr-xr-x. 1 root root  109792 Dec 23 01:01 pg_verifybackup
-rwxr-xr-x. 1 root root  108760 Dec 23 01:01 pg_waldump
-rwxr-xr-x. 1 root root  174008 Dec 23 01:01 pgbench
-rwxr-xr-x. 1 root root  630160 Dec 23 01:01 psql
-rwxr-xr-x. 1 root root   82840 Dec 23 01:01 createdb
-rwxr-xr-x. 1 root root   73680 Dec 23 01:01 dropdb
-rwxr-xr-x. 1 root root   79088 Dec 23 01:01 createuser
-rwxr-xr-x. 1 root root   73616 Dec 23 01:01 dropuser
-rwxr-xr-x. 1 root root   78584 Dec 23 01:01 clusterdb
-rwxr-xr-x. 1 root root   87648 Dec 23 01:01 vacuumdb
-rwxr-xr-x. 1 root root   83432 Dec 23 01:01 reindexdb
-rwxr-xr-x. 1 root root   73664 Dec 23 01:01 pg_isready
-rwxr-xr-x. 1 root root   48776 Dec 23 01:15 oid2name
-rwxr-xr-x. 1 root root   43720 Dec 23 01:15 pg_standby
-rwxr-xr-x. 1 root root   48488 Dec 23 01:15 vacuumlo
[root@pcs1 bin]# ./pg_config
BINDIR = /u01/app/postgres/13.3/bin
DOCDIR = /u01/app/postgres/13.3/share/doc
HTMLDIR = /u01/app/postgres/13.3/share/doc
INCLUDEDIR = /u01/app/postgres/13.3/include
PKGINCLUDEDIR = /u01/app/postgres/13.3/include
INCLUDEDIR-SERVER = /u01/app/postgres/13.3/include/server
LIBDIR = /u01/app/postgres/13.3/lib
PKGLIBDIR = /u01/app/postgres/13.3/lib
LOCALEDIR = /u01/app/postgres/13.3/share/locale
MANDIR = /u01/app/postgres/13.3/share/man
SHAREDIR = /u01/app/postgres/13.3/share
SYSCONFDIR = /u01/app/postgres/13.3/etc
PGXS = /u01/app/postgres/13.3/lib/pgxs/src/makefiles/pgxs.mk
CONFIGURE =  '--prefix=/u01/app/postgres/13.3' '--with-pgport=5432'
CC = gcc -std=gnu99
CPPFLAGS = -D_GNU_SOURCE
CFLAGS = -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -O2
CFLAGS_SL = -fPIC
LDFLAGS = -Wl,--as-needed -Wl,-rpath,'/u01/app/postgres/13.3/lib',--enable-new-dtags
LDFLAGS_EX =
LDFLAGS_SL =
LIBS = -lpgcommon -lpgport -lpthread -lz -lreadline -lrt -ldl -lm
VERSION = PostgreSQL 13.3
[root@pcs1 bin]#

pg_config utility working fine.


12. Change binary owner to postgres

[root@pcs1 ~]# chown -R postgres:postgres /u02/app/psql/13.3/DATA
[root@pcs1 ~]# chown -R postgres:postgres /u01/app/postgres


13. Initialize postgreSQL data directory using postgres user

[root@pcs1 13.3]# su - postgres
[postgres@pcs1 ~]$
[postgres@pcs1 ~]$
[postgres@pcs1 ~]$ ps -ef | grep postgres
root      3098  1810  0 01:59 pts/1    00:00:00 su - postgres
postgres  3101  3098  0 01:59 pts/1    00:00:00 -bash
postgres  3183  3101  0 01:59 pts/1    00:00:00 ps -ef
postgres  3184  3101  0 01:59 pts/1    00:00:00 grep --color=auto postgres
[postgres@pcs1 ~]$
[postgres@pcs1 ~]$ /u01/app/postgres/13.3/bin/initdb -D /u02/app/psql/13.3/DATA
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

fixing permissions on existing directory /u02/app/psql/13.3/DATA ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... Asia/Singapore
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

initdb: warning: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    /u01/app/postgres/13.3/bin/pg_ctl -D /u02/app/psql/13.3/DATA -l logfile start

[postgres@pcs1 ~]$


14. Validate the postgreSQL data directory

[postgres@pcs1 postgres]$ cd /u02/app/psql/13.3/DATA/
[postgres@pcs1 DATA]$ ls -ltr
total 124
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_twophase
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_snapshots
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_serial
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_replslot
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_notify
drwx------. 4 postgres postgres  4096 Dec 23 01:59 pg_multixact
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_dynshmem
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_commit_ts
-rw-------. 1 postgres postgres     3 Dec 23 01:59 PG_VERSION
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_tblspc
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_stat
-rw-------. 1 postgres postgres 28025 Dec 23 01:59 postgresql.conf
-rw-------. 1 postgres postgres    88 Dec 23 01:59 postgresql.auto.conf
-rw-------. 1 postgres postgres  4760 Dec 23 01:59 pg_hba.conf
-rw-------. 1 postgres postgres  1636 Dec 23 01:59 pg_ident.conf
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_xact
drwx------. 3 postgres postgres  4096 Dec 23 01:59 pg_wal
drwx------. 2 postgres postgres  4096 Dec 23 01:59 pg_subtrans
drwx------. 2 postgres postgres  4096 Dec 23 01:59 global
drwx------. 5 postgres postgres  4096 Dec 23 01:59 base
-rw-------. 1 postgres postgres    67 Dec 23 02:05 postmaster.opts
-rw-------. 1 postgres postgres    89 Dec 23 02:05 postmaster.pid
drwx------. 4 postgres postgres  4096 Dec 23 02:10 pg_logical
drwx------. 2 postgres postgres  4096 Dec 23 03:21 pg_stat_tmp
[postgres@pcs1 DATA]$


15. Start postgreSQL database as postgres user

[postgres@pcs1 ~]$ /u01/app/postgres/13.3/bin/pg_ctl -D /u02/app/psql/13.3/DATA status
pg_ctl: no server running
[postgres@pcs1 ~]$
[postgres@pcs1 ~]$ /u01/app/postgres/13.3/bin/pg_ctl -D /u02/app/psql/13.3/DATA start
waiting for server to start....2021-12-23 02:05:49.529 +08 [3695] LOG:  starting PostgreSQL 13.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44.0.3), 64-bit
2021-12-23 02:05:49.532 +08 [3695] LOG:  listening on IPv6 address "::1", port 5432
2021-12-23 02:05:49.532 +08 [3695] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2021-12-23 02:05:49.537 +08 [3695] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2021-12-23 02:05:49.543 +08 [3696] LOG:  database system was shut down at 2021-12-23 01:59:40 +08
2021-12-23 02:05:49.548 +08 [3695] LOG:  database system is ready to accept connections
 done
server started
[postgres@pcs1 ~]$
[postgres@pcs1 ~]$ /u01/app/postgres/13.3/bin/pg_ctl -D /u02/app/psql/13.3/DATA status
pg_ctl: server is running (PID: 3695)
/u01/app/postgres/13.3/bin/postgres "-D" "/u02/app/psql/13.3/DATA"
[postgres@pcs1 ~]$

[postgres@pcs1 ~]$ ps -ef | grep postgres
root      3098  1810  0 01:59 pts/1    00:00:00 su - postgres
postgres  3101  3098  0 01:59 pts/1    00:00:00 -bash
postgres  3695     1  0 02:05 ?        00:00:00 /u01/app/postgres/13.3/bin/postgres -D /u02/app/psql/13.3/DATA
postgres  3697  3695  0 02:05 ?        00:00:00 postgres: checkpointer
postgres  3698  3695  0 02:05 ?        00:00:00 postgres: background writer
postgres  3699  3695  0 02:05 ?        00:00:00 postgres: walwriter
postgres  3700  3695  0 02:05 ?        00:00:00 postgres: autovacuum launcher
postgres  3701  3695  0 02:05 ?        00:00:00 postgres: stats collector
postgres  3702  3695  0 02:05 ?        00:00:00 postgres: logical replication launcher
postgres  3768  3101  0 02:06 pts/1    00:00:00 ps -ef
postgres  3769  3101  0 02:06 pts/1    00:00:00 grep --color=auto postgres
[postgres@pcs1 ~]$


16. Setting the postgres User Environment Variables

[postgres@pcs1 ~]$ psql
bash: psql: command not found...
[postgres@pcs1 ~]$ 

cat pg.env

export LD_LIBRARY_PATH=/u01/app/postgres/13.3/lib:$LD_LIBRARY_PATH
export PATH=/u01/app/postgres/13.3/bin:$PATH

[postgres@pcs1 ~]$ . pg.env
[postgres@pcs1 ~]$ 
[postgres@pcs1 ~]$ psql
psql (13.3)
Type "help" for help.

postgres=#


17. Create postgreSQL DB and test the installation

[postgres@pcs1 ~]$ psql
psql (13.3)
Type "help" for help.

postgres=# \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(3 rows)

postgres=#
postgres=# create database test;
CREATE DATABASE
postgres=#
postgres=# \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 test      | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
(4 rows)

postgres=#

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
WhatsApp : +
Linkedin: https://www.linkedin.com/in/rajasekhar-amudala/

PostgreSQL DBA – How to Create Database in PostgreSQL?

PostgreSQL DBA – How to Create Database in PostgreSQL?

Table of Contents
___________________________________________________________________________________________________

0. How to Find Create Database Syntax in PostgreSQL?
1. How to List All Databases in PostgreSQL using psql?
2. How To Create New Database in PostgreSQL using psql?
3. How To Create New Database With Owner in PostgreSQL using psql?
4. How To Create New Database With Tablespace in PostgreSQL using psql?
5. How To Create New Database With Encoding in PostgreSQL using psql?
6. How To Create New Database With Template in PostgreSQL using psql?
7. How to Create New Database With Binary Owner in PostgreSQL using Command Line?
8. How to Connect to Database in PostgreSQL using psql?
9. How to Find the Version of Database in PostgreSQL?
10. How to Exit from PostgreSQL?
___________________________________________________________________________________________________


0. How to Find Create Database Syntax in PostgreSQL?

[postgres@rac1 ~]$ psql
psql (13.2)
Type "help" for help.

postgres=# \h CREATE DATABASE
Command:     CREATE DATABASE
Description: create a new database
Syntax:
CREATE DATABASE name
    [ [ WITH ] [ OWNER [=] user_name ]
           [ TEMPLATE [=] template ]
           [ ENCODING [=] encoding ]
           [ LOCALE [=] locale ]
           [ LC_COLLATE [=] lc_collate ]
           [ LC_CTYPE [=] lc_ctype ]
           [ TABLESPACE [=] tablespace_name ]
           [ ALLOW_CONNECTIONS [=] allowconn ]
           [ CONNECTION LIMIT [=] connlimit ]
           [ IS_TEMPLATE [=] istemplate ] ]

URL: https://www.postgresql.org/docs/13/sql-createdatabase.html

postgres=#


1. How to List All Databases in PostgreSQL using psql?

postgres=# \l+
                                                                    List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   |  Size   | Tablespace |                Description
-----------+----------+----------+-------------+-------------+-----------------------+---------+------------+--------------------------------------------
 orcl      | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                       | 8117 kB | pg_default |
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                       | 8117 kB | pg_default | default administrative connection database
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +| 7969 kB | pg_default | unmodifiable empty database
           |          |          |             |             | postgres=CTc/postgres |         |            |
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +| 7969 kB | pg_default | default template for new databases
           |          |          |             |             | postgres=CTc/postgres |         |            |
(4 rows)

postgres=#

postgres=# select oid,datname from pg_database;
  oid  |  datname
-------+-----------
 14172 | postgres
 16384 | orcl
     1 | template1
 14171 | template0
(4 rows)

postgres=#


select * from pg_database;


2. How To Create New database in PostgreSQL using psql?

postgres=# create database test;
CREATE DATABASE
postgres=#
postgres=# SELECT (pg_stat_file('base/'||oid ||'/PG_VERSION')).modification, datname FROM pg_database where datname='test';
      modification      | datname
------------------------+---------
 2021-03-15 21:30:27+08 | test <----
(1 row)

postgres=#


3. How To Create New database With Owner in PostgreSQL using psql?

postgres=# create user vishnu with password 'vishnu';
CREATE ROLE
postgres=# CREATE DATABASE test2 OWNER vishnu;
CREATE DATABASE
postgres=#
postgres=# \l+ test2
                                               List of databases
 Name  | Owner  | Encoding |   Collate   |    Ctype    | Access privileges |  Size   | Tablespace | Description
-------+--------+----------+-------------+-------------+-------------------+---------+------------+-------------
 test2 | vishnu | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                   | 7969 kB | pg_default |
(1 row)

postgres=#


4. How To Create New database With Tablespace in PostgreSQL using psql?

[root@rac1 ~]# mkdir -p /u01/postgres/data/test3_tbs
[root@rac1 ~]# chown -R postgres:postgres /u01/postgres
[root@rac1 ~]# chmod -R 750 /u01/postgres

postgres=# CREATE TABLESPACE test3_tbs LOCATION '/u01/postgres/data/test3_tbs';
CREATE TABLESPACE
postgres=#

postgres=# CREATE DATABASE test3 TABLESPACE test3_tbs;
CREATE DATABASE
postgres=# select datname from pg_database where datname='test3';
 datname
---------
 test3 <----
(1 row)

postgres=#


5. How To Create New database With Encoding in PostgreSQL using psql?

postgres=# CREATE DATABASE test4 ENCODING 'UTF8';
CREATE DATABASE
postgres=#
postgres=# \l+ test4
                                                List of databases
 Name  |  Owner   | Encoding |   Collate   |    Ctype    | Access privileges |  Size   | Tablespace | Description
-------+----------+----------+-------------+-------------+-------------------+---------+------------+-------------
 test4 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                   | 7969 kB | pg_default |
(1 row)

postgres=#


6. How To Create New database With Template in PostgreSQL using psql?

postgres=# \l+ template1
                                                                List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   |  Size   | Tablespace |            Description
-----------+----------+----------+-------------+-------------+-----------------------+---------+------------+------------------------------------
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +| 7969 kB | pg_default | default template for new databases
           |          |          |             |             | postgres=CTc/postgres |         |            |
(1 row)

postgres=#

postgres=# CREATE DATABASE test5 TEMPLATE template1;
CREATE DATABASE
postgres=#
postgres=# \l+ test5
                                                List of databases
 Name  |  Owner   | Encoding |   Collate   |    Ctype    | Access privileges |  Size   | Tablespace | Description
-------+----------+----------+-------------+-------------+-------------------+---------+------------+-------------
 test5 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                   | 7969 kB | pg_default |
(1 row)

postgres=#


7. How to Create New Database With Binary Owner in PostgreSQL using Command Line?

[postgres@rac1 ~]$ id
uid=26(postgres) gid=26(postgres) groups=26(postgres) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[postgres@rac1 ~]$
[postgres@rac1 ~]$ which createdb
/bin/createdb
[postgres@rac1 ~]$
[postgres@rac1 ~]$ createdb test6
[postgres@rac1 ~]$

postgres=# \l+ test6
                                                List of databases
 Name  |  Owner   | Encoding |   Collate   |    Ctype    | Access privileges |  Size   | Tablespace | Description
-------+----------+----------+-------------+-------------+-------------------+---------+------------+-------------
 test6 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |                   | 7969 kB | pg_default |
(1 row)

postgres=#


8. How to Connect to Database in PostgreSQL using psql?

[postgres@rac1 ~]$ id
uid=26(postgres) gid=26(postgres) groups=26(postgres) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[postgres@rac1 ~]$ psql
psql (13.2)
Type "help" for help.

postgres=#
postgres=#  SELECT current_database();
 current_database
------------------
 postgres <-----
(1 row)

postgres=#
postgres=# \c test2    <---- to connect to selective database
You are now connected to database "test2" as user "postgres".
test2=#
test2=# SELECT current_database();
 current_database
------------------
 test2 <----
(1 row)

test2=#

--- OR ---

[postgres@rac1 ~]$ psql orcl
psql (13.2)
Type "help" for help.

orcl=#  <---- Now we connected to database "orcl"


9. How to Find the Version of Database in PostgreSQL using psql?

test2=# select version();
                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 13.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44), 64-bit
(1 row)

test2=#

-- OR --

[postgres@rac1 ~]$ psql
psql (13.2)  <-----
Type "help" for help.

postgres=#


10. How to Exit from PostgreSQL?

test2=# \q  <---- To quit from Postgres prompt.
[postgres@rac1 ~]$

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/

PostgreSQL DBA – How to START/STOP PostgreSQL 13 ON RHEL 7

How to START/STOP PostgreSQL 13 ON RHEL 7

Table of Contents
___________________________________________________________________________________________________

0. Overview
1. How to check Postgres server status?
2. How to Stop Postgres server?
3. How to Start Postgres server?
4. How to Restart Postgres server?
5. How to Reload Postgres server?
___________________________________________________________________________________________________


0. Overview

As root user:

service postgresql-13.service status
service postgresql-13.service start
service postgresql-13.service restart
service postgresql-13.service reload
service postgresql-13.service stop

OR 

systemctl stop postgresql-13.service
systemctl start postgresql-13.service
systemctl restart postgresql-13.service
systemctl status postgresql-13.service
systemctl reload postgresql-13.service

As Postgres user use pg_ctl command

/usr/pgsql-13/bin/pg_ctl stop -D /var/lib/pgsql/13/data
/usr/pgsql-13/bin/pg_ctl start -D /var/lib/pgsql/13/data
/usr/pgsql-13/bin/pg_ctl restart -D /var/lib/pgsql/13/data
/usr/pgsql-13/bin/pg_ctl status -D /var/lib/pgsql/13/data
/usr/pgsql-13/bin/pg_ctl reload -D /var/lib/pgsql/13/data

Restart or reload is required when changes are made to the postgresql.conf file.

Reload simply reloads the configuration in-memory. Restart replaces the entire instance.


1. How to check Postgres server status?

[root@rac1 ~]# systemctl list-units|grep postgresql
  postgresql-13.service     loaded active running   PostgreSQL 13 database server
[root@rac1 ~]# 

---- OR -----

[root@rac1 ~]# service postgresql-13.service status
Redirecting to /bin/systemctl status postgresql-13.service
● postgresql-13.service - PostgreSQL 13 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-13.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2021-03-15 17:57:05 +08; 53min ago
     Docs: https://www.postgresql.org/docs/13/static/
  Process: 969 ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 991 (postmaster)
   CGroup: /system.slice/postgresql-13.service
           β”œβ”€ 991 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/
           β”œβ”€1053 postgres: logger
           β”œβ”€1178 postgres: checkpointer
           β”œβ”€1179 postgres: background writer
           β”œβ”€1180 postgres: walwriter
           β”œβ”€1181 postgres: autovacuum launcher
           β”œβ”€1182 postgres: stats collector
           β”œβ”€1183 postgres: logical replication launcher
           └─2282 postgres: postgres postgres [local] idle

Mar 15 17:57:03 rac1.rajasekhar.com systemd[1]: Starting PostgreSQL 13 database server...
Mar 15 17:57:04 rac1.rajasekhar.com postmaster[991]: 2021-03-15 17:57:04.155 +08 [991] LOG:  redirecting log output to logging collector process
Mar 15 17:57:04 rac1.rajasekhar.com postmaster[991]: 2021-03-15 17:57:04.155 +08 [991] HINT:  Future log output will appear in directory "log".
Mar 15 17:57:05 rac1.rajasekhar.com systemd[1]: Started PostgreSQL 13 database server.
[root@rac1 ~]#

--- OR ---

[root@rac1 ~]# ps -ef | grep postgres
postgres   991     1  0 17:57 ?        00:00:00 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/
postgres  1053   991  0 17:57 ?        00:00:00 postgres: logger
postgres  1178   991  0 17:57 ?        00:00:00 postgres: checkpointer
postgres  1179   991  0 17:57 ?        00:00:00 postgres: background writer
postgres  1180   991  0 17:57 ?        00:00:00 postgres: walwriter
postgres  1181   991  0 17:57 ?        00:00:00 postgres: autovacuum launcher
postgres  1182   991  0 17:57 ?        00:00:00 postgres: stats collector
postgres  1183   991  0 17:57 ?        00:00:00 postgres: logical replication launcher
root      2201  2143  0 17:58 pts/0    00:00:00 su - postgres
postgres  2202  2201  0 17:58 pts/0    00:00:00 -bash
postgres  2281  2202  0 17:58 pts/0    00:00:00 psql
postgres  2282   991  0 17:58 ?        00:00:00 postgres: postgres postgres [local] idle
root      5744  5275  0 18:55 pts/1    00:00:00 grep --color=auto postgres
[root@rac1 ~]#

OR

[postgres@rac1 ~]$ cd /usr/pgsql-13/bin/
[postgres@rac1 bin]$ ./pg_ctl status -D /var/lib/pgsql/13/data/
pg_ctl: server is running (PID: 991)
/usr/pgsql-13/bin/postgres "-D" "/var/lib/pgsql/13/data/"
[postgres@rac1 bin]$


2. How to Stop Postgres server?

[postgres@rac1 ~]$ cd /usr/pgsql-13/bin/
[postgres@rac1 bin]$ ./pg_ctl stop -D /var/lib/pgsql/13/data/
waiting for server to shut down.... done
server stopped
[postgres@rac1 bin]$

[root@rac1 ~]# ps -ef | grep postgres
root      6718  2143  0 19:07 pts/0    00:00:00 grep --color=auto postgres
[root@rac1 ~]#

--- OR ----

[root@rac1 ~]# service postgresql-13.service stop
Redirecting to /bin/systemctl stop postgresql-13.service
[root@rac1 ~]#
[root@rac1 ~]# service postgresql-13.service status
Redirecting to /bin/systemctl status postgresql-13.service
● postgresql-13.service - PostgreSQL 13 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-13.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Mon 2021-03-15 19:07:03 +08; 5min ago
     Docs: https://www.postgresql.org/docs/13/static/
  Process: 991 ExecStart=/usr/pgsql-13/bin/postmaster -D ${PGDATA} (code=exited, status=0/SUCCESS)
  Process: 969 ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 991 (code=exited, status=0/SUCCESS)

Mar 15 17:57:03 rac1.rajasekhar.com systemd[1]: Starting PostgreSQL 13 database server...
Mar 15 17:57:04 rac1.rajasekhar.com postmaster[991]: 2021-03-15 17:57:04.155 +08 [991] LOG:  redirecting log output to logging collector process
Mar 15 17:57:04 rac1.rajasekhar.com postmaster[991]: 2021-03-15 17:57:04.155 +08 [991] HINT:  Future log output will appear in directory "log".
Mar 15 17:57:05 rac1.rajasekhar.com systemd[1]: Started PostgreSQL 13 database server.
[root@rac1 ~]#


3. How to Start Postgres server?

[postgres@rac1 ~]$ cd /usr/pgsql-13/bin/
[postgres@rac1 bin]$ ./pg_ctl start -D /var/lib/pgsql/13/data/
waiting for server to start....2021-03-15 19:14:17.815 +08 [7443] LOG:  redirecting log output to logging collector process
2021-03-15 19:14:17.815 +08 [7443] HINT:  Future log output will appear in directory "log".
 done
server started
[postgres@rac1 bin]$

--- OR ---- 

[root@rac1 ~]# service postgresql-13.service start
Redirecting to /bin/systemctl start postgresql-13.service
[root@rac1 ~]#
[root@rac1 ~]# service postgresql-13.service status
Redirecting to /bin/systemctl status postgresql-13.service
● postgresql-13.service - PostgreSQL 13 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-13.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2021-03-15 19:15:14 +08; 3s ago
     Docs: https://www.postgresql.org/docs/13/static/
  Process: 7523 ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 7529 (postmaster)
   CGroup: /system.slice/postgresql-13.service
           β”œβ”€7529 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/
           β”œβ”€7533 postgres: logger
           β”œβ”€7535 postgres: checkpointer
           β”œβ”€7536 postgres: background writer
           β”œβ”€7537 postgres: walwriter
           β”œβ”€7538 postgres: autovacuum launcher
           β”œβ”€7539 postgres: stats collector
           └─7540 postgres: logical replication launcher

Mar 15 19:15:14 rac1.rajasekhar.com systemd[1]: Starting PostgreSQL 13 database server...
Mar 15 19:15:14 rac1.rajasekhar.com postmaster[7529]: 2021-03-15 19:15:14.193 +08 [7529] LOG:  redirecting log output to logging collector process
Mar 15 19:15:14 rac1.rajasekhar.com postmaster[7529]: 2021-03-15 19:15:14.193 +08 [7529] HINT:  Future log output will appear in directory "log".
Mar 15 19:15:14 rac1.rajasekhar.com systemd[1]: Started PostgreSQL 13 database server.
[root@rac1 ~]#


4. How to Restart Postgres server?

-w, --wait             wait until operation completes (default)
  
[postgres@rac1 ~]$ cd /usr/pgsql-13/bin/
[postgres@rac1 bin]$ ./pg_ctl -w restart -D /var/lib/pgsql/13/data/
waiting for server to shut down.... done
server stopped
waiting for server to start....2021-03-15 19:22:58.920 +08 [8017] LOG:  redirecting log output to logging collector process
2021-03-15 19:22:58.920 +08 [8017] HINT:  Future log output will appear in directory "log".
 done
server started
[postgres@rac1 bin]$

--- OR ----

[root@rac1 ~]# service postgresql-13.service restart
Redirecting to /bin/systemctl restart postgresql-13.service
[root@rac1 ~]#
[root@rac1 ~]# service postgresql-13.service status
Redirecting to /bin/systemctl status postgresql-13.service
● postgresql-13.service - PostgreSQL 13 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-13.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2021-03-15 19:52:26 +08; 3s ago
     Docs: https://www.postgresql.org/docs/13/static/
  Process: 10439 ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 10445 (postmaster)
   CGroup: /system.slice/postgresql-13.service
           β”œβ”€10445 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/
           β”œβ”€10449 postgres: logger
           β”œβ”€10451 postgres: checkpointer
           β”œβ”€10452 postgres: background writer
           β”œβ”€10453 postgres: walwriter
           β”œβ”€10454 postgres: autovacuum launcher
           β”œβ”€10455 postgres: stats collector
           └─10456 postgres: logical replication launcher

Mar 15 19:52:26 rac1.rajasekhar.com systemd[1]: Starting PostgreSQL 13 database server...
Mar 15 19:52:26 rac1.rajasekhar.com postmaster[10445]: 2021-03-15 19:52:26.856 +08 [10445] LOG:  redirecting log output to logging collector process
Mar 15 19:52:26 rac1.rajasekhar.com postmaster[10445]: 2021-03-15 19:52:26.856 +08 [10445] HINT:  Future log output will appear in directory "log".
Mar 15 19:52:26 rac1.rajasekhar.com systemd[1]: Started PostgreSQL 13 database server.
[root@rac1 ~]#


5. How to Reload Postgres server?

[postgres@rac1 bin]$ ./pg_ctl reload -D /var/lib/pgsql/13/data
server signaled
[postgres@rac1 bin]$

--- OR --- 

[root@rac1 ~]# service postgresql-13.service reload
Redirecting to /bin/systemctl reload postgresql-13.service
[root@rac1 ~]#
[root@rac1 ~]# service postgresql-13.service status
Redirecting to /bin/systemctl status postgresql-13.service
● postgresql-13.service - PostgreSQL 13 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-13.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2021-03-15 19:52:26 +08; 11min ago
     Docs: https://www.postgresql.org/docs/13/static/
  Process: 11218 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
  Process: 10439 ExecStartPre=/usr/pgsql-13/bin/postgresql-13-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 10445 (postmaster)
   CGroup: /system.slice/postgresql-13.service
           β”œβ”€10445 /usr/pgsql-13/bin/postmaster -D /var/lib/pgsql/13/data/
           β”œβ”€10449 postgres: logger
           β”œβ”€10451 postgres: checkpointer
           β”œβ”€10452 postgres: background writer
           β”œβ”€10453 postgres: walwriter
           β”œβ”€10454 postgres: autovacuum launcher
           β”œβ”€10455 postgres: stats collector
           └─10456 postgres: logical replication launcher

Mar 15 19:52:26 rac1.rajasekhar.com systemd[1]: Starting PostgreSQL 13 database server...
Mar 15 19:52:26 rac1.rajasekhar.com postmaster[10445]: 2021-03-15 19:52:26.856 +08 [10445] LOG:  redirecting log output to logging collector process
Mar 15 19:52:26 rac1.rajasekhar.com postmaster[10445]: 2021-03-15 19:52:26.856 +08 [10445] HINT:  Future log output will appear in directory "log".
Mar 15 19:52:26 rac1.rajasekhar.com systemd[1]: Started PostgreSQL 13 database server.
Mar 15 19:53:40 rac1.rajasekhar.com systemd[1]: Reloaded PostgreSQL 13 database server.
Mar 15 20:03:49 rac1.rajasekhar.com systemd[1]: Reloaded PostgreSQL 13 database server.
[root@rac1 ~]#

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
WhatsApp : +
Linkedin: https://www.linkedin.com/in/rajasekhar-amudala/

PSQL

PostgreSQL DBA Step by Step Learning

#PostgreSQL DBA Topics
1How to Install PostgreSQL ON Linux?
2How to Install PostgreSQL on Linux 7 using source code?
3How to START/STOP PostgreSQL ON Linux?
4How to Create Database in PostgreSQL?
5PostgreSQL User Management
6PostgreSQL pg_hba.conf Guide
7PostgreSQL Change Data Directory
8Understanding WAL Files in PostgreSQL – For Oracle DBAs
9Change PostgreSQL WAL Directory Path (pg_wal)
10Enable Archive Mode in PostgreSQL 17
11How to Disable ARCHIVELOG Mode
12PostgreSQL Tablespace Management
13PostgreSQL pg_dump and pg_restore Guide
14PostgreSQL Backup and Restore Using pg_dumpall and psql
15pg_basebackup – Backup, Restore, and Recovery
16Backup & Restore PostgreSQL DB Cluster to Another Host (No Archive Mode)
17Backup & Restore PostgreSQL DB Cluster on Same Host
18Restore PostgreSQL to New Host using pg_basebackup + WAL Archives
19PostgreSQL PITR – Point in Time Recovery
20Configure Streaming Replication in PostgreSQL
21Manual Failover in PostgreSQL Streaming Replication
22Convert Asynchronous Replication to Synchronous Replication

 

Thank you,
Rajasekhar Amudala
Email: br8dba@gmail.com
Linkedin: https://www.linkedin.com/in/rajasekhar-amudala/