Installing the PostgreSQL 8.2 RPMs on RHEL 5/CentOS 5

RedHat's latest enterprise distribution RHEL 5 includes PostgreSQL 8.1. While that's a perfectly servicable release, many people will want the latest 8.2 instead. RPM packages for current PostgreSQL releases are built and distributed on the postgresql.org web site; the RHEL ones for 8.2.4 I show installing here are at http://www.postgresql.org/ftp/binary/v8.2.4/linux/rpms/redhat/. These are sometimes referred to as the PostgreSQL Development Group or PGDG packages.

But actually installing these packages is kind of tricky. There is a guide that includes a section on doing a major version upgrade like this, but I disagree with one of its fundamental premises: that it's OK to remove a RPM package using the --nodeps option.

Much like --force, using --nodeps opens up the possibility that you will end up with an inconsistant package set should something go wrong when when you're installing things, and I don't consider that an acceptable way to work on a RHEL server. The situation that I've encountered in the past I try to avoid happens like this:

Instead, I like to understand what the dependencies are and see how they can be resolved without ever using --nodeps or --force. Here is a log of how I was able to remove the PostgreSQL 8.1 packages from a fresh installation and replace them with the postgresql.org PGDG RPMs for 8.2.4 without even using either of the options I consider dangerous.

My example here comes from a CentOS 5 installation rather than a genuine RHEL 5, as I was blazing this trail on my test system. I started by downloading all the new packages and seeing what I already had installed:

[root@jester rpms]# ls
compat-postgresql-libs-4-1PGDG.rhel5.i686.rpm  postgresql-plperl-8.2.4-1PGDG.i686.rpm
postgresql-8.2.4-1PGDG.i686.rpm                postgresql-plpython-8.2.4-1PGDG.i686.rpm
postgresql-contrib-8.2.4-1PGDG.i686.rpm        postgresql-pltcl-8.2.4-1PGDG.i686.rpm
postgresql-devel-8.2.4-1PGDG.i686.rpm          postgresql-server-8.2.4-1PGDG.i686.rpm
postgresql-docs-8.2.4-1PGDG.i686.rpm           postgresql-test-8.2.4-1PGDG.i686.rpm
postgresql-libs-8.2.4-1PGDG.i686.rpm
[root@jester rpms]# rpm -qa | grep postgresql
postgresql-python-8.1.9-1.el5
postgresql-8.1.9-1.el5
postgresql-pl-8.1.9-1.el5
postgresql-contrib-8.1.9-1.el5
postgresql-libs-8.1.9-1.el5
postgresql-server-8.1.9-1.el5
postgresql-tcl-8.1.9-1.el5
postgresql-test-8.1.9-1.el5
postgresql-docs-8.1.9-1.el5
Next I try to remove all the packages one by one; since I know a bit about the dependencies here I had a good idea what order to remove them in:
[root@jester rpms]# rpm -e postgresql-python
[root@jester rpms]# rpm -e postgresql-test
[root@jester rpms]# rpm -e postgresql-docs
[root@jester rpms]# rpm -e postgresql-tcl
[root@jester rpms]# rpm -e postgresql-pl
[root@jester rpms]# rpm -e postgresql-contrib
[root@jester rpms]# rpm -e postgresql-server
[root@jester rpms]# rpm -e postgresql
[root@jester rpms]# rpm -e postgresql-libs
error: Failed dependencies:
        libpq.so.4 is needed by (installed) apr-util-1.2.7-6.i386
        libpq.so.4 is needed by (installed) exim-4.63-3.el5.i386
        libpq.so.4 is needed by (installed) mod_auth_pgsql-2.0.3-2.3.1.i386
        libpq.so.4 is needed by (installed) dovecot-1.0-1.2.rc15.el5.i386
        libpq.so.4 is needed by (installed) perl-DBD-Pg-1.49-1.fc6.i386
        libpq.so.4 is needed by (installed) libdbi-dbd-pgsql-0.8.1a-1.2.2.i386 
	libpq.so.4 is needed by (installed) php-pgsql-5.1.6-12.el5.i386
        postgresql-libs is needed by (installed) libdbi-dbd-pgsql-0.8.1a-1.2.2.i386
