A PostgreSQL active-active architecture keeps multiple database nodes available for read and write traffic, reducing maintenance downtime and avoiding a single primary bottleneck for client connections.
In a Pacemaker and Corosync cluster, the pcs CLI can manage a systemd unit as a cluster resource and clone that resource so the service stays started on every node. Health checks are performed by Pacemaker based on the configured monitor operation, while traffic distribution is handled outside the cluster by a load balancer, DNS, or application-side routing.
Cloning a PostgreSQL service provides supervision and restart behavior, not multi-writer replication. A true active-active deployment requires a multi-primary replication layer (such as BDR or an equivalent solution) and separate local data directories on each node; cloning a shared-storage database instance can corrupt the data directory. Quorum, fencing, and replication health should be correct before allowing write traffic to land on multiple nodes.
$ sudo pcs status Cluster name: clustername Cluster Summary: * Stack: corosync (Pacemaker is running) * Current DC: node-01 (version 2.1.6-6fdc9deea29) - partition with quorum * Last updated: Thu Jan 1 05:41:07 2026 on node-01 * Last change: Thu Jan 1 05:41:04 2026 by root via cibadmin on node-01 * 3 nodes configured * 0 resource instances configured Node List: * Online: [ node-01 node-02 node-03 ] Full List of Resources: * No resources Daemon Status: corosync: active/enabled pacemaker: active/enabled pcsd: active/enabled
$ systemctl list-unit-files --type=service | grep -E '^postgresql.*\.service' postgresql.service disabled enabled postgresql@.service indirect enabled
Use the unit name without the trailing .service in the resource agent, such as systemd:postgresql, systemd:postgresql-15, or systemd:postgresql@15-main.
$ sudo pcs resource create postgresql_service systemd:postgresql@16-main op monitor interval=30s
Replace systemd:postgresql with the unit name found in the previous step when a versioned or templated unit is used.
Related: How to create a Pacemaker resource
$ sudo pcs resource clone postgresql_service meta clone-max=2 clone-node-max=1
Omit clone-max to default to one instance per cluster node.
Cloning a PostgreSQL instance that uses shared storage for a single data directory can cause immediate data corruption.
$ sudo pcs status resources
* Clone Set: postgresql_service-clone [postgresql_service]:
* postgresql_service (systemd:postgresql@16-main): Starting node-02
* Started: [ node-01 ]
* Stopped: [ node-03 ]
$ pg_isready -h node-01 -p 5432 node-01:5432 - accepting connections $ pg_isready -h node-02 -p 5432 node-02:5432 - accepting connections