Dans un blog récent sur les nouveautés de PostgreSQL 13, nous avons passé en revue certaines des nouvelles fonctionnalités de cette version, mais maintenant, voyons comment mettre à niveau pour pouvoir profiter de toutes ces fonctionnalités mentionnées .
Mettre à jour vers PostgreSQL 13
Si vous souhaitez mettre à niveau votre version actuelle de PostgreSQL vers cette nouvelle version, vous disposez de trois principales options natives pour effectuer cette tâche.
-
Pg_dump/pg_dumpall :c'est un outil de sauvegarde logique qui vous permet de vider vos données et de les restaurer dans le nouvelle version de PostgreSQL. Ici, vous aurez une période d'indisponibilité qui variera en fonction de la taille de vos données. Vous devez arrêter le système ou éviter de nouvelles données dans le nœud principal, exécuter pg_dump, déplacer le vidage généré vers le nouveau nœud de base de données et le restaurer. Pendant ce temps, vous ne pouvez pas écrire dans votre base de données PostgreSQL principale pour éviter l'incohérence des données.
-
Pg_upgrade :il s'agit d'un outil PostgreSQL permettant de mettre à niveau votre version PostgreSQL sur place. Cela pourrait être dangereux dans un environnement de production et nous ne recommandons pas cette méthode dans ce cas. En utilisant cette méthode, vous aurez également des temps d'arrêt, mais ils seront probablement beaucoup moins longs qu'avec la méthode pg_dump précédente.
-
Réplication logique :Depuis PostgreSQL 10, vous pouvez utiliser cette méthode de réplication qui vous permet d'effectuer des mises à jour de version majeures avec zéro (ou presque zéro) temps d'arrêt. De cette façon, vous pouvez ajouter un nœud de secours dans la dernière version de PostgreSQL, et lorsque la réplication est à jour, vous pouvez effectuer un processus de basculement pour promouvoir le nouveau nœud PostgreSQL.
Alors, voyons ces méthodes une par une.
Utiliser pg_dump/pg_dumpall
Si les temps d'arrêt ne vous posent pas de problème, cette méthode est un moyen simple de mise à niveau.
Pour créer le dump, vous pouvez exécuter :
$ pg_dumpall > dump_pg12.out
Ou pour créer un dump d'une seule base de données :
$ pg_dump world > dump_world_pg12.out
Ensuite, vous pouvez copier ce dump sur le serveur avec la nouvelle version de PostgreSQL, et le restaurer :
$ psql -f dump_pg12.out postgres
Gardez à l'esprit que vous devrez arrêter votre application ou éviter d'écrire dans votre base de données pendant ce processus, sinon vous aurez des incohérences de données ou une perte potentielle de données.
Utiliser pg_upgrade
Tout d'abord, vous devrez avoir à la fois la nouvelle et l'ancienne version de PostgreSQL installées sur le serveur.
$ rpm -qa |grep postgres
postgresql13-contrib-13.3-2PGDG.rhel8.x86_64
postgresql13-server-13.3-2PGDG.rhel8.x86_64
postgresql13-libs-13.3-2PGDG.rhel8.x86_64
postgresql13-13.3-2PGDG.rhel8.x86_64
postgresql12-libs-12.7-2PGDG.rhel8.x86_64
postgresql12-server-12.7-2PGDG.rhel8.x86_64
postgresql12-12.7-2PGDG.rhel8.x86_64
postgresql12-contrib-12.7-2PGDG.rhel8.x86_64
Ensuite, vous pouvez d'abord exécuter pg_upgrade pour tester la mise à niveau en ajoutant l'indicateur -c :
$ /usr/pgsql-13/bin/pg_upgrade -b /usr/pgsql-12/bin -B /usr/pgsql-13/bin -d /var/lib/pgsql/12/data -D /var/lib/pgsql/13/data -c
Performing Consistency Checks on Old Live Server
------------------------------------------------
Checking cluster versions ok
Checking database user is the install user ok
Checking database connection settings ok
Checking for prepared transactions ok
Checking for system-defined composite types in user tables ok
Checking for reg* data types in user tables ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking for presence of required libraries ok
Checking database user is the install user ok
Checking for prepared transactions ok
Checking for new cluster tablespace directories ok
*Clusters are compatible*
Les drapeaux signifient :
-
-b :l'ancien répertoire exécutable PostgreSQL
-
-B :le nouveau répertoire exécutable PostgreSQL
-
-d :l'ancien répertoire de configuration du cluster de bases de données
-
-D :le nouveau répertoire de configuration du cluster de bases de données
-
-c :vérifier uniquement les clusters. Cela ne change aucune donnée
Si tout semble correct, vous pouvez exécuter la même commande sans l'indicateur -c et cela mettra à jour votre serveur PostgreSQL. Pour cela, vous devez d'abord arrêter votre version actuelle et exécuter la commande mentionnée.
$ systemctl stop postgresql-12
$ /usr/pgsql-13/bin/pg_upgrade -b /usr/pgsql-12/bin -B /usr/pgsql-13/bin -d /var/lib/pgsql/12/data -D /var/lib/pgsql/13/data
...
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
Lorsqu'il est terminé, comme le message le suggère, vous pouvez utiliser ces scripts pour analyser le nouveau serveur PostgreSQL et supprimer l'ancien lorsqu'il est sûr.
Utilisation de la réplication logique
La réplication logique est une méthode de réplication des objets de données et de leurs modifications, en fonction de leur identité de réplication. Il est basé sur un mode de publication et d'abonnement, où un ou plusieurs abonnés s'abonnent à une ou plusieurs publications sur un nœud d'éditeur.
Donc, sur cette base, configurons l'éditeur, dans ce cas le serveur PostgreSQL 12, comme suit.
Modifiez le fichier de configuration postgresql.conf :
listen_addresses = '*'
wal_level = logical
max_wal_senders = 8
max_replication_slots = 4
Modifiez le fichier de configuration pg_hba.conf :
# TYPE DATABASE USER ADDRESS METHOD
host all rep1 10.10.10.141/32 md5
Utilisez ici l'adresse IP de l'abonné.
Maintenant, vous devez configurer l'abonné, dans ce cas le serveur PostgreSQL 13, comme suit.
Modifiez le fichier de configuration postgresql.conf :
listen_addresses = '*'
max_replication_slots = 4
max_logical_replication_workers = 4
max_worker_processes = 8
Comme ce PostgreSQL 13 sera bientôt le nouveau nœud principal, vous devriez envisager d'ajouter les paramètres wal_level et archive_mode dans cette étape, pour éviter un nouveau redémarrage du service plus tard.
wal_level = logical
archive_mode = on
Ces paramètres seront utiles si vous souhaitez ajouter une nouvelle réplique ou pour utiliser des sauvegardes PITR.
Certaines de ces modifications nécessitent un redémarrage du serveur, donc redémarrez à la fois l'éditeur et l'abonné.
Maintenant, dans l'éditeur, vous devez créer l'utilisateur qui sera utilisé par l'abonné pour y accéder. Le rôle utilisé pour la connexion de réplication doit avoir l'attribut REPLICATION et, pour pouvoir copier les données initiales, il a également besoin du privilège SELECT sur la table publiée :
world=# CREATE ROLE rep1 WITH LOGIN PASSWORD '********' REPLICATION;
CREATE ROLE
world=# GRANT SELECT ON ALL TABLES IN SCHEMA public to rep1;
GRANT
Créons la publication pub1 dans le nœud de l'éditeur, pour toutes les tables :
world=# CREATE PUBLICATION pub1 FOR ALL TABLES;
CREATE PUBLICATION
Comme le schéma n'est pas répliqué, vous devez faire une sauvegarde dans votre PostgreSQL 12 et la restaurer dans votre PostgreSQL 13. La sauvegarde ne sera prise que pour le schéma puisque les informations seront répliquées dans le transfert.
Dans PostgreSQL 12, exécutez :
$ pg_dumpall -s > schema.sql
Dans PostgreSQL 13, exécutez :
$ psql -d postgres -f schema.sql
Une fois que vous avez votre schéma dans PostgreSQL 13, vous devez créer l'abonnement, en remplaçant les valeurs de host, dbname, user et password par celles qui correspondent à votre environnement.
world=# CREATE SUBSCRIPTION sub1 CONNECTION 'host=10.10.10.140 dbname=world user=rep1 password=********' PUBLICATION pub1;
NOTICE: created replication slot "sub1" on publisher
CREATE SUBSCRIPTION
Ce qui précède démarrera le processus de réplication, qui synchronise le contenu initial des tables dans la publication, puis commence à répliquer les modifications incrémentielles de ces tables.
Pour vérifier l'abonnement créé, vous pouvez utiliser le catalogue pg_stat_subscription. Cette vue contiendra une ligne par abonnement pour le nœud de calcul principal (avec un PID nul si le nœud de calcul n'est pas en cours d'exécution) et des lignes supplémentaires pour les nœuds de calcul gérant la copie initiale des données des tables abonnées.
world=# SELECT * FROM pg_stat_subscription;
-[ RECORD 1 ]---------+------------------------------
subid | 16421
subname | sub1
pid | 464
relid |
received_lsn | 0/23A8490
last_msg_send_time | 2021-07-23 22:42:26.358605+00
last_msg_receipt_time | 2021-07-23 22:42:26.358842+00
latest_end_lsn | 0/23A8490
latest_end_time | 2021-07-23 22:42:26.358605+00
Pour vérifier quand le transfert initial est terminé, vous pouvez vérifier la variable srsubstate sur le catalogue pg_subscription_rel. Ce catalogue contient l'état de chaque relation répliquée dans chaque souscription.
world=# SELECT * FROM pg_subscription_rel;
srsubid | srrelid | srsubstate | srsublsn
---------+---------+------------+-----------
16421 | 16408 | r | 0/23B1738
16421 | 16411 | r | 0/23B17A8
16421 | 16405 | r | 0/23B17E0
16421 | 16402 | r | 0/23B17E0
(4 rows)
Description des colonnes :
-
srsubid :référence à l'abonnement.
-
srrelid :référence à la relation.
-
srsubstate :code d'état :i =initialiser, d =les données sont en cours de copie, s =synchronisé, r =prêt (réplication normale).
-
srsublsn :fin LSN pour les états s et r.
Lorsque le transfert initial est terminé, tout est prêt pour faire pointer votre application vers votre nouveau serveur PostgreSQL 13.
Conclusion
Comme vous pouvez le constater, PostgreSQL propose différentes options de mise à niveau, en fonction de vos besoins et de la tolérance aux temps d'arrêt.
Peu importe le type de technologie que vous utilisez, maintenir vos serveurs de base de données à jour en effectuant des mises à niveau régulières est une tâche nécessaire mais difficile, car vous devez vous assurer que vous n'aurez pas de perte de données ou incohérence des données après la mise à niveau. Un plan détaillé et testé est la clé ici, et bien sûr, il doit inclure une option de retour en arrière, juste au cas où.