Managing High Availability in PostgreSQL – Part I
Tags: postgres, highavailability, database, failover
Published: 2018-11-27 16:27:32

---
title: Managing High Availability in PostgreSQL – Part I
published: true
description: 3-part blog on how to manage PostgreSQL high availability using streaming replication via open source tools for automatic failover, monitoring and replication
tags: PostgreSQL, High Availability, Database, Failover,
canonical_url: https://scalegrid.io/blog/managing-high-availability-in-postgresql-part-1/
---
<link rel="canonical" href="https://scalegrid.io/blog/managing-high-availability-in-postgresql-part-1/" />

<a href="https://scalegrid.io/blog/managing-high-availability-in-postgresql-part-1/"><img src="https://scalegrid.io/blog/wp-content/uploads/2018/11/Managing-High-Availability-in-PostgreSQL-Part-I-ScaleGrid.png" alt="Managing High Availability in PostgreSQL – Part I - ScaleGrid Blog"></a>

<p style="text-align: justify;">Managing high availability in your <a style="color: #2da964;" href="https://scalegrid.io/postgresql.html" target="_blank">PostgreSQL hosting</a> is very important to ensuring your clusters maintain exceptional uptime and strong operational performance so your data is always available to your application. In an earlier blog post, we introduced you to <a style="color: #2da964;" href="https://scalegrid.io/blog/getting-started-with-postgresql-streaming-replication/" target="_blank">configuring high availability for PostgreSQL using streaming replication</a>, and now we're going to show you how to <a style="color: #2da964;" href="https://scalegrid.io/blog/managing-high-availability-in-postgresql-part-1/" target="_blank">best manage PostgreSQL high availability</a>.</p>
<p style="text-align: justify;">There are multiple tools available for managing the high availability of your PostgreSQL clusters using streaming replication. These solutions offer automatic failover capabilities, monitoring, replication, and other useful administrative tasks. Some of the prominent open source solutions include:</p>

<ol>
	<li>
<h4>PostgreSQL Automatic Failover by <a style="color: #2da964;" href="https://www.clusterlabs.org/" target="_blank">ClusterLabs</a></h4>
</li>
	<li>
<h4>Replication Manager for PostgreSQL Clusters by <a style="color: #2da964;" href="https://repmgr.org/" target="_blank">repmgr</a> (2ndQuadrant)</h4>
</li>
	<li>
<h4>Patroni by <a style="color: #2da964;" href="https://github.com/zalando/patroni" target="_blank">Zalando</a></h4>
</li>
</ol>
<p style="text-align: justify;">Each of these tools provides their own way of managing the clusters. In our three-part series of posts on high availability for PostgreSQL, we'll share an overview, the prerequisites, and the working and test results for each of these three tools. Here in Part 1, we'll deep dive into the PostgreSQL Automatic Failover (PAF) solution by ClusterLabs.</p>

<h2 style="padding-top: 15px;">PostgreSQL Automatic Failover</h2>
<p style="text-align: justify;"><a style="color: #2da964;" href="https://clusterlabs.github.io/PAF/" target="_blank">PostgreSQL Automatic Failover</a> (PAF) is a high availability management solution for PostgreSQL by ClusterLabs. PAF makes use of the popular, industry-standard <a style="color: #2da964;" href="https://clusterlabs.org/pacemaker/" target="_blank">Pacemaker</a> and <a style="color: #2da964;" href="https://clusterlabs.org/corosync.html" target="_blank">Corosync</a> stack. With Pacemaker and Corosync together, you'll be able to detect failures in the system and act accordingly.</p>
<p style="text-align: justify;">Pacemaker is capable of managing many resources, and does so with the help of their <a style="color: #2da964;" href="https://github.com/ClusterLabs/resource-agents/" target="_blank">resource agents</a>. Resource agents then have the responsibility of handling a specific resource, how they should behave, and inform Pacemaker of their results.</p>
<p style="text-align: justify;">Your resource agent implementation must comply to the <a style="color: #2da964;" href="https://clusterlabs.org/pacemaker/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/s-resource-supported.html" target="_blank">Open Cluster Framework</a> (OCF) specification. This specification defines resource agents’ behavior and implementation of methods like stop, start, promote, demote and interaction with Pacemaker.</p>
<p style="text-align: justify;">PAF is an OCF resource agent for PostgreSQL written in Perl. Once your PostgreSQL cluster is built using internal streaming replication, PAF is able to expose to Pacemaker the current status of the PostgreSQL instance on each node: master, slave, stopped, catching up, etc.</p>

