![]() |
Since version 9.0, PostgreSQL has featured the pg_upgrade tool to automate the process of transferring data to a new cluster data version. This guide covers its use on DICE SL7 servers, but is transferrable to any modern LCFG environment.
It's worthwhile checking the PostgreSQL Release Notes for each version involved in the upgrade. It is often also worth reading the migration notes for each major version between old and new. The pg_upgrade
tool and source or target server versions could have unique limitations or provisos which are unlikely to be obvious without reading the notes.
These steps, or some equivalent thereof, must be followed in strict order.
om postgresql backup preupgrade
.sql.gz
file.
#include <dice/options/postgresql-oldver.h> /* old version */
#include <dice/options/postgresql-newver.h> /* new version */
$ om updaterpms run
$ om postgresql stop
postgres
processes are still running with $ ps -ef | grep postgres
).
#include <dice/options/postgresql-oldver.h> /* old version */
#include <dice/options/postgresql-newver-server.h> /* new version */
postgresql.pgdata
has the value /disk/scratch/db
I would recommend something like /disk/scratch/dbNN
where NN is the new version number. Add this to the machine profile, also:
!postgresql.pgdata mSET(/path/to/new/cluster) /* e.g. /disk/scratch/dbNN */
$ om updaterpms run
(verifying that the new postgresql packages are installed, and starting any new components (other than postgresql) such as rmirrorclient
)$ om postgresql start
(you will see initdb
being run on a new cluster).
qxprof postgresql.pglogdir
.$ om postgresql stop
postgres
, as given by qxprof postgresql.pgowner
), and... postgres$ mv /path/to/old/cluster /path/to/old/cluster.old
/usr/pgsql-NN/bin
and you can get a hint by checking for the locations of utilities as defined by qxprof postgresql | grep bin
:postgres$ cd /tmp/
(or some other user-writable directory)postgres$ /path/to/new/binaries/pg_upgrade \
-d /path/to/old/cluster.old -D /path/to/new/cluster \
-b /path/to/old/binaries -B /path/to/new/binaries
The database cluster has been upgraded. If the database is to be returned to its previous location, now is the time to do it:
postgres$ mv /path/to/new/cluster /path/to/old/cluster
!postgresql.pgdata mSET(/path/to/new/cluster)
Don't forget to:
$ om postgresql start
to start the database server in its new version.analyze_new_cluster.sh
script created by the upgrade script, as the postgres user.postgresql-newver-server.h
header.postgresql-xxx
headers from the machine profile once they are no longer required.Optional optimisations:
pgdata
directory in LCFG; just move the existing dir after step 2.dice/options/postgresql-newver.h
, then just add -server.h
at step 3.The following procedure allows you to upgrade a server and its data from an older version of PostgreSQL on one host, to a newer version on another host, with less than a minute's downtime (and typically a half-hour window of read-only access to data whilst clients' DNS caches update). The procedure works without the upgrade step, of course, but it's particularly useful during upgrade.
PostgreSQL's data structures are particularly amenable to incremental transfer using rsync
, which allows you to perform an initial, slow "dirty" copy of a running database, followed by a near-instantaneous final transfer of data with only the briefest of downtime. So, on the running database server oldhost
:
postgres$ rsync -av --delete /disk/data/db/ <you>@newdb:/disk/data/olddb/
You should repeat the above step as close in time to the next steps as possible, to decrease the length of time taken by the final transfer.
Then, when you're ready to commit to the upgrade, perform the following steps on the same, existing server:
!postgresql.options mADD(default_transaction_read_only)
postgresql.option_default_transaction_read_only on
$ om postgresql stop
postgres$ rsync -av --delete /disk/data/db/ <you>@newdb:/disk/data/olddb/
$ om postgresql start
An alternative to the rsync
command above is possible where there is a replication relationship (master → slave) between old and new servers. In this case one can take advantage of the the postgresql basebackup
command which allows a copy to be taken of the data without downtime on the master. However, given that both the default_transaction_read_only
and replication setup steps still involve a restart of the master, it is not recommended over a simple rsync.
[1] Clients can in theory override this setting and modify data, but it is expected that users will be informed of the period of read-only service. Read-only status can be enforced by careful application of DENY
statements but this is considered unnecessary for the purposes of a scheduled upgrade.
The PostgreSQL extension system allow registered extensions to be upgraded automatically and as a result no special action is usually necessary for most extensions, so long as both versions of the extension library are installed during upgrade.
Upgrades should be handled automatically by the postgresql-<extname>.h
header if they are loaded after all postgresql-version headers. If you
can't completely control the header ordering (e.g. pgresearch.inf
where postgresql versions are determined by a stable header) you may follow the
protocol below:
/* predefine new software header before main header */
#include <dice/options/postgresql-newver.h>
/* (existing header, includes oldver-server and postgis headers) */
#include <dice/options/postgresql-research-server.h>
/* post-define server header as per upgrade procedure */
#include <dice/options/postgresql-newver-server.h>
Before (and periodically after) every PostgreSQL upgrade it is worth checking to make sure that your extension is the latest version to avoid the risk of having to perform future PostgreSQL upgrades in multiple leaps.
To upgrade extensions (within the same PostgreSQL version) you will
sometimes need both software versions installed simultaneously: this doesn't
map well to an RPM world, which will require something like
# rpm -iv --force extension-oldver.arch.rpm extension-newver.arch.rpm
/* and on the machine profile, if changes must persist */
!profile.packages mEXTRA(
+extension-oldver/arch:i
+extension-newver/arch:i
)
Remembering to remove the old version as soon as upgrade is comfortably complete.
9.5 makes a further change to the default settings of the gss
authtype. Assuming you're upgrading from ≥9.3 and using the gss
authtype already then for seamless forward compatibility it's recommended that, before upgrade, the following backwards-compatible auth options are added to each HBA entry:
/* For each HBA line with the gss type */
sslauthtype_tag gss
/* Add the following auth options: */
!sslauthopts_tag mADD(include_realm=0 krb_realm=<%kerberos.realm%>)
This preserves the old behaviour of connecting clients, and restricts the connection to the current realm only.
If your requirements are more complex, for example allowing clients from non-default realms to connect, or you are planning a new database server from scratch, these instructions need not apply: servers configured without the above will present connecting users with qualified kerberos principal names, i.e. user@MY.REALM
and new installations merely need to take this change into account.
Please contact us with any
comments or corrections.
Unless explicitly stated otherwise, all material is copyright The University of Edinburgh |
![]() |