How To Set Up An Active/Passive PostgreSQL Cluster With Pacemaker, Corosync, And DRBD (CentOS 5.5)

This article explains how to set up (and monitor) an Active/Passive PostgreSQL Cluster, using Pacemaker with Corosync and DRBD. Prepared by Rafael Marangoni, from BRLink Servidor Linux Team.



We use two nodes, one active (that answers requests from apps) and the other on passive mode. If the active server is down, the passive one will automatically take its position (being the active node).


1 Preliminary Note

Linux Distribution:

We are using the CentOS 5.5 (64bits) distribution, but it will probably work on Fedora (and Red Hat, for sure) as well. The installation of the CentOS is very simple and classical, select the base packages and other stuff that you like/need. One issue that must be remembered is that we use DRBD to replicate the PostgreSQL data between the nodes, then you'll need to have a disk or partition exclusive to DRBD. Remember this before partitioning disks on CentOS installation.

Network Hardware/Topology:

We use two Gigabit NIC's per node, one (eth0) connect to the network (LAN), and the other one (eth1) with a cross-over cable connecting both nodes.
The cross-over cable must be used to improve performance and confiability of the system, because DRBD won't depends of network switchs or anything else to replicate data between the nodes.

In this tutorial we will use the physical nodes and Uses IP (LAN) and IP (cross-over) Uses IP (LAN) and IP (cross-over) It's the Cluster IP, This is the IP that all the applications need to be pointed to, to access the PostgreSQL


Both the nodes have two disks:
/dev/sda: to system OS;
/dev/sdb: to DRBD.
As I said before, you can use only one disk, if leaving one partition exclusive to DRBD.


The version of the PostgreSQL used on this article is 8.4, but it doesn't really matters, because anything that you have inside the DRBD device, will be replicated through the cluster.


2 Preparing the Nodes

Disabling SELINUX

We need to disable the SELINUX:

vi /etc/selinux/config

Change this line only (leaving everything else untouched):



Setting Hostname

We need to change the hostname and gateway of the nodes:

vi /etc/sysconfig/network






Configuring network interfaces

Next, we will configure the network interfaces:


The LAN interface

vi /etc/sysconfig/network-scripts/ifcfg-eth0


The Cross-Over/DRBD interface

vi /etc/sysconfig/network-scripts/ifcfg-eth1



The LAN interface

vi /etc/sysconfig/network-scripts/ifcfg-eth0


The Cross-Over/DRBD interface

vi /etc/sysconfig/network-scripts/ifcfg-eth1



Setting DNS Configuration

Setting DNS configuration on both nodes (according to your network):

vi /etc/resolv.conf



Configuring basic hostname resolution

Configuring /etc/hosts (same config on both nodes):

vi /etc/hosts               localhost.localdomain localhost       node1       node2       node2

PS: You'll probably want to set another lines on this file, to point to other addresses of your network.


Checking network connectivity

Let's check if everything is fine:


Pinging node2 (thru LAN interface):

ping -c 2 node2