<h2 style="padding-top: 15px;">How it Works</h2>
<p style="text-align: justify;">PAF communicates with Pacemaker regarding the cluster status and monitors the PostgreSQL functioning. In the event of a failure, it informs Pacemaker, and if there's no chance of the current master being recovered, it will trigger an election between the current standby servers. With the robust Pacemaker in place, PAF will perform management actions like start, stop, monitor, and failover on all the PostgreSQL nodes.</p>


<h3 style="padding-top: 15px;">Are There Any Setup Requirements?</h3>
<ul>
	<li>PAF supports <a style="color: #2da964;" href="https://www.postgresql.org/support/versioning/" target="_blank">PostgreSQL version 9.3</a> and higher.</li>
	<li>PAF is not responsible for PostgreSQL master/standby creation or its setup - you must create and setup streaming replication before using PAF.</li>
	<li>PAF doesn’t edit any configuration of Postgres. However, it requires users to follow a few prerequisites like:
<ul>
	<li>Slave must be configured as hot standby.</li>
	<li>A recovery template file (default: &lt;postgresql_data_location&gt;/recovery.conf.pcmk) has to be provided with below parameters:
<ul>
	<li><strong>standby_mode</strong> = on</li>
	<li><strong>recovery_target_timeline</strong> = 'latest'</li>
	<li><strong>primary_conninfo</strong> must have the application_name parameter defined and set to local node name as in Pacemaker.</li>
</ul>
</li>
</ul>
</li>
	<li>PAF exposes multiple parameters related to the management of a PostgreSQL resource. This can be configured to suit one’s requirement. Below are the parameters:
<ul>
	<li><strong>bindir:</strong> location of the PostgreSQL binaries (default: /usr/bin)</li>
	<li><strong>pgdata:</strong> location of the PGDATA of your instance (default: /var/lib/pgsql/data)</li>
	<li><strong>datadir:</strong> path to the directory set in data_directory from your postgresql.conf file</li>
	<li><strong>pghost:</strong> the socket directory or IP address to use to connect to the local instance (default: /tmp)</li>
	<li><strong>pgport:</strong> the port to connect to the local instance (default: 5432)</li>
	<li><strong>recovery_template:</strong> the local template that will be copied as the PGDATA/recovery.conf file. This template file must exists on all node (default: $PGDATA/recovery.conf.pcmk)</li>
	<li><strong>start_opts:</strong> Additional arguments given to the Postgres process on startup. See "postgres --help" for available options. Useful when the postgresql.conf file is not in the data directory (PGDATA), eg.: -c config_file=/etc/postgresql/9.3/main/postgresql.conf</li>
	<li><strong>system_user:</strong> the system owner of your instance's process (default: postgres)</li>
	<li><strong><span style="color: #444444;">maxlag:</span></strong> maximum lag allowed on a standby before we set a negative master score on it</li>
</ul>
</li>
</ul>
<h2 style="padding-top: 15px;">PAF Pros</h2>
<ul>
	<li>PAF provides the user a free hands-on configuration and setup of PostgreSQL.</li>
	<li>PAF can handle node failures and trigger elections when the master goes down.</li>
	<li>Quorum behavior can be enforced in PAF.</li>
	<li>It will provide a complete high availability management solution for the resource, including start, stop, and monitor, and handle network isolation scenarios.</li>
	<li>It's a distributed solution, which enables the management of any node from another node.</li>
</ul>
<h2 style="padding-top: 15px;">PAF Cons</h2>
<ul>
	<li>PAF doesn’t detect if a standby is misconfigured with an unknown or non-existent node in recovery configuration. Node will be shown as slave, even if standby is running without connecting to the master/cascading standby node.</li>
	<li>Requires an extra port (Default 5405) to be opened for the Pacemaker and Corosync components’ communication using UDP.</li>
	<li>Does not support NAT-based configuration.</li>
	<li>No pg_rewind support.</li>
</ul>
<h2 style="padding-top: 15px;">High Availability Test Scenarios</h2>
<p style="text-align: justify;">We conducted a few tests to determine the capability of the PostgreSQL HA management using PAF. All of these tests were run while the application was running and inserting data to the PostgreSQL database. The application was written using PostgreSQL Java <a style="color: #2da964;" href="https://jdbc.postgresql.org/" target="_blank">JDBC Driver</a> leveraging the connection failover capability.</p>

<h3 style="padding-top: 15px;">Standby Server Tests</h3>
<table class="table table-bordered">
<tbody>
<tr>
<th style="width: 5%; vertical-align: middle; background-color: #d9fce9;">Sl. No</th>
<th style="width: 25%; vertical-align: middle; background-color: #d9fce9;">Test Scenario</th>
<th style="width: 70%; vertical-align: middle; background-color: #d9fce9;">Observation</th>
</tr>
<tr>
<td style="vertical-align: middle;">1</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Kill the PostgreSQL process</td>
<td style="vertical-align: middle;">Pacemaker brought the PostgreSQL process back to running state. There was no disruption in writer application.</td>
</tr>
<tr>
<td style="vertical-align: middle;">2</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Stop the PostgreSQL process</td>
<td style="vertical-align: middle;">Pacemaker brought the PostgreSQL process back to running state. There was no disruption in writer application.</td>
</tr>
<tr>
<td style="vertical-align: middle;">3</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Reboot the server</td>
<td style="vertical-align: middle;">Standby server was marked offline initially. Once the server came up after reboot, PostgreSQL was started by Pacemaker and the server was marked as online. If fencing was enabled, the node wouldn’t have been added automatically to cluster. There was no disruption in writer application.</td>
</tr>
<tr>
<td style="vertical-align: middle;">4</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Stop the Pacemaker process</td>
<td style="vertical-align: middle;">It will stop the PostgreSQL process also, and the server will be marked offline. There was no disruption in writer application.</td>
</tr>
</tbody>
</table>
<h3 style="padding-top: 15px;">Master/Primary Server Tests</h3>
<table class="table table-bordered">
<tbody>
<tr>
<td style="width: 5%; vertical-align: middle; background-color: #d9fce9;"><strong>Sl. No</strong></td>
<td style="width: 25%; vertical-align: middle; background-color: #d9fce9;"><strong>Test Scenario</strong></td>
<td style="width: 70%; vertical-align: middle; background-color: #d9fce9;"><strong>Observation</strong></td>
</tr>
<tr>
<td style="vertical-align: middle;">1</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Kill the PostgreSQL process</td>
<td style="vertical-align: middle;">Pacemaker brought the PostgreSQL process back to running state. Primary was recovered within the threshold time and, hence, election was not triggered. The writer application was down for about 26 seconds.</td>
</tr>
<tr>
<td style="vertical-align: middle;">2</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Stop the PostgreSQL process</td>
<td style="vertical-align: middle;">Pacemaker brought the PostgreSQL process back to running state. Primary was recovered within the threshold time and, hence, election was not triggered. There was a downtime in writer application for about 26 seconds.</td>
</tr>
<tr>
<td style="vertical-align: middle;">3</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Reboot the server</td>
<td style="vertical-align: middle;">Election was triggered by Pacemaker after the threshold time for which master was not available. The most eligible standby server was promoted as the new master. Once the old master came up after reboot, it was added back to the cluster as a standby. If fencing was enabled, the node wouldn’t have been added automatically to cluster. The writer application was down for about 26 seconds.</td>
</tr>
<tr>
<td style="vertical-align: middle;">4</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Stop the Pacemaker process</td>
<td style="vertical-align: middle;">It will stop the PostgreSQL process also and server will be marked offline. Election will be triggered and new master will be elected. There was downtime in writer application.</td>
</tr>
</tbody>
</table>
<h3 style="padding-top: 15px;">Network Isolation Tests</h3>
<table class="table table-bordered">
<tbody>
<tr>
<td style="width: 5%; vertical-align: middle; background-color: #d9fce9;"><strong>Sl. No</strong></td>
<td style="width: 25%; vertical-align: middle; background-color: #d9fce9;"><strong>Test Scenario</strong></td>
<td style="width: 70%; vertical-align: middle; background-color: #d9fce9;"><strong>Observation</strong></td>
</tr>
<tr>
<td style="vertical-align: middle;">1</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Network isolate the standby server from other servers</td>
<td style="vertical-align: middle;">Corosync traffic was blocked on the standby server. The server was marked offline and PostgreSQL service was turned off due to quorum policy. There was no disruption in the writer application.</td>
</tr>
<tr>
<td style="vertical-align: middle;">2</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Network isolate the master server from other servers (split-brain scenario)</td>
<td style="vertical-align: middle;">Corosync traffic was blocked on the master server. PostgreSQL service was turned off and master server was marked offline due to quorum policy. A new master was elected in the majority partition. There was a downtime in the writer application.</td>
</tr>
</tbody>
</table>
<h3 style="padding-top: 15px;">Miscellaneous Tests</h3>
<table class="table table-bordered">
<tbody>
<tr>
<td style="width: 5%; vertical-align: middle; background-color: #d9fce9;"><strong>Sl. No</strong></td>
<td style="width: 25%; vertical-align: middle; background-color: #d9fce9;"><strong>Test Scenario</strong></td>
<td style="width: 70%; vertical-align: middle; background-color: #d9fce9;"><strong>Observation</strong></td>
</tr>
<tr>
<td style="vertical-align: middle;">1</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Degrade the cluster by turning off all the standby servers.</td>
<td style="vertical-align: middle;">When all the standby servers went down, PostgreSQL service on master was stopped due to quorum policy. After this test, when all the standby servers was turned on, a new master was elected. There was a downtime in the writer application.</td>
</tr>
<tr>
<td style="vertical-align: middle;">2</td>
<td style="vertical-align: middle; background-color: #f5f5f5;">Randomly turn off all the servers one after the other, starting with the master, and bring them all back at same time</td>
<td style="vertical-align: middle;">All the servers came up and joined the cluster. New master was elected. There was a downtime in the writer application.</td>
</tr>
</tbody>
</table>
<h2>Inference</h2>
<p style="text-align: justify;">PostgreSQL Automatic Failover provides several advantages in handling PostgreSQL high availability. PAF uses IP address failover instead of rebooting the standby to connect to the new master during a failover event. This proves advantageous in scenarios where the user does not want to restart the standby nodes. PAF also needs very little manual intervention and manages the overall health of all the resources. The only case where manual intervention is a requirement is in the event of a timeline divergence where the user can elect to use <a style="color: #2da964;" href="https://www.postgresql.org/docs/9.6/app-pgrewind.html" target="_blank">pg_rewind</a>.</p>
<p style="text-align: justify; padding-bottom: 15px;">In Part 1, we've discussed the capabilities and workings of PostgreSQL Automatic Failover (PAF) by ClusterLabs, and in Part 2, we'll discuss the same high availability aspects using the Replication Manager for PostgreSQL clusters (repmgr) by 2ndQuadrant. Make sure to check back for Part 3, where we'll also cover Patroni by Zalando and compare all three open source solutions to help you determine the best fit for your application.</p>