Using pg_upgrade

This guide describes how to perform a major-version upgrade of an AgensGraph cluster with pg_upgrade — for example from AgensGraph 2.16 (PostgreSQL 16) to AgensGraph 2.17 (PostgreSQL 17). The steps below were verified by upgrading a 2.16 cluster containing a graph and confirming that the graph, labels, vertices, edges, and properties were preserved. For a complete worked example with real commands and output, see the Demo.

How pg_upgrade works

pg_upgrade performs an in-place major-version upgrade without dumping and reloading the data. It creates the new cluster’s system catalogs and then reuses the existing user data files, so the upgrade is fast even for large databases. Because AgensGraph stores graphs as ordinary PostgreSQL schemas and tables, graph data is migrated the same way relational data is.

Before you begin

  • Install AgensGraph 2.17 in a separate location from the existing 2.16 installation — do not overwrite it. pg_upgrade needs both sets of binaries, and keeping 2.16 in place lets you roll back.

  • Disk space. By default pg_upgrade copies the data files, so you need room for a second copy. The --link option uses hard links instead (almost instant, little extra space) but requires both data directories to be on the same filesystem, and rollback is no longer possible once the new server starts.

  • Match the new installation to the old one. Any external module the old cluster uses (for example pgvector) must also be installed in the 2.17 installation before upgrading. AgensGraph’s graph features are built into the server itself, so there is no extension to recreate.

  • Run every command as the operating-system user that owns the data directory (the user that installed/runs AgensGraph).

The commands below use these variables; set them for your environment:

# old (2.16) and new (2.17) installation directories
export OLD=/usr/local/agensgraph-2.16
export NEW=/usr/local/agensgraph-2.17
# data directories
export OLDDATA=$OLD/data
export NEWDATA=$NEW/data

Step 1 — Stop the old server

pg_upgrade requires both clusters to be stopped while it runs.

$OLD/bin/pg_ctl -D $OLDDATA stop

Step 2 — Initialize the new cluster

Create an empty 2.17 cluster. Use the same superuser, encoding, and locale as the old cluster (here the superuser is postgres):

$NEW/bin/initdb -D $NEWDATA -U postgres --encoding=UTF8

Step 3 — Check compatibility

Run pg_upgrade with --check first. It validates the two clusters and changes nothing:

$NEW/bin/pg_upgrade \
  -b $OLD/bin -B $NEW/bin \
  -d $OLDDATA -D $NEWDATA \
  -U postgres --check

A successful check ends with:

Performing Consistency Checks
-----------------------------
Checking cluster versions                                     ok
...
Checking for new cluster tablespace directories               ok

*Clusters are compatible*

Run pg_upgrade as a database superuser. Pass the superuser role with the -U option — for example, if the cluster’s superuser is postgres, use -U postgres. By default pg_upgrade connects as your operating-system user, which is usually not a database role.

Step 4 — Run the upgrade

Run the same command without --check:

$NEW/bin/pg_upgrade \
  -b $OLD/bin -B $NEW/bin \
  -d $OLDDATA -D $NEWDATA \
  -U postgres

It finishes with:

Upgrade Complete
----------------

To use hard links instead of copying the data files, add --link to both the check and the upgrade commands.

Step 5 — Start the new server

$NEW/bin/pg_ctl -D $NEWDATA -l $NEW/logfile start

Step 6 — Post-upgrade tasks

pg_upgrade does not transfer optimizer statistics, so plan quality will be poor until they are rebuilt. Regenerate them:

$NEW/bin/vacuumdb -U postgres --all --analyze-in-stages

Once you have confirmed the upgraded cluster works correctly, delete the old cluster’s data files using the script pg_upgrade generated in the directory you ran it from:

./delete_old_cluster.sh

Rolling back

If you upgraded in the default (copy) mode and have not yet run delete_old_cluster.sh, the old 2.16 data directory is untouched. To roll back, stop the new server and start the old one again:

$NEW/bin/pg_ctl -D $NEWDATA stop
$OLD/bin/pg_ctl -D $OLDDATA -l $OLD/logfile start

If you upgraded with --link, rollback is not possible once the new server has started, because the two clusters share data files — restore from a backup instead.

pg_upgrade options reference

Option

Description

-b, --old-bindir

bin directory of the old AgensGraph (env: PGBINOLD)

-B, --new-bindir

bin directory of the new AgensGraph (env: PGBINNEW)

-d, --old-datadir

old cluster data directory (env: PGDATAOLD)

-D, --new-datadir

new cluster data directory (env: PGDATANEW)

-U, --username

install superuser to connect as (env: PGUSER)

-c, --check

only check compatibility; make no changes

-k, --link

hard-link data files instead of copying

-j, --jobs

number of simultaneous processes to use

-p / -P

port for the old / new cluster during the run

-r, --retain

keep the SQL and log files after a successful run

-v, --verbose

verbose output

Any of the directory and connection options can also be supplied through the environment variables shown above, in which case the corresponding command-line flag can be omitted.