Managing PostgreSQL Clusters
Quick Reference
| Action | Command | Description |
|---|---|---|
| Create Cluster | bin/pgsql-add <cls> | Create a new PostgreSQL cluster |
| Expand Cluster | bin/pgsql-add <cls> <ip...> | Add replica to existing cluster |
| Shrink Cluster | bin/pgsql-rm <cls> <ip...> | Remove instance from cluster |
| Remove Cluster | bin/pgsql-rm <cls> | Destroy entire PostgreSQL cluster |
| Reload Service | bin/pgsql-svc <cls> [ip...] | Reload cluster load balancer config |
| Reload HBA | bin/pgsql-hba <cls> [ip...] | Reload cluster HBA access rules |
| Clone Cluster | - | Clone via standby cluster or PITR |
For other management tasks, see: HA Management, Manage Users, Manage Databases.
Create Cluster
To create a PostgreSQL cluster, first define the cluster in the inventory. Then add nodes and initialize them:
Create the cluster on the managed nodes.
Run the pgsql.yml playbook on the <cls> group:
Example: Create 3-node PG cluster pg-test
If you repeat cluster creation, Pigsty keeps existing data files.
However, it overwrites service configurations and restarts the cluster.
It also runs any baseline SQL from the database definition again.
If that SQL deletes or overwrites data, data loss can occur.
Expand Cluster
To add a replica to an existing PostgreSQL cluster, add its instance definition to the inventory.
Use all.children.<cls>.hosts:
Scale out with a procedure similar to cluster creation. First add the new node to Pigsty:
Then install the PGSQL module on the new node.
Use the same pg_cluster value as the existing cluster:
After you scale out, reload the service to add the new member to the load balancer.
Example: Add replica 10.10.10.13 to 2-node cluster pg-test
Shrink Cluster
To remove a replica from an existing PostgreSQL cluster, remove its instance definition.
Update all.children.<cls>.hosts in the inventory.
By default, scaling in stops the instance and deletes its data directory.
First run pig pg list <cls> and pig pb info.
Verify that the target is not the primary and that a recent restorable backup exists.
Then have the operator enter the exact <ip>.
Run the removal only after confirmation.
First uninstall the PGSQL module from the target node.
Run pgsql-rm.yml on <ip>:
After you remove the PGSQL module, you can remove the node from Pigsty:
After you scale in, remove the instance from the inventory. Then reload the service to remove the instance from the load balancer.
Example: Remove replica 10.10.10.13 from 3-node cluster pg-test
Remove Cluster
To destroy a cluster, uninstall the PGSQL module from all its nodes.
Run pgsql-rm.yml on <cls>:
This operation permanently deletes data.
Inspect pig pg list <cls> and pig pb info.
Verify a recent backup and any independent copy that you must keep.
Have the operator enter the exact cluster name.
The following commands destroy that cluster directly.
After you destroy PGSQL, you can remove all its nodes from Pigsty. You can keep nodes that run other services:
After removal, delete the entire cluster definition from inventory.
Example: Destroy 3-node PG cluster pg-test
If pg_safeguard is true for the cluster or globally, pgsql-rm.yml stops to prevent accidental removal.
To force removal, override this setting on the playbook command line.
By default, removal also deletes the cluster backup repository.
To keep backups, such as a centralized repository, set pg_rm_backup=false:
Reload Service
PostgreSQL clusters expose services through HAProxy on host nodes. Reload services when service definitions, instance weights, or cluster membership change, including scale-out and scale-in. The reload updates the static HAProxy member configuration. The default Primary and Replica services detect current roles through Patroni REST API health checks. Thus, ordinary switchover or failover redirects traffic automatically. These role changes do not require a new HAProxy configuration.
To reload service configuration, run the pg_service subtask of pgsql.yml.
Target <cls> for the whole cluster or <ip> for specific instances:
If you use a dedicated load balancer cluster, set
pg_service_provider. In this configuration, only a reload on the cluster primary updates the load balancer configuration.
Example: Reload pg-test cluster service config
Reload HBA
When HBA configuration changes, reload the pg_hba_rules and pgb_hba_rules rules.
Some HBA rules depend on inventory roles or address ranges that refer to cluster member aliases.
For these rules, reload HBA after you change pg_role labels or scale the cluster.
Role selectors use static inventory variables.
They do not change automatically after a Patroni switchover.
To reload PostgreSQL and Pgbouncer HBA rules, run the HBA subtasks of pgsql.yml.
Target <cls> for the whole cluster or <ip> for specific instances:
Example: Reload pg-test cluster HBA rules
Config Cluster
Patroni manages PostgreSQL configuration parameters.
The Patroni configuration template supplies the initial values.
After cluster initialization, Patroni dynamically manages and synchronizes the configuration stored in Etcd.
Use patronictl to change most Patroni configuration parameters.
Use subtasks for other parameters, such as etcd DCS, logging, and REST API configuration.
For example, refresh Patroni configuration after etcd cluster membership changes:
You can override Patroni-managed defaults at different levels: specify params per instance, specify params per user, or specify params per database.
Clone Cluster
You can clone a cluster with a Standby Cluster or Point-in-Time Recovery. A standby cluster is simple and does not require a backup repository. It requires a reachable replication upstream and can copy only the latest state. PITR requires a centralized backup repository, such as Silo. It can clone the cluster to any point within the retention period.
| Method | Pros | Cons | Use Cases |
|---|---|---|---|
| Standby Cluster | No backup repository needed | Requires reachable upstream; latest state only | DR, read-write separation, migration |
| PITR | Recover to any point | Requires centralized backup | Undo mistakes, data audit |
Clone via Standby Cluster
A standby cluster continuously synchronizes from the upstream cluster through streaming replication.
This is the simplest cloning method.
Set pg_upstream on the new cluster primary to pull data automatically from the upstream.
Create standby cluster with:
The standby cluster follows the upstream and keeps its data synchronized. You can promote it to an independent cluster at any time:
Example: Promote Standby to Independent Cluster
Via Config Cluster, remove standby_cluster config to promote:
After promotion, pg-test2 becomes independent cluster accepting writes, forked from pg-test.
Example: Change Replication Upstream
If upstream cluster switchover occurs, change standby cluster upstream via Config Cluster:
Clone via PITR
Point-in-Time Recovery (PITR) can recover to any point within the backup retention period. It requires a centralized backup repository, such as Silo or S3. It gives more recovery options than a standby cluster.
To clone with PITR, add pg_pitr and specify the recovery target:
Execute clone with pgsql-pitr.yml playbook:
PITR supports multiple recovery target types:
| Target Type | Example | Description |
|---|---|---|
| Time | time: "2025-01-10 10:00:00+00" | Recover to specific timestamp |
| XID | xid: "250000" | Recover to before/after txn |
| Name | name: "before_migration" | Recover to named restore point |
| LSN | lsn: "0/4001C80" | Recover to specific WAL pos |
| Latest | pg_pitr: {} | Recover to end of WAL archive |
Pigsty v4.5 PITR keeps archiving enabled by default (archive: true). If you explicitly set archive: false for exploratory recovery, reset archive_mode, restart the cluster, and perform a new full backup after confirming the recovered data is correct:
For detailed PITR usage, see Restore Operations documentation.
Was this page helpful?
Thanks—your feedback helps us improve this page.
What got in the way? (optional)