J’ai utilisé avec plaisir PostgreSQL 9.2 installé par homebrew avec beaucoup de plaisir. Ce matin un brew upgrade a fini par mettre à jour PostgreSQL 9.3, qui entraine une incompatibilité de format. Voici comment migrer ses bases de données de 9.2 à 9.3.

Note: Ces instructions sont valables uniquement si vous avez déjà installé PostgreSQL 9.3. Ne désinstallez pas encore PostgreSQL 9.2, il est nécessaire pour le processus de mise à jour.

Je n’avais pas encore remarqué le problème puisque mon ancienne version de PostgreSQL était encore en fonctionnement. Mais en redémarrant, la nouvelle version n’a jamais démarré, et j’ai trouvée ces erreurs dans : /usr/local/var/postgres/server.log :

FATAL: database files are incompatible with server
DETAIL: The data directory was initialized by PostgreSQL version 9.2, which is not compatible with this version 9.3.1.

La solution ? Éteindre le serveur, migrer le dossier de données vers le nouveau format compatible avec PostgreSQL 9.3et redémarrer.

1. Éteindre PostgreSQL

Puisque PostgreSQL a été installé à l’aide de homebrew, il est piloté par le launchd system d’Apple, la première étape est donc de dire à launchd de stopper l’ancienne version : launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

2. Créer le dossier pour la nouvelle version de PostgreSQL

Le processus de mise à jour requiert que l’on migre les anciennes données vers un nouveau dossier. Il faut donc créer un nouveau dossier de données. Puisqu’homebrew a déjà mis à jour vers PostgreSQL, la commande initdb est fonctionnelle.

initdb /usr/local/var/postgres9.3 -E utf8

3. Lancer la migration à l’aide pg_upgrade

Heureusement, PostgreSQL est livré avec un utilitaire en ligne de commande pour effectuer la migration. Il faut spécifié le dossier des anciennes données et le binaire (-d et -b) ainsi que le nouveau dossier et le nouveau binaire (-D et -B) et hop c’est parti !

pg_upgrade 
-d /usr/local/var/postgres 
-D /usr/local/var/postgres9.3 
-b /usr/local/Cellar/postgresql/9.2.4/bin/ 
-B /usr/local/Cellar/postgresql/9.3.1/bin/ 
-v

Une fois terminé, vous verrez, le message suivant :

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    analyze_new_cluster.sh

Running this script will delete the old cluster's data files:
    delete_old_cluster.sh

4. Déplacer le nouveau dossier en place

Une fois la migration effectuée, il faut renommer le dossier à sa place :

cd /usr/local/var
mv postgres postgres9.2.4
mv postgres9.3 postgres

5. redémarrer la nouvelle version de PostgreSQL

Comme j’ai installé le gem lunchy (cf installer PostgreSQL sur mac avec Homebrew), voici la commande :

lunchy start postgresql

Sinon :

launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

On vérifie la version de PostgreSQL :

psql postgres -c "select version()"

6. On fait le ménage dans les brew

brew cleanup postgresql

7. Si vous utilisez Ruby on Rails, recompilez le gem pg

Finalement, une nouvelle version de PostgreSQL veut dire que des nouveaux binaires vont être utilisé par le gem pg. Donc pour faire tourner PostgreSQL avec rails il faut forcer une réinstallation du gem pg :

gem uninstall pg
# Choose to remove "all versions"
# Re-install to force a recompile
gem install pg

Et voila !