[root@node1 ~]# ping -c 2 node2
PING node2 ( 56(84) bytes of data.
64 bytes from node2 ( icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from node2 ( icmp_seq=2 ttl=64 time=0.082 ms
--- node2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.082/0.085/0.089/0.009 ms

Pinging node2 (thru cross-over interface):

ping -c 2

[root@node1 ~]# ping -c 2
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from icmp_seq=2 ttl=64 time=0.083 ms
--- ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.083/0.083/0.083/0.000 ms


Pinging node1 (thru LAN interface):

ping -c 2 node1

[root@node2 ~]# ping -c 2 node1
PING node1 ( 56(84) bytes of data.
64 bytes from node1 ( icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from node1 ( icmp_seq=2 ttl=64 time=0.063 ms
--- node1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.063/0.065/0.068/0.008 ms

Pinging node1 (thru cross-over interface):

ping -c 2

[root@node2 ~]# ping -c 2
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=1.36 ms
64 bytes from icmp_seq=2 ttl=64 time=0.075 ms
--- ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.075/0.722/1.369/0.647 ms


Configuring Initialization options

I like to set runlevel to 3.

vi /etc/inittab

Change this line only (leaving everything else untouched):


I like remove some services from automatic initialization, to maintain only services that really will be used.

These are the active services that we'll need:

chkconfig --list | grep 3:sim

[root@node1 ~]# chkconfig --list | grep 3:sim
acpid           0:não  1:não  2:sim   3:sim   4:sim   5:sim   6:não
anacron         0:não  1:não  2:sim   3:sim   4:sim   5:sim   6:não
apmd            0:não  1:não  2:sim   3:sim   4:sim   5:sim   6:não
atd             0:não  1:não  2:não  3:sim   4:sim   5:sim   6:não
cpuspeed        0:não  1:sim   2:sim   3:sim   4:sim   5:sim   6:não
crond           0:não  1:não  2:sim   3:sim   4:sim   5:sim   6:não
irqbalance      0:não  1:não  2:sim   3:sim   4:sim   5:sim   6:não
kudzu           0:não  1:não  2:não  3:sim   4:sim   5:sim   6:não
network         0:não  1:não  2:sim   3:sim   4:sim   5:sim   6:não
rawdevices      0:não  1:não  2:não  3:sim   4:sim   5:sim   6:não
sshd            0:não  1:não  2:sim   3:sim   4:sim   5:sim   6:não
syslog          0:não  1:não  2:sim   3:sim   4:sim   5:sim   6:não

PS: The services that will be managed by the Pacemaker (the Cluster Resource Manager - CRM), in this article they're Postgresql and DRBD, should not been on automatic initialization, because Pacemaker will start/stop these services.

At this point, we need to reboot both nodes to apply configuration.


3. Installing prerequisites and cluster packages

There are some packages that need to be installed before:

yum install -y postgresql84** gcc perl-mailtools perl-dbi php-pgsql

To install the cluster packages, we'll need to add the EPEL repository:

rpm -Uvh

This link points to the EPEL package to CentOS 5 64bits, be sure to make changes if this is not your distro/version.

Now, we install the ClusterLabs EPEL repository:

wget -O /etc/yum.repos.d/pacemaker.repo

If evething is fine, just go ahead now, and install cluster and drbd packages:

yum install -y pacemaker corosync drbd83 kmod-drbd83 heartbeat

Share this page:

6 Comment(s)

Add comment


From: at: 2010-11-17 21:19:04

Very nice and happily confirms that my solution (although using Debian Lenny) was spot on.

Also very cool to see some additional tools mentioned (zabbix f.i.)

Thanks for the efforts!


One word though to anyone using the HA stuff, there are some versions that can be 'complicated' so watch out and if possible, use known working versions.

From: Serge Dubrouski at: 2010-11-15 22:47:11

Nice work!

Could you place it to the Clusterlabs' HowTo page? There is a basic HowTo for PostgreSQL that I created earlier, it would be good to replace it with yours.

From: Gergely Polonkai at: 2013-03-13 18:28:43

Dear everyone, 

please stop disabling SELinux. It is good, and works more than fine. If you really have trouble with it, set it to permissive mode, and create a custom house rule for that. Most importantly, if you use packages from the central CentOS/Fedora/RedHad repository, report these troubles so they can add the required changes to their policies.

It's a nice article, though, it goes through every necessary steps, thank you!

Best wishes!


From: Peter Scott at: 2012-01-24 21:43:44

I have been banging my head against setting up simple failover on RHEL 6 and your page is the only one I have found that has worked 100% for me.  Thank you, thank you.

From: Jeff at: 2011-02-22 21:43:23

I don't think the configuration you gave will provide any high availability for network failures. You mentioned STONITH, but said you could do this without it. In this configuration, if you pull the cable for eth0 from node1, then node2 would not take over. DRBD would prevent node2 from becoming the primary. Do you have any recommendations for that scenario without a STONITH device?

From: Chris at: 2012-05-19 18:41:18

Sure you can, but it all depends on your network infrastructure.  Use redundant switches and nic bonding for both the lan and the crossover and you're set.  I typically create a replication vlan with bonding in this scenario.  The down side is that you need 4 nics per box but the general config outlined in this document will work.  I also built one in a vmware (vsphere cluster environment in my case) and achieved HA that way.  Both ways have worked well for me.  This is really just a reference guide.  If you're a little creative and make adjustments to suit the details of your environment you'll find a way.  I promise.  I've even managed to use this as a general guide for achieving the same cluster mechanism for mysql.