pg_upgrade — met à jour une instance de serveur PostgreSQL™
pg_upgrade -b ancien_dir_exec -B nouveau_dir_exec -d ancien_dir_donnees -D nouveau_dir_donnees [option...]
pg_upgrade (auparavant appelé pg_migrator) permet la mise à jour des fichiers de données d'une version majeure de PostgreSQL™ vers une autre version majeure sans nécessiter la partie sauvegarde/restauration typiquement requise pour les mises à jour majeures, par exemple de la version 8.4.7 à la version majeure courante de PostgreSQL™. Cet outil n'est pas utile pour les mises à jour mineures, par exemple pour une migration de la 9.0.1 à la 9.0.4.
Les versions majeures de PostgreSQL ajoutent régulièrement de nouvelles fonctionnalités qui modifient la composition des tables systèmes. Par contre, le format de stockage des données change rarement. pg_upgrade utilise cette information pour réaliser des mises à jour rapides en créant les nouvelles tables systèmes et en réutilisant les anciens fichiers de données utilisateurs. Si une version majeure future change le format des données d'une façon qui rend l'ancien format illisible, pg_upgrade ne sera pas utilisable pour ces mises à jour. (La communauté tente d'éviter ce type de situation.)
pg_upgrade fait de son mieux pour s'assurer que les clusters, ancien et nouveau, soient compatibles binairement, c'est-à-dire en vérificant les paramètres de temps modifiables à la compilation, en incluant les binaires 32/64 bits. Il est important que tout module externe soit aussi compatible binairement, bien que cela ne soit pas vérifié pg_upgrade.
pg_upgrade supporte la mise à jour de version 8.3.X et ultérieures vers la dernière version majeure de PostgreSQL™, ceci incluant les versions intermédiaires (snapshots) et les versions alpha.
pg_upgrade accepte les arguments suivant en ligne de commande :
indique le répertoire des exécutables de l'ancienne instance ; variable d'environnement PGBINOLD
indique le répertoire des exécutables de la nouvelle instance ; variable d'environnement PGBINNEW
vérifie seulement les instances, ne modifie pas les données
indique le répertoire des données de l'ancienne instance ; variable d'environnement PGDATAOLD
indique le répertoire des données de la nouvelle instance ; variable d'environnement PGDATANEW
utilise des liens plutôt que de copier les fichiers vers la nouvelle instance
options à fournir directement à l'ancienne commande postgres
options à fournir directement à la nouvelle commande postgres
indique le numéro de port de l'ancienne instance ; variable d'environnement PGPORTOLD
indique le numéro de port de la nouvelle instance ; variable d'environnement PGPORTNEW
conserve les fichiers SQL et les journaux applicatifs, y compris en cas d'exécution réussie.
superutilisateur de l'instance ;variable d'environnement PGUSER
active les traces internes
affiche la version puis quitte
affiche l'aide puis quitte
Ci-après sont décrites les étapes permettant de réaliser une mise à jour avec pg_upgrade :
Si nécessaire, déplacez l'ancienne instance
Si vous utilisez un répertoire d'installation spécifique à la version, par exemple /opt/PostgreSQL/9.1, vous n'avez pas besoin de déplacer l'ancien répertoire de l'instance. Les installeurs one-click utilisent tous des répertoires d'installation spécifiques à la version.
Si votre répertoire d'installation n'est pas spécifique à la version, par exemple /usr/local/pgsql, il est nécessaire de déplacer le répertoire d'installation actuelle de PostgreSQL pour qu'il n'interfère pas avec la nouvelle installation de PostgreSQL™. Une fois que le serveur actuel PostgreSQL™ est arrêté, il est bon de renommer le répertoire d'installation de PostgreSQL ; en supposant que l'ancien répertoire est /usr/local/pgsql, vous pouvez saisir ceci :
mv /usr/local/pgsql /usr/local/pgsql.old
pour renommer le répertoire.
Pour une installation par les sources, construisez la nouvelle version
Construisez la nouvelle version de PostgreSQL avec des options de compilation compatibles avec l'ancienne instance. pg_upgrade utilisera pg_controldata pour vérifier que tous les paramètres sont compatibles avant de lancer la mise à jour.
Installez les nouveaux exécutables de PostgreSQL
Installez les nouveaux exécutables du serveur ainsi que les fichiers de support.
Pour les installations à partir des sources, si vous préférez installer le nouveau serveur dans un emplacement particulier, utilisez le mot clé prefix :
gmake prefix=/usr/local/pgsql.new install
Installez pg_upgrade et pg_upgrade_support
Installez l'exécutable pg_upgrade et la bibliothèque pg_upgrade_support dans la nouvelle instance PostgreSQL
Initialisez la nouvelle instance PostgreSQL
Initialisez la nouvelle instance avec initdb. Encore une fois, utilisez des options d'initdb qui correspondent à celles de l'ancienne instance. Beaucoup d'installeurs font cette étape automatiquement. Il n'est pas nécessaire de démarrer la nouvelle instance.
Installez les fichiers objets partagés personnalisés (ou DLL)
Installez tous fichiers objets partagés personnalisés (ou DLL) utilisés par l'ancien cluster dans le nouveau cluster, par exemple pgcrypto.so, qu'ils proviennent des modules contrib ou de toute autre source. N'installez pas les définitions du schéma, par exemple pgcrypto.sql, car elles seront aussi mises à jour à partir de l'ancien cluster.
Ajustez l'authentification
pg_upgrade se connectera à l'ancien et au nouveau serveurs plusieurs fois. Vous devez donc configurer l'authentification à trust dans pg_hba.conf ou, si vous utilisez l'authentification md5, configurer un fichier ~/.pgpass (voir Section 31.15, « Fichier de mots de passe » pour les détails) pour éviter d'avoir à saisir de façon répétée le mot de passe.
Arrêtez les deux serveurs
Assurez-vous que les deux serveurs de bases de données sont stoppés. Pour cela, vous pouvez utiliser la commande suivante sous Unix :
pg_ctl -D /opt/PostgreSQL/8.4 stop pg_ctl -D /opt/PostgreSQL/9.0 stop
et la commande suivante sous Windows (en utilisant les bons noms de service) :
NET STOP postgresql-8.4 NET STOP postgresql-9.0
ou encore :
NET STOP pgsql-8.3 (PostgreSQL™ 8.3 et antérieurs
utilisent un autre nom de service)
Exécutez pg_upgrade
Exécutez toujours le binaire pg_upgrade dans le nouveau serveur, pas l'ancien. pg_upgrade nécessite de spécifier les repértoires de l'instance (PGDATA) et des exécutables pour l'ancien et la nouvelle instance (bin). Vous pouvez aussi indiquer des valeurs pour l'utilisateur et le port, et si vous voulez que les données soient ajoutées par lien ou par copie (cette dernière étant la valeur par défaut).
Si vous utilisez les liens, la mise à jour sera bien plus rapide (pas de copie de données), mais vous ne serez plus capable d'accéder à votre ancienne instance une fois que vous aurez démarré la nouvelle instance après la mise à jour. Le mode des liens nécessite aussi que les répertoires des données de l'ancienne et de la nouvelle instances soient situés sur le même système de fichiers. Voir pg_upgrade --help pour une liste complète des options.
Pour les utilisateurs Windows, vous devez être connecté avec un compte administrateur, puis lancé un shell en tant qu'utilisateur postgres et configuré la variable PATH correctement :
RUNAS /USER:postgres "CMD.EXE" SET PATH=%PATH%;C:\Program Files\PostgreSQL\9.0\bin;
Enfin, vous lancez pg_upgrade avec les noms des répertoires entre guillemets doubles, par exemple :
pg_upgrade.exe --old-datadir "C:/Program Files/PostgreSQL/8.4/data" --new-datadir "C:/Program Files/PostgreSQL/9.0/data" --old-bindir "C:/Program Files/PostgreSQL/8.4/bin" --new-bindir "C:/Program Files/PostgreSQL/9.0/bin"
Une fois lancé, pg_upgrade vérifiera que les deux instances sont compatibles puis lancera la mise à jour. vous pouvez utiliser pg_upgrade --check pour ne faire que les vérifications, même si l'ancienne installation est en cours d'exécution. pg_upgrade --check indiquera aussi tout ajustement manuel que vous devrez faire après la mise à jour. pg_upgrade réclame des droits en écriture dans le répertoire courant.
Évidemment, personne ne doit accéder aux instances pendant la mise à jour. Par défaut, pg_upgrade lance les serveurs sur le port 50432 pour éviter les connexions clientes non désirées. Vous pouvez utiliser le même numéro de port pour chaque instance lors d'une mise à jour car l'ancienne et la nouvelle instance ne seront pas lancées en même temps. Cependant, lors de la vérification d'un ancien serveur en cours d'exécution, l'ancien et le nouveau numéro de port doivent être différents.
Si une erreur survient lors de la restauration du schéma de la base de données, pg_upgrade quittera et vous devrez retourner sur l'ancienne instance comme indiqué dans Étape 14. Pour essayer de nouveau pg_upgrade, vous aurez besoin de modifier l'ancienne instance pour que la restauration du schéma par pg_upgrade réussisse. Si le problème est dû à un module contrib, vous pourriez avoir besoin de désinstaller le module contrib à partir de l'ancienne instance et de l'installer sur la nouvelle après la mise à jour en espérant que le module n'est pas utilisé pour stocker des données de l'utilisateur.
Restaurez pg_hba.conf
Si vous avez modifié pg_hba.conf pour utiliser trust, restaurez-le à sa configuration d'origine. Il pourrait aussi être nécessaire d'ajuster les fichiers de configuration dans la nouvelle instance pour correspondre à l'ancienne instance, par exemple le fichier postgresql.conf.
Traitement post-mise à jour
Si tout traitement post-mise à jour est requis, pg_upgrade lancera des avertissements à la fin de son travail. Il générera aussi des fichiers de script à exécuter par l'administrateur. Les fichiers de script se connecteront à chaque base de données pour réaliser un traitement post-mise à jour. Chaque script doit être exécuté avec la commande suivante :
psql --username postgres --file script.sql postgres
Ces scripts peuvent être exécutés dans n'importe quel ordre et peuvent être supprimés une fois qu'ils ont été exécutés.
En général, il n'est pas prudent d'accéder aux tables référencées dans les scripts de reconstruction tant que ses scripts n'ont pas été exécutés entièrement ; le faire malgré tout pourrait amener des résultats incorrects ou des contre-performances. Les tables non référencées dans les scripts de reconstruction peuvent être utilisées immédiatement.
Statistiques
Comme les statistiques de l'optimiseur ne sont pas transférées par pg_upgrade, il vous sera demandé d'exécuter une commande pour regénérer les informations statistiques à la fin de la mise à jour.
Supprimez l'ancienne instance
Une fois que vous être satisfait par la mise à jour, vous pouvez supprimer les répertoires de données de l'ancienne instance en exécutant le script mentionné à la fin de pg_upgrade. Vous devrez supprimer manuellement les anciens répertoires d'installation, par exemple bin, share.
Retourner sur l'ancienne instance
Si, après avoir exécuté pg_upgrade, vous souhaitez retourner à l'ancienne instance, il existe plusieurs options.
Si vous avez exécuté pg_upgrade avec l'option --check, aucune modification n'a eu lieu sur l'ancienne instance, donc vous pouvez la réutiliser immédiatement.
Si vous avez exécuté pg_upgrade avec l'option --link, les fichiers de données sont partagés entre l'ancienne et la nouvelle instances. Si vous avez démarré la nouvelle instance, le nouveau serveur a écrit dans les fichiers partagés et il est du coup dangereux d'utiliser l'ancienne instance.
Si vous avez exécuté pg_upgrade sans l'option --link ou si vous n'avez pas lancé le nouveau serveur, l'ancien serveur ne sera pas modifié, hormis, si la liaison a débuté, l'ajout d'un suffixe .old au fichier $PGDATA/global/pg_control. Pour réutiliser l'ancienne instance, il est possible de supprimer le suffixe .old du fichier $PGDATA/global/pg_control. Vous pouvez alors relancer l'ancienne instance.
pg_upgrade ne supporte pas la mise à jour de bases de données qui contiennent les types systèmes identifiants d'objet reg* suivant : regproc, regprocedure, regoper, regoperator, regconfig, et regdictionary. (regtype peut être mis à jour.)
Chaque échec, reconstruction, ou cas de réindexation qui affectent votre installation sera signalé par pg_upgrade. Les scripts de reconstruction des tables et index à exécuter après la mise à jour seront générés automatiquement.
Pour effectuer un test de déploiement, vous pouvez créer une simple copie du schéma de votre ancienne instance, insérer des données fictives, et le mettre à jour.
Si vous mettez à jour une instance antérieure à PostgreSQL™ 9.2 qui utilise un répertoire dédié aux fichiers de configuration, vous devrez spécifier le répertoire des données à pg_upgrade, et spécifier le répertoire de configuration au serveur, c'est-à-dire -d /repertoire-des-donnees -o '-D /repertoire-de-configuration'.
Lors de l'utilisation d'un ancien serveur (pré-9.1) qui utilise un répertoire pour la socket de domaine Unix qui diffère du répertoire par défaut ou qui diffère de celui de la nouvelle instance, configurez PGHOST pour pointer vers l'emplacement de la socket de l'ancien serveur. (Ceci ne concerne pas Windows.)
Un serveur en standby utilisant le Log-Shipping (Section 25.2, « Serveurs de Standby par transfert de journaux ») ne peut pas être mis à jour car le serveur doit autoriser les écritures. Le moyen le plus simple est de mettre à jour le serveur primaire et d'utiliser rsync pour reconstruire les esclaves. Vous pouvez exécuter rsync quand le serveur principal est arrêté ou en l'intégrant dans une sauvegarde de fichiers (Section 24.3.2, « Réaliser une sauvegarde de base ») qui va surcharger l'ancienne instance du standby.
Si vous voulez utiliser l'option --link mais que vous ne voulez pas que votre ancienne instance soit modifiée lorsque la nouvelle instance démarrera, créez une copie de l'ancien serveur et mettez-le à jour avec l'option --link. Pour créer une copie valide de votre ancienne instance, utilisez la commande rsync pour créer une copie incohérente de votre ancienne instance alors que le serveur tourne toujours, puis arrêtez l'ancien serveur et lancez à nouveau la commande rsync pour rendre cohérent la copie avant le moindre changement. Vous pouvez exclure certains fichiers, par exemple postmaster.pid, comme documenté dans Section 24.3.3, « Effectuer une sauvegarde de base avec l'API bas niveau ».
La mise à jour à partir de PostgreSQL 8.3 comporte quelques restrictions supplémentaires. Par exemple, pg_upgrade ne fonctionnera pas pour une mise à jour à partir d'une 8.3 si une colonne utilisateur est définie comme :
le type de données tsquery
le type de données name et qu'il ne s'agit pas de la première colonne
Vous devez supprimer ce type de colonnes et les mettre à jour manuellement.
pg_upgrade ne fonctionnera pas si le module contrib ltree est installé dans une base de données.
pg_upgrade nécessitera une reconstruction de la table si :
une colonne utilisateur est de type tsvector
pg_upgrade nécessitera un réindexage si :
un index est de type hash ou GIN
un index utilise bpchar_pattern_ops
De plus, le format de stockage des dates et heures par défaut a changé vers l'entier après l'arrivée de PostgreSQL™ 8.3. pg_upgrade vérifiera que le format de stockage utilisé sur l'ancienne instance correspond à celui utilisé sur la nouvelle instance. Assurez-vous que votre nouvelle instance est construite avec le drapeau de configuration --disable-integer-datetimes.
Pour les utilisateurs Windows, notez que, dû à une configuration différente sur ce paramètre par l'installeur one-click et l'installeur MSI, il est seulement possible de mettre à jour une version 8.3 provenant de l'installeur one-click vers la version 8.4 ou ultérieure de l'installeur one-click. Il n'est pas possible de mettre à jour un répertoire des données créé par l'installeur MSI à un répertoire de données créé par l'installeur one-click.