So only the postgresql-libs package won't uninstall cleanly. I don't want to lose/reinstall all those packages. Since the main problem here is libpsq.so.4, let's take a look inside the packages to see if I can use the PGDG compat-postgresql-libs instead of postgresql-libs to provide that shared library (that's actually what the compat package is there for):
[root@jester rpms]# rpm -ql postgresql-libs
/usr/lib/libecpg.so.5
/usr/lib/libecpg.so.5.1
/usr/lib/libecpg_compat.so.2
/usr/lib/libecpg_compat.so.2.1
/usr/lib/libpgtypes.so.2
/usr/lib/libpgtypes.so.2.1
/usr/lib/libpq.so.4
/usr/lib/libpq.so.4.1
/usr/share/locale/af/LC_MESSAGES/libpq.mo
/usr/share/locale/cs/LC_MESSAGES/libpq.mo
/usr/share/locale/de/LC_MESSAGES/libpq.mo
/usr/share/locale/es/LC_MESSAGES/libpq.mo
/usr/share/locale/fr/LC_MESSAGES/libpq.mo
/usr/share/locale/hr/LC_MESSAGES/libpq.mo
/usr/share/locale/it/LC_MESSAGES/libpq.mo
/usr/share/locale/ko/LC_MESSAGES/libpq.mo
/usr/share/locale/nb/LC_MESSAGES/libpq.mo
/usr/share/locale/pl/LC_MESSAGES/libpq.mo
/usr/share/locale/pt_BR/LC_MESSAGES/libpq.mo
/usr/share/locale/ru/LC_MESSAGES/libpq.mo
/usr/share/locale/sk/LC_MESSAGES/libpq.mo
/usr/share/locale/sl/LC_MESSAGES/libpq.mo
/usr/share/locale/sv/LC_MESSAGES/libpq.mo
/usr/share/locale/tr/LC_MESSAGES/libpq.mo
/usr/share/locale/zh_CN/LC_MESSAGES/libpq.mo
/usr/share/locale/zh_TW/LC_MESSAGES/libpq.mo
[root@jester rpms]# rpm -qlp compat-postgresql-libs-4-1PGDG.rhel5.i686.rpm
/usr/lib/libpq.so.4
/usr/lib/libpq.so.4.1
[root@jester rpms]# rpm -i compat-postgresql-libs-4-1PGDG.rhel5.i686.rpm
        file /usr/lib/libpq.so.4 from install of compat-postgresql-libs-4-1PGDG.rhel5 conflicts with file from package postgresql-libs-8.1.9-1.el5
        file /usr/lib/libpq.so.4.1 from install of compat-postgresql-libs-4-1PGDG.rhel5 conflicts with file from package postgresql-libs-8.1.9-1.el5
So here's our fundamental problem: the installed postgresql-libs package provides the shared library libpq.so.4. The new RPM also provides these files, but we can't install it because the already installed RPM already has them. Here's what we can do: rpm provides a --replacefiles option just for situations like this. We can install the RPM using it:
[root@jester rpms]# rpm -iv --replacefiles compat-postgresql-libs-4-1PGDG.rhel5.i686.rpm
After doing that, now the libpq.so.4 files that are active on the system belong to the compat-postgresql-libs package instead of the old postgresql-libs one. When we go to erase the old postgresql-libs package now, that dependency will no longer apply:
[root@jester rpms]# rpm -e postgresql-libs
error: Failed dependencies:
        postgresql-libs is needed by (installed) libdbi-dbd-pgsql-0.8.1a-1.2.2.i386
So now I'm down to one package that depends on the postgresql-libs package. libdbi-dbd-pgsql allows Perl programs to access a PostgreSQL database; as long as no other packages depend on that one I can remove it, then just put it back afterwards--and even if I can't get to the repository to reinstall it (like in my sample disaster case mentioned at the beginning), I know I don't care that it will be broken temporarily. Let's try and uninstall it cleanly:
[root@jester rpms]# rpm -e libdbi-dbd-pgsql
[root@jester rpms]# rpm -e postgresql-libs
Great, the old postgresql-libs package is finally gone. For paranoia sake, confirm I didn't lose the PGDG libpq files by removing that:
[root@jester ~]# rpm -q compat-postgresql-libs
compat-postgresql-libs-4-1PGDG.rhel5
[root@jester rpms]# ls -l /usr/lib/libpq.so.4.1
-rwxr-xr-x 1 root root 422096 Dec  6 08:05 /usr/lib/libpq.so.4.1
Note that this was my first time through here. Were I to do this again on a more important server, now that I'm sure this path would work I would try upgrading postgresql-libs rather than deleting the old version at the point where this came up, potentially avoiding the step where I had to break the Perl dependency.

Now I'm clear to install all the rest of the new postgresql RPM files, then put back the libdbi-dbd-pgsql package:

[root@jester rpms]# rpm -iv postgresql*.rpm
warning: postgresql-8.2.4-1PGDG.i686.rpm: Header V3 DSA signature: NOKEY, key ID 20579f11
[root@jester rpms]# yum install libdbi-dbd-pgsql
Finally, confirm all the packages I expect are there:
[root@jester ~]# rpm -qa | grep postgresql
postgresql-libs-8.2.4-1PGDG
postgresql-test-8.2.4-1PGDG
postgresql-docs-8.2.4-1PGDG
postgresql-server-8.2.4-1PGDG
postgresql-plperl-8.2.4-1PGDG
compat-postgresql-libs-4-1PGDG.rhel5
postgresql-contrib-8.2.4-1PGDG
postgresql-pltcl-8.2.4-1PGDG
postgresql-plpython-8.2.4-1PGDG
postgresql-devel-8.2.4-1PGDG
postgresql-8.2.4-1PGDG
[root@jester ~]# rpm -q libdbi-dbd-pgsql
libdbi-dbd-pgsql-0.8.1a-1.2.2
And we're all done. You may want to return to the regular install guide at this point. Normally you'd next start the service and make sure it comes up at boot time with:
[root@jester ~]# chkconfig postgresql on
[root@jester ~]# service postgresql start
Copyright 2007 Gregory Smith. Last update 11/19/2007.