Pgpool-II is a powerful, open-source middleware that sits between PostgreSQL servers and database clients
Architecture
What is Pgpool-II?
Pgpool-II is a middleware between your application and PostgreSQL that provides:
- Connection Pooling
- Load Balancing
- Failover & HA
- Query Caching
- Replication Support
- Health Checking
Recommended Production Architecture
+-------------------+
| Application |
+---------+---------+
|
VIP / LB IP
|
+-------+-------+
| Pgpool-II |
+-------+-------+
|
+----------------+----------------+
| |
+-------+--------+ +---------+-------+
| PostgreSQL | | PostgreSQL |
| Primary |<------------>| Replica |
| Read/Write | Streaming | Read Only |
+----------------+ Replication +----------------+
Install PostgreSQL
On Primary Server
Example OS: Ubuntu 26.04
sudo apt update
sudo apt install -y postgresql postgresql-contrib
Check service:
sudo systemctl status postgresql
Configure PostgreSQL Primary
Edit PostgreSQL Config
File:
vi /etc/postgresql/18/main/postgresql.conf
Update:
listen_addresses = '*'
wal_level = replica
max_wal_senders = 10
max_replication_slots = 10
hot_standby = on
archive_mode = on
archive_command = 'true'
Configure pg_hba.conf
vi /etc/postgresql/16/main/pg_hba.conf
Add:
host replication replicator 0.0.0.0/0 md5
host all all 0.0.0.0/0 md5
Restart:
sudo systemctl restart postgresql
Create Replication User
Login:
sudo -u postgres psql
Create user:
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'StrongPassword';
Step 4: Configure Replica Server
Install PostgreSQL on the replica node.
Stop PostgreSQL:
sudo systemctl stop postgresql
Clear old data:
sudo rm -rf /var/lib/postgresql/18/main/*
Clone from primary:
PGPASSWORD='StrongPassword' pg_basebackup \
-h PRIMARY_IP \
-U replicator \
-D /var/lib/postgresql/18/main \
-P -R
Fix Ownership
sudo chown -R postgres:postgres /var/lib/postgresql/18/main
sudo chmod 700 /var/lib/postgresql/18/main
Verify Recovery Files
ls -la /var/lib/postgresql/18/main/
Must contain:
standby.signal
Start replica:
sudo pg_ctlcluster 18 main start
Verify:
pg_lsclusters
Expected:
18 main 5432 online,recovery
This is GOOD for the replica.
Test Replication
sudo -u postgres psql -c "SELECT * FROM pg_stat_wal_receiver;"
# Expected:
t # true, if f then its false
Important Check on PRIMARY
Primary must allow replication.
postgresql.conf
wal_level = replica
max_wal_senders = 10
hot_standby = on
listen_addresses = '*'
pg_hba.conf
host replication replicator REPLICA_IP/32 md5
or:
host replication replicator 0.0.0.0/0 md5
Restart primary:
sudo systemctl restart postgresql
Send the output of:
cat /var/log/postgresql/postgresql-18-main.log
If the replica still stays down,recovery.
Install Pgpool-II
On Pgpool Server
sudo apt install -y pgpool2
Step 6: Configure Pgpool-II
Main config:
vi /etc/pgpool2/pgpool.conf
Basic Pgpool Configuration
listen_addresses = '*'
port = 9999
backend_hostname0 = '10.0.0.10'
backend_port0 = 5432
backend_weight0 = 1
backend_flag0 = 'ALLOW_TO_FAILOVER'backend_hostname1 = '10.0.0.11'
backend_port1 = 5432
backend_weight1 = 1
backend_flag1 = 'ALLOW_TO_FAILOVER'enable_pool_hba = onmaster_slave_mode = on
master_slave_sub_mode = 'stream'load_balance_mode = onsr_check_period = 10
sr_check_user = 'postgres'
sr_check_password = 'postgres_password'health_check_period = 10
health_check_user = 'postgres'
health_check_password = 'postgres_password'failover_on_backend_error = on
Step 7: Configure Pool Authentication
Create password file:
sudo pg_md5 --md5auth --username=postgres postgres_password
Creates:
/etc/pgpool2/pool_passwd
Step 8: Configure pg_hba for Pgpool
File:
/etc/pgpool2/pool_hba.conf
Example:
host all all 0.0.0.0/0 md5
Step 9: Enable PCP Commands
Edit:
/etc/pgpool2/pcp.conf
Add:
admin:md5hash
Generate md5:
pg_md5 mypassword
Step 10: Start Pgpool-II
sudo systemctl restart pgpool2
sudo systemctl enable pgpool2
Check:
sudo systemctl status pgpool2
Step 11: Test Connection
Connect application:
psql -h PGPOOL_IP -p 9999 -U postgres
Verify Replication
On Primary:
SELECT * FROM pg_stat_replication;
Verify Load Balancing
On Pgpool:
SHOW pool_nodes;
Pgpool-II Features
FeatureDescriptionConnection PoolingReuse DB connectionsLoad BalancingSend SELECT queries to replicasFailoverAuto switch primaryHealth CheckDetect node failureWatchdogVirtual IP HAQuery CacheCache repeated queries
Pgpool-II High Availability (Optional)
For production:
Use:
- 2 Pgpool-II servers
- Watchdog
- VIP (Virtual IP)
Architecture:
App
|
VIP
|
+-------------------+
| Pgpool-II Active |
| Pgpool-II Standby |
+-------------------+
|
PostgreSQL Cluster
Recommended Production Stack
LayerRecommendedPostgreSQL HAStreaming ReplicationPoolingPgpool-IIVIPKeepalivedMonitoringPrometheus + GrafanaBackuppgBackRestConnection LimitPgBouncer (optional)
Pgpool-II vs PgBouncer
FeaturePgpool-IIPgBouncerPoolingYesYesLoad BalancingYesNoFailoverYesNoReplication AwarenessYesNoLightweightMediumVery LightweightHA SupportYesLimited
Production Recommendation
Best setup:
App
↓
HAProxy / Keepalived VIP
↓
Pgpool-II Cluster
↓
PostgreSQL Primary + Replicas
Useful Commands
Show Pool Nodes
SHOW pool_nodes;
Attach Node
pcp_attach_node
Detach Node
pcp_detach_node
Node Info
pcp_node_info
Common Problems
ProblemSolutionReplica not syncingCheck wal_level & pg_hbaPgpool login failConfigure pool_passwdFailover not workingEnable watchdogSELECT not balancedEnable load_balance_modeToo many connectionsTune num_init_children
Docker Compose Example
version: '3.9'
services: postgres-primary:
image: postgres:16
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- "5432:5432" pgpool:
image: bitnami/pgpool:latest
ports:
- "9999:5432"
environment:
PGPOOL_BACKEND_NODES: 0:postgres-primary:5432
PGPOOL_SR_CHECK_USER: postgres
PGPOOL_SR_CHECK_PASSWORD: postgres
PGPOOL_POSTGRES_USERNAME: postgres
PGPOOL_POSTGRES_PASSWORD: postgres
Top comments (0)