How To Configure PostgreSQL 12 Streaming Replication in CentOS 8
PostgreSQL is one of the most popular open-source relational databases, renowned for its reliability, scalability, and advanced features. Streaming replication is a critical high-availability (HA) feature in PostgreSQL that allows a replica server to synchronize with a primary server in real time. This ensures minimal data loss, enables load balancing for read queries, and provides a fallback in case the primary server fails.
In this guide, we’ll walk you through setting up PostgreSQL 12 streaming replication on two CentOS 8 servers. We’ll cover everything from prerequisites to verifying replication, testing failover, and troubleshooting common issues. By the end, you’ll have a fully functional HA PostgreSQL cluster ready for production use.
May 18, 20262026-05
Discover more
scripts
Operating Systems
Linux
Table of Contents#
- Prerequisites
- Environment Setup
- Step 1: Install PostgreSQL 12 on Both Nodes
- Step 2: Configure the Primary Node for Replication
- Step 3: Set Up the Replica Node
- Step 4: Verify Replication is Working
- Step 5: Test Failover (Optional but Recommended)
- Troubleshooting Common Issues
- Conclusion
- References
Discover more
OS
Linux & Unix
Computer Drives & Storage
Prerequisites#
Before you begin, ensure you have the following:
- Two CentOS 8 servers: One for the primary node, one for the replica node.
- Root or sudo access on both servers.
- Network connectivity: The two nodes must be able to communicate over the network (ping each other to confirm).
- Firewall rules: Allow incoming connections on PostgreSQL’s default port (5432) between the nodes.
- SELinux adjustments: Disable or configure SELinux to allow PostgreSQL network connections (common pitfall in CentOS 8).
Environment Setup#
For clarity, we’ll use the following node definitions throughout this guide:
| Node | Hostname | IP Address | Role |
|---|---|---|---|
| Primary | pg-primary |
192.168.1.10 | Main database server |
| Replica | pg-replica |
192.168.1.11 | Standby synchronization server |
First, set the hostnames on each node (replace with your values):
# On primary nodesudo hostnamectl set-hostname pg-primary # On replica nodesudo hostnamectl set-hostname pg-replica
Step 1: Install PostgreSQL 12 on Both Nodes#
CentOS 8’s default repositories do not include PostgreSQL 12, so we’ll use the official PostgreSQL YUM repository.
Step 1.1: Enable the PostgreSQL Repository#
Run this command on both nodes to install the official PostgreSQL repo:
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
Step 1.2: Install PostgreSQL 12 Packages#
Install the PostgreSQL 12 server and client packages on both nodes:
sudo dnf install -y postgresql12 postgresql12-server
Step 1.3: Initialize the Primary Node Database#
On the primary node only, initialize the PostgreSQL database:
sudo /usr/pgsql-12/bin/postgresql-12-setup initdb
Enable and start the PostgreSQL service on the primary node:
sudo systemctl enable --now postgresql-12
Note: Do not initialize the database on the replica node—we’ll clone the primary’s database later.
Step 2: Configure the Primary Node for Replication#
We need to adjust the PostgreSQL configuration files to allow replication connections and enable necessary WAL logging.
Step 2.1: Edit postgresql.conf#
Open the PostgreSQL configuration file with your preferred editor (e.g., nano or vim):
sudo nano /var/lib/pgsql/12/data/postgresql.conf
Update the following parameters (uncomment if necessary):
# Allow connections from all network interfaces (or specify replica IP)listen_addresses = '*' # Enable WAL logging required for replicationwal_level = replica # Maximum number of replication connections allowedmax_wal_senders = 3 # Retain at least 16MB of WAL segments to prevent replica from falling behindwal_keep_size = 16MB # Enable WAL archiving (optional but recommended for long-term replication)archive_mode = onarchive_command = 'cp %p /var/lib/pgsql/12/archive/%f'
Explanation:
wal_level: Sets the level of detail in WAL logs (replica is required for streaming replication).max_wal_senders: Limits concurrent replication connections (adjust based on your needs).wal_keep_size: Ensures the primary retains enough WAL data to help the replica catch up if it falls behind.
Create the archive directory for WAL segments:
sudo mkdir -p /var/lib/pgsql/12/archivesudo chown postgres:postgres /var/lib/pgsql/12/archive
Step 2.2: Edit pg_hba.conf#
This file controls client authentication. Add a rule to allow the replica node to connect for replication:
sudo nano /var/lib/pgsql/12/data/pg_hba.conf
Add the following line at the end of the file:
host replication replicator 192.168.1.11/32 md5
Replace 192.168.1.11 with your replica node’s IP address.
Step 2.3: Create a Replication User#
Switch to the postgres user and create a dedicated replication user:
sudo su - postgrespsql -c "CREATE USER replicator WITH REPLICATION LOGIN PASSWORD 'StrongPassword123!'"exit
Caution: Use a strong, unique password for production environments.
Step 2.4: Adjust Firewall and SELinux Rules#
Allow PostgreSQL traffic through the firewall on the primary node:
sudo firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.1.11" port protocol="tcp" port="5432" accept' --permanentsudo firewall-cmd --reload
Configure SELinux to allow PostgreSQL network connections:
sudo setsebool -P postgresql_can_network_connect 1
Step 2.5: Restart PostgreSQL Service#
Apply all changes by restarting the PostgreSQL service on the primary node:
sudo systemctl restart postgresql-12
Step 3: Set Up the Replica Node#
The replica node will clone the primary’s database using pg_basebackup, then connect to the primary for real-time replication.
Step 3.1: Stop PostgreSQL Service#
If PostgreSQL is running on the replica node, stop it first:
sudo systemctl stop postgresql-12
Step 3.2: Clone the Primary Database#
Switch to the postgres user and run pg_basebackup to create a copy of the primary’s database:
sudo su - postgres/usr/pgsql-12/bin/pg_basebackup -h 192.168.1.10 -U replicator -D /var/lib/pgsql/12/data/ -P -X stream -C -S repl_slot_1
Command Explanation:
-h: Primary node’s IP address.-U: Replication user we created earlier.-D: Directory to store the cloned database.-P: Show progress of the backup.-X stream: Stream WAL segments during the backup to ensure consistency.-C: Create a replication slot on the primary to prevent WAL segment deletion.-S: Name of the replication slot (repl_slot_1).
When prompted, enter the replication user’s password you set on the primary node.
Step 3.3: Configure Replica for Standby Mode#
PostgreSQL 12 replaces the old recovery.conf file with standby.signal and configuration parameters in postgresql.conf.
Create the standby.signal file to enable standby mode:
touch /var/lib/pgsql/12/data/standby.signal
Edit the postgresql.conf file to add replication settings:
nano /var/lib/pgsql/12/data/postgresql.conf
Add or update the following parameters:
# Connection details for the primary nodeprimary_conninfo = 'host=192.168.1.10 port=5432 user=replicator password=StrongPassword123!' # Use the replication slot we created on the primaryprimary_slot_name = 'repl_slot_1'
Step 3.4: Start PostgreSQL on Replica#
Exit the postgres user and start/enable the PostgreSQL service:
exitsudo systemctl enable --now postgresql-12
Step 4: Verify Replication is Working#
Let’s confirm the replica is synchronized with the primary.
Step 4.1: Check Replication Status on Primary#
On the primary node, connect to PostgreSQL and run:
sudo su - postgrespsql -c "SELECT usename, application_name, client_addr, state, sync_state FROM pg_stat_replication;"
You should see output like this, indicating the replica is connected:
usename | application_name | client_addr | state | sync_state
-----------|------------------|--------------|--------|------------
replicator| pg-replica | 192.168.1.11 | streaming | async
Step 4.2: Check Standby Mode on Replica#
On the replica node, connect to PostgreSQL and verify it’s in standby mode:
sudo su - postgrespsql -c "SELECT pg_is_in_recovery();"
The output should return t (true), meaning the replica is in recovery mode and synchronizing with the primary.
Step 4.3: Test Data Synchronization#
Create a test table on the primary node:
# On primarypsql -c "CREATE DATABASE test_db; \c test_db; CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(50));"psql -d test_db -c "INSERT INTO users (name) VALUES ('John Doe');"
On the replica node, query the test table to confirm synchronization:
# On replicapsql -d test_db -c "SELECT * FROM users;"
You should see the John Doe entry, confirming replication works.
Step 5: Test Failover (Optional but Recommended)#
Testing failover ensures your cluster can recover if the primary node goes down.
Step 5.1: Promote Replica to Primary#
On the replica node, stop PostgreSQL and promote it to primary:
sudo systemctl stop postgresql-12sudo su - postgres/usr/pgsql-12/bin/pg_ctl promote -D /var/lib/pgsql/12/data/exit
Verify the replica is now the primary:
sudo su - postgrespsql -c "SELECT pg_is_in_recovery();"
The output should return f (false), indicating it’s now a primary node.
Step 5.2: Update Applications#
Redirect your application traffic to the new primary node (192.168.1.11). To reconfigure the old primary as a replica, repeat Step 3 using the new primary node’s IP.
Discover more
Software
Scripting Languages
scripting
Troubleshooting Common Issues#
-
Replica Cannot Connect to Primary:
- Check if the firewall on the primary allows port 5432 from the replica.
- Verify
listen_addresses = '*'is set inpostgresql.confon the primary. - Ensure the
pg_hba.confon the primary includes the replica’s IP for replication.
-
Replication Slot Not Found:
- Recreate the replication slot on the primary:
SELECT pg_create_physical_replication_slot('repl_slot_1'); - Confirm
primary_slot_namein the replica’spostgresql.confmatches the slot name.
- Recreate the replication slot on the primary:
-
SELinux Blocking Connections:
- Check audit logs:
sudo cat /var/log/audit/audit.log | grep postgres - Allow network connections:
sudo setsebool -P postgresql_can_network_connect 1
- Check audit logs:
-
Replica Falling Behind:
- Increase
wal_keep_sizeon the primary to retain more WAL segments. - Ensure the replica has sufficient network bandwidth and system resources.
- Increase
Discover more
Open Source
Scripting
script
Conclusion#
You’ve successfully set up PostgreSQL 12 streaming replication on CentOS 8! This configuration provides a robust HA solution, ensuring minimal data loss and high availability. For production environments, consider adding automatic failover tools like Patroni or repmgr to streamline recovery, and monitor replication status using tools like pg_stat_replication or Prometheus with PostgreSQL exporters.
References#
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)