dimanche 5 janvier 2014

Postgresql upgrade 2

Dans l'article Postgresql upgrade, nous avons traité de la migration des données postgresql lors du passage de Fedora 19 à Fedora 20.
Cette fois, nous allons considérer le même problème pour une autre distribution, à l’occurrence "Chakra". Cependant le contenu de cet article pourrait être utilisé dans d'autres cas.

En tant qu'utilisateur postgres, sauvegardons les anciennes données sous un nom qui rappelle l'ancienne version de postgresql:

[toto@rigel ~]$ su -
Mot de passe : 
[root@rigel ~]# su - postgres
[postgres@rigel ~]$ mv /var/lib/postgres/data/ /var/lib/postgres/data_9.2/

Dans la foulée nous pouvons créer le nouveau cluster:

[postgres@rigel]$ initdb --locale fr_FR.utf8 -E UTF8 -D /var/lib/postgres/data

Notons que au démarrage de postgresql.service, il est prévu le lancement d'un script qui initialise la database si celle-ci ne l'est pas encore:

[toto@rigel ~]$ grep "ExecStartPre" /usr/lib/systemd/system/postgresql.service 
ExecStartPre=/usr/lib/systemd/scripts/postgresql-initdb

Donc pour coller au plus près de ce qui a été fait auparavant, nous aurions pu, au lieu d'utiliser la commande initdb, procéder comme ceci:

[root@rigel ~]# /usr/lib/systemd/scripts/postgresql-initdb

à condition d'avoir pris quelques précautions.
La commande suivante:

[toto@rigel ~]$ head -5 /usr/lib/systemd/scripts/postgresql-initdb
#!/bin/sh

set -e


. /etc/conf.d/postgresql

montre que le script utilise /etc/conf.d/postgresql.
L'examen de ce fichier nous conduit à devoir y remplacer, avant l'exécution du script,  en_US par ce qui convient:

[root@rigel ~]# sed -i 's/en_US/fr_FR/' /etc/conf.d/postgresql

Quelle que soit la méthode employée pour initialiser la database, il reste ensuite à utiliser  pg_upgrade pour procéder à la migration. Avec Fedora, pg_upgrade venait avec le paquet postgresql-upgrade qui fournissait également les commandes relatives à l'ancienne version de postgresql.
Rien de tel cette fois, pg-upgrade vient avec le paquet postgresql:

[toto@rigel ~]$ pacman -Qo $(which pg_upgrade)
/usr/bin/pg_upgrade appartient à postgresql 9.3.2-1

Interrogeons le paquet à la recherche d'informations:

[toto@rigel ~]$ pacman -Qi postgresql 
Nom                   : postgresql
Version               : 9.3.2-1
Description           : A sophisticated object-relational DBMS
Architecture          : x86_64
URL                   : http://www.postgresql.org/
Licences              : custom:PostgreSQL
Groupes               : --
Fournit               : akonadi-backend
Dépend de             : postgresql-libs>=9.3.2  krb5  libxml2  readline>=6.0  openssl>=1.0.0
Dépendances opt.      : python3: for PL/Python support [installé]
                        perl: for PL/Perl support [installé]
                        tcl: for PL/Tcl support [installé]
                        postgresql-old-upgrade: upgrade from previous major version using pg_upgrade    

Nous avons besoin de postgresql-old-upgrade,  mais cette dépendance optionnelle semble ne pas être fournie.
Qu'à cela ne tienne: allons rechercher l'ancien paquet dans le cache de pacman:

[toto@rigel ~]$ cp /var/cache/pacman/pkg/postgresql-9.2.4-2-x86_64.pkg.tar.xz Downloads/
[toto@rigel ~]$ cd Downloads/
[toto@rigel Downloads]$ mkdir postgresql
[toto@rigel Downloads]$ tar xpvf postgresql-9.2.4-2-x86_64.pkg.tar.xz -C postgresql

Évidemment si le cache a été vidé, au lieu de simplement utiliser la commande cp, il faudra télécharger le paquet ad hoc (postgresql-9.2.4-2-x86_64.pkg.tar.xz)

Après extraction du paquet, exécutons pg_upgrade (en tant qu'utilisateur postgres) et puis recopions ce qui convient:

[postgres@rigel ~]$ pg_upgrade -b /home/toto/Downloads/postgresql/usr/bin -B /usr/bin/ -d data_9.2/ -D data
[postgres@rigel ~]$ cp data_9.2/pg_hba.conf data
[postgres@rigel ~]$ cp data_9.2/pg_ident.conf data

Il reste éventuellement à adapter le fichier /var/lib/postgres/data/postgresql.conf et en tout cas à décommenter la ligne

port = 5432  

avant de démarrer le serveur comme ceci:


[root@rigel ~]# systemctl start postgresql.service  

ou comme cela

[postgres@rigel ~]$ pg_ctl start -D /var/lib/postgres/data
serveur en cours de démarrage
[postgres@rigel ~]$ LOG:  le système de bases de données a été arrêté à 2014-01-04 16:15:19 CET
LOG:  lancement du processus autovacuum
LOG:  le système de bases de données est prêt pour accepter les connexions

La deuxième commande donne plus d'infos en cas de problème.
Par exemple on peut avoir:

[postgres@rigel ~]$ pg_ctl start -D /var/lib/postgres/data
serveur en cours de démarrage
[postgres@rigel ~]$ FATAL:  n'a pas pu créer le fichier verrou « /run/postgresql/.s.PGSQL.5432.lock » : Aucun fichier ou dossier de ce type

alors que la commande systemctl ne fournit aucun retour bien que le service ne soit pas démarré.
Dans ce cas, il faut automatiser la création du dossier /run/postgresql en procédant comme indiqué ici.
Le dossier sera disponible après redémarrage.