Yet another alternative is to use symbolic links for upgrades. This concept is quite simple: install a package into some directory and symlink to it. So, if some software was expected in the directory /usr/local/foo, you could simply install the first version of the software in the directory /usr/local/foo-1.0 and point to it from the expected directory:

panic# ln -sf /usr/local/foo-1.0 /usr/local/foo

If later you want to install a second version of the software, install it into the directory /usr/local/foo-2.0 and change the symbolic link to this new directory:

panic# ln -sf /usr/local/foo-2.0 /usr/local/foo

Now if something goes wrong, you can always switch back with:

panic# ln -sf /usr/local/foo-1.0 /usr/local/foo

In reality, things aren't as simple as in this example. It works if you can place all the software components under a single directory, as with the default Apache installation. Everything is installed under a single directory, so you can have:

/usr/local/apache-1.3.17
/usr/local/apache-1.3.19

and use the symlink /usr/local/apache to switch between the two versions.

However, if you use a default installation of Perl, files are spread across multiple directories. In this case, it's not easy to use symlinks—you need several of them, and they're hard to keep track of. Unless you automate the symlinks with a script, it might take a while to do a switch, which might mean some downtime. Of course, you can install all the Perl components under a single root, just like the default Apache installation, which simplifies things.

Another complication with upgrading Perl is that you may need to recompile mod_perl and other Perl third-party modules that use XS extensions. Therefore, you probably want to build everything on some other machine, test it, and when ready, just untar everything at once on the production machine and adjust the symbolic links.