Upgrading a PostgreSQL installation

Installing the new package

When we installed the dev-db/postgresql-server package we specified a particular major version using the :9.0 suffix after the package atom. This ensured that only packages from the 9.0 series would be installed or upgraded automatically. It also ensured that when a new major version becomes available we will continue to use a compatible version until we decide to upgrade and issue the relevant commands. This is particularly important as otherwise an emerge --depclean action could potentially remove our running instance before we have performed the required upgrade procedures.

The main consequence of this decision is that when a new major version becomes available we will be required to install this new slotted package manually. Assuming that you followed this guide some time ago and installed an 8.4 series server then you will need to issue the following command to install the new version 9.0 series packages.

lisa emerge -pv postgresql-server:9.0
 
These are the packages that would be merged, in order:

Calculating dependencies... done!
[ebuild      ] dev-db/postgresql-base-9.0.3  USE="ldap nls pam readline ssl zlib -doc -kerberos -pg_legacytimestamp -threads"
[ebuild      ] dev-db/postgresql-server-9.0.3  USE="nls perl python -doc -pg_legacytimestamp -tcl -uuid -xml"

Configuring the new database instance

Once the new packages have been installed we can begin the upgrade procedure by configuring the new database instance to be compatible with the existing database server. This can easily be accomplished by copying the relevant changes from /etc/conf.d/postgresql-8.4 to /etc/conf.d/postgresql-9.0. Care should be taken to ensure that the same settings are used for the PG_INITDB_OPTS in both instances or the upgrade procedure will fail. It is also important that the PGDATA variable points to a different location in both instances as the files used by the new version are incompatible with those used by the old version and cannot coexist in the same path.

Caution:
If you are upgrading from version 8.4 then some of the configuration options have changed in the most recent version so a straight copy of the old configuration file should not be performed. If you require more information on the meaning of the new options then the section of this guide may be useful.
 

Now that we have configured the new instance we can initialise the new database using the commends shown in the example below. The first command sets the active instance of postgresql to version 9.0 while the second creates the new set of empty system databases.

lisa eselect postgresql set 9.0
lisa emerge --config dev-db/postgresql-server:9.0

When the above commands have completed successfully we can copy the host based authentication file from the old database instance to the new database instance we created in the previous step. Assuming that you have used the same database location as we did (in the section of this guide) the command below will perform this task.

lisa cp /mnt/databases/postgres/8.4/pg_hba.conf /etc/postgresql-9.0/pg_hba.conf

You will also need to modify the new /etc/postgresql-9.0/postgresql.conf configuration file to reflect the changes you made when configuring the original database instance. It is often useful to view a list of the differences between the old and new configuration files as an aide-mémoire. This can be easily achieved using the diff utility as shown below.

lisa diff -iwu /mnt/databases/postgres/8.4/postgresql.conf /etc/postgresql-9.0/postgresql.conf

Migrating data to the new database instance

Assuming that the steps thus far have been completed successfully we can now stop the old database server in preparation for the data migration. If there are any clients connected to the old instance then they should be gracefully disconnected first for maximum stability.

lisa /etc/init.d/postgresql-8.4 stop

Once the old database server has stopped we can switch to the postgres user account and perform the database upgrade using the pg_upgrade utility provided by the new version. As you can see in the example below the pg_upgrade utility requires the paths to the old database instance and the paths to the new database instance to be specified.

lisa su - postgres
postgres@lisa /usr/lib/postgresql-9.0/bin/pg_upgrade --old-datadir /mnt/databases/postgres/8.4 --old-bindir /usr/lib/postgresql-8.4/bin --new-datadir /mnt/databases/postgres/9.0 --new-bindir /usr/lib/postgresql-9.0/bin -u pgadmin
postgres@lisa exit

After the pg_upgrade utility has successfully migrated the data from the old database instance to the new database instance we can start the new database server and, assuming it starts correctly, add it to the default runlevel. We should also remove the old database server from the default runlevel so that it is no longer started automatically.

lisa /etc/init.d/postgresql-9.0 start
lisa rc-update add postgresql-9.0 default
 * service postgresql-9.0 added to runlevel default 
lisa rc-update del postgresql-8.4
 * service postgresql-8.4 removed from runlevel default 

Although the above steps have migrated the data from the old instance to the new instance the index and table statistics remain uninitialised. For optimal performance of the new database instance these statistics need to be recreated as shown below.

lisa su - pgadmin
pgadmin@lisa vacuumdb --all --analyze-only
pgadmin@lisa exit

Uninstalling the old packages and dependencies

After the databases have been successfully migrated there is no longer a need for the old dev-db/postgresql-server package or any of the dependencies required solely by this package. The commands in the example below can be used to ensure that these packages have been removed from the system.

lisa emerge -C postgresql-server:8.4
lisa emerge --depclean