Managing PostgreSQL Process on Ubuntu - service, pg_ctl and pg_ctlcluster

If you've ever dealt a bit more seriously with PostgreSQL, and gone through different online articles and examples, chances are that you've ran to pg_ctl command. Being Ubuntu user, I've often wondered what is the difference between starting PostgreSQL by using Ubuntu-native service command and pg_ctl. After some research I've found out what is the catch, and here I'll share this with you.


When you install PostgreSQL on Ubuntu from apt package repository, you get Ubuntu service script automatically installed, and convenience to start / stop / restart / status... postgresql service in a way you are accustomed to:

$ service postgresql start
$ service postgresql stop
$ update-rc.d postgresql disable
$ update-rc.d postgresql enable

Then you'll see that in majority of resources pg_ctl command is used instead, and you start getting scared if you are doing something wrong. Well, let's demystify this by understanding the differences.

There are few things you should know about service command used above:

  • It affects all PostgreSQL database clusters on machine (if you have more than one), and all PostgreSQL versions, if you have more than one running side-by-side;
  • PostgreSQL service script internally uses pg_ctlcluster command, meaning that even if you execute service command, internally it executes pg_ctlcluster, and as will be shown later - everything finishes by executing pg_ctl.


Comparing to service command, pg_ctl offers you more options and flags, and most importantly - it offers you a way to start / stop / restart particular database cluster, without affecting any other clusters, i.e.:

$ pg_ctl -w -D /var/lib/postgresql/9.5/main start

Keep calm, I know that the previous command won't run on Ubuntu - it is not added to PATH. But you can run it by using its full path (/usr/lib/postgresql/9.5/bin/pg_ctl), or you can use its wrapper - pg_ctlcluster explained below. Another important thing to say is that if you've tried to execute pg_ctl without specifying its full path, you've probably got something like:

$ The program 'pg_ctl' is currently not installed. To run 'pg_ctl' please ask your administrator to install the package 'postgres-xc'

Don't do that! Don't install postgres-xc! It is nothing more than hugely misleading, deeply wrong message.

There are few things you should know about pg_ctl command:

  • At the end of the day it is the command that actually does do job. As will be shown later, pg_ctlcluster command is nothing more than a pg_ctl wrapper, meaning that it internally executes pg_ctl command.
  • It is version specific, meaning that if you have multiple PostgreSQL versions installed on the same machine - you'll also have multiple pg_ctl versions. You should always pick the right version of the command to use.


pg_ctlcluster is Ubuntu-specific pg_ctl wrapper. The original documentation is perfectly clear: "It determines the cluster version and data path and calls the right version of pg_ctl with appropriate configuration parameters and paths." Example:

$ pg_ctlcluster 9.5 main status

Significant characteristics of pg_ctlcluster command is that (as you can see above), it forces you to specify PostgreSQL version (i.e. 9.5) and database cluster (i.e. main).


We can conclude that if you have only one database cluster on the machine, service and pg_ctlcluster (thus pg_ctl also) commands are completely equivalent. For example, there's no any difference between the following lines:

$ service postgresql restart
$ pg_ctlcluster 9.5 main restart

So you haven't did anything wrong while using service command. Even if you have multiple database clusters, the previous two lines are identical from the main database cluster's point of view, and again you haven't did anything wrong except restarting other database clusters needlessly.


In fact the commands are so equivalent that you can use them interchangeably. For example, you can start a database cluster by using pg_ctlcluster and later stop it by using service, and vice versa.


Submitted byMittal (not verified) on Thu, 02/16/2017 - 13:21

Hey I came across this blog while struggling with pg_ctl and pg_ctlcluster on RHEL and Ubuntu resp. :)
Thanks for the writeup

May I ask a couple of more questions ;)
I need to move postgresql from RHEL 7.2 to Ubuntu 16.04
- The admin who did the setup on RHEL made many changes to postgresql.service file on RHEL. On Ubuntu there are multiple .service files for postgres. And there is an /etc/init.d file too
Where to make the changes ?
- The service file on postgresql starts the server with different DB location and port, defined in service file. Also issues 'postgresql-setup initdb' with that file. Where to make similar changes on Ubuntu ?

To add to the agony, I need to put all of this in a script :(

Add new comment

Anonymous comments require solving captcha, and waiting for administrator's approval.