534 words, ~3 min read

Install multiple PostgreSQL versions from src on Arch

On Arch Linux if you need multiple versions of PostgreSQL installed at the same time. Say because you are working on a software product that is currently locked into an older PostgreSQL version while also working on another product that is using a new PostgreSQL version. You are kinda screwed, at least in terms of being able to do it from the packagement management system.

They effectively provide the latest version and then also provided through the user packages you can get a previous version to facilitate the upgrade process that PostgreSQL requires.

So we have to look for a solution outside of the normal package management system. I tried looking for solutions like a PostgreSQL Version Manager similar in concept to NVM (Node Version Manager) or RVM (Ruby Version Manager), etc. There were a couple that seemed not fully baked and just seemed like a bunch of unnecessary layers of crap.

The only alternative I could find was to use Docker which I also didn't want to do as it is a bunch more layers of crap that I didn't want to deal with.

We should totally be able to install multiple versions of PostgreSQL side by side on Arch Linux and it shouldn't be a problem. And guess what. I was correct. The following are my notes from when I set this up.

The Setup

In the below I specify a custom prefix of /usr/local/pgsql/15.13 instead of the default of /usr/local/pgsql because I want to be able to have multiple postgresql versions installed at the same time.

Additionally, I specified the openssl-1.1 which is an additional package you can install on Arch linux beside the normal openssl 3.6.0, because the pgcrypto extension depends on things that were provided by openssl 1.1 but were removed in openssl 3.x.

Beyond that I specified --with-uuid=e2fs because on Arch linux the libuuid is provided and not the ossp-uuid library. I needed to specify this so that when I built the uuid-ossp extension in contrib it could properly build.

Out side of that I simply followed the directions in the PostgreSQL documentation with the following configure command to take the above into account.

./configure --prefix=/usr/local/pgsql/15.13 --with-openssl --with-includes=/usr/include/openssl-1.1 --with-libraries=/usr/lib/openssl-1.1 --with-uuid=e2fs
make

Note: During the process the build would fail. And I would look at why it was failing and it was always simply a dependency that was not installed. I would install the package from the package system and then re-run the build. I did this a handfull of times to get the build to fully succeed. I also followed the same process for the extensions that I installed as well.

Start/Stop Versions

You don't really have two versions running at the same time in this setup. So the key becomes how do you start and stop the different versions of PostgreSQL that you have installed. The way I addressed this was simply to whip up some quick shell scripts to start and stop it. For example I created a ~/bin/pgsql_start_15.13 and ~/bin/pgsql_stop_15.13 to facilitate starting and stopping that specific version of PostgreSQL.

The following is the content from ~/bin/pgsql_start_15.13.

#!/usr/bin/env sh

PGDATA="/usr/local/pgsql/15.13/data"
PGCTL="/usr/local/pgsql/15.13/bin/pg_ctl"
LOGFILE="$PGDATA/logfile"

# go to directory pg_ctl has perms to so that when
# pg_ctl tries to return to the directory it doesn't
# error.
cd /tmp || exit 1

# Check if PostgreSQL is already running
if sudo -u postgres $PGCTL -D "$PGDATA" status > /dev/null 2>&1; then
    echo "PostgreSQL is already running."
else
    echo "Starting PostgreSQL..."
    sudo -u postgres $PGCTL -D "$PGDATA" -l "$LOGFILE" start
    echo "PostgreSQL started."
fi

The following is the content from the ~/bin/pgsql_stop_15.13.

#!/usr/bin/env sh

# Variables
PGDATA="/usr/local/pgsql/15.13/data"
PGCTL="/usr/local/pgsql/15.13/bin/pg_ctl"

# go to directory pg_ctl has perms to so that when
# pg_ctl tries to return to the directory it doesn't
# error.
cd /tmp || exit 1

# Check if PostgreSQL is running
if sudo -u postgres $PGCTL -D "$PGDATA" status > /dev/null 2>&1; then
    echo "Stopping PostgreSQL..."
    sudo -u postgres $PGCTL -D "$PGDATA" stop
    echo "PostgreSQL stopped."
else
    echo "PostgreSQL is not running."
fi