PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Mise à niveau vers PostgreSQL 11 avec réplication logique

Il est temps.

Il y a environ un an, nous avons publié PostgreSQL 10 avec prise en charge de la réplication logique native. L'une des utilisations de la réplication logique est de permettre une mise à niveau avec peu ou pas de temps d'arrêt entre les versions majeures de PostgreSQL. Jusqu'à présent, PostgreSQL 10 était la seule version de PostgreSQL avec une réplication logique native, il n'y avait donc pas beaucoup d'opportunités de mise à niveau de cette manière. (La réplication logique peut également être utilisée pour déplacer des données entre des instances sur différents systèmes d'exploitation ou architectures de processeur ou avec différents paramètres de configuration de bas niveau tels que la taille de bloc ou les paramètres régionaux - une mise à niveau latérale si vous voulez.) Maintenant que PostgreSQL 11 est proche, il y aura plus de raisons d'utiliser cette fonctionnalité.

Commençons par comparer les trois principales manières de mettre à niveau une installation PostgreSQL :

  • pg_dump et restauration
  • pg_upgrade
  • réplication logique

Nous pouvons comparer ces méthodes en termes de robustesse, de vitesse, de temps d'arrêt requis et de restrictions (et plus encore, mais nous devons nous arrêter quelque part pour cet article).

pg_dump and restore est sans doute la méthode la plus robuste, car elle est la plus testée et utilisée depuis des décennies. Il a également très peu de restrictions en termes de ce qu'il peut gérer. Il est possible de construire des bases de données qui ne peuvent pas être vidées et restaurées, impliquant principalement des relations de dépendance d'objet particulières, mais celles-ci sont rares et impliquent généralement des pratiques déconseillées.

Le problème avec la méthode de vidage et de restauration est bien sûr qu'elle nécessite effectivement un temps d'arrêt pendant toute la durée d'exécution des opérations de vidage et de restauration. Bien que la base de données source soit toujours accessible en lecture et en écriture pendant l'exécution du processus, toutes les mises à jour de la base de données source après le début du vidage seront perdues.

pg_upgrade améliore le processus pg_dump en déplaçant directement les fichiers de données sans avoir à les vider dans une forme textuelle logique. Notez que pg_upgrade utilise toujours pg_dump en interne pour copier le schéma, mais pas les données. Lorsque pg_upgrade était nouveau, sa robustesse était remise en question et il mettait à jour certaines bases de données de manière incorrecte. Mais pg_upgrade est maintenant assez mature et bien testé, il n'est donc plus nécessaire d'hésiter à l'utiliser pour cette raison. Pendant l'exécution de pg_upgrade, le système de base de données est en panne. Mais on peut faire un choix sur la durée d'exécution de pg_upgrade. Dans le mode de copie par défaut, le temps d'exécution total est composé du temps de vidage et de restauration du schéma (ce qui est généralement très rapide, sauf si l'on a des milliers de tables ou d'autres objets) plus le temps de copie des fichiers de données, qui dépend de la taille de la base de données (et le système d'E/S, le système de fichiers, etc.).

Dans le mode de liaison facultatif, les fichiers de données sont à la place liés en dur au nouveau répertoire de données, de sorte que le temps est simplement le temps d'effectuer une courte opération de noyau par fichier au lieu de copier chaque octet. L'inconvénient est que si quelque chose ne va pas avec la mise à niveau ou si vous devez revenir à l'ancienne installation, cette opération aura détruit votre ancienne base de données. (Je travaille sur une solution optimale pour PostgreSQL 12 en utilisant des liens de référence ou des opérations de clonage de fichiers sur les systèmes de fichiers pris en charge.)

La réplication logique est la plus récente du groupe ici, il faudra donc probablement un certain temps pour résoudre les problèmes. Si vous n'avez pas le temps d'explorer et d'enquêter, ce n'est peut-être pas la voie à suivre pour le moment. (Bien sûr, les gens utilisent d'autres solutions de réplication logique non essentielles telles que Slony, Londiste et pglogical pour mettre à niveau PostgreSQL depuis de nombreuses années, donc il y a beaucoup d'expérience avec les principes, sinon avec les détails.)

L'avantage d'utiliser la réplication logique pour la mise à niveau est que l'application peut continuer à s'exécuter sur l'ancienne instance pendant la synchronisation des données. Il ne doit y avoir qu'une petite panne pendant que les connexions client sont commutées. Ainsi, bien qu'une mise à niveau utilisant la réplication logique soit probablement plus lente du début à la fin que d'utiliser pg_upgrade en mode copie (et certainement plus lente que d'utiliser le mode lien physique), cela n'a pas beaucoup d'importance puisque le temps d'arrêt réel peut être beaucoup plus court.

Notez que la réplication logique ne réplique actuellement pas les modifications de schéma. Dans cette procédure de mise à niveau proposée, le schéma est toujours copié via pg_dump, mais les modifications de schéma ultérieures ne sont pas reportées. La mise à niveau avec la réplication logique comporte également quelques autres restrictions. Certaines opérations ne sont pas capturées par la réplication logique :objets volumineux, TRUNCATE, changements de séquence. Nous discuterons des solutions de contournement pour ces problèmes plus tard.

Si vous avez des veilles physiques (et si ce n'est pas le cas, pourquoi pas ?), il y a aussi quelques différences à prendre en compte entre les méthodes. Quelle que soit la méthode, vous devez créer de nouvelles instances physiques de secours pour l'instance mise à niveau. Avec le vidage et la restauration ainsi qu'avec la réplication logique, ils peuvent être mis en place avant le démarrage de la mise à niveau afin que le serveur de secours soit pratiquement prêt une fois la restauration ou la synchronisation initiale de la réplication logique terminée, sous réserve du délai de réplication.

Avec pg_upgrade, les nouveaux standbys doivent être créés une fois la mise à niveau du primaire terminée. (La documentation pg_upgrade décrit cela plus en détail.) Si vous comptez sur des standbys physiques pour la haute disponibilité, les standbys doivent être en place avant de passer à la nouvelle instance, de sorte que la configuration des standbys pourrait affecter vos calculs de temps globaux.

Mais revenons à la réplication logique. Voici comment effectuer une mise à niveau avec réplication logique :

0. L'ancienne instance doit être préparée pour la réplication logique. Cela nécessite certains paramètres de configuration comme décrit sous http://www.postgresql.org/docs/10/static/logical-replication-config.html (principalement wal_level = logical . S'il s'avère que vous devez apporter ces modifications, elles nécessiteront un redémarrage du serveur. Vérifiez donc cela bien à l'avance. Vérifiez également que pg_hba.conf sur l'ancienne instance est configuré pour accepter les connexions de la nouvelle instance. (Changer cela ne nécessite qu'un rechargement.)

1. Installez la nouvelle version de PostgreSQL. Vous avez besoin au moins du package serveur et du package client contenant pg_dump. De nombreux packages permettent désormais d'installer plusieurs versions côte à côte. Si vous utilisez des machines virtuelles ou des instances cloud, il vaut la peine d'envisager d'installer la nouvelle instance sur un nouvel hôte.

2. Configurez une nouvelle instance, c'est-à-dire exécutez initdb. La nouvelle instance peut avoir des paramètres différents de l'ancienne, par exemple les paramètres régionaux, la taille du segment WAL ou la somme de contrôle. (Pourquoi ne pas profiter de cette opportunité pour activer les sommes de contrôle des données ?)

3. Avant de démarrer la nouvelle instance, vous devrez peut-être modifier certains paramètres de configuration. Si l'instance s'exécute sur le même hôte que l'ancienne instance, vous devez définir un numéro de port différent. Reportez également toutes les modifications personnalisées que vous avez apportées dans postgresql.conf sur votre ancienne instance, tels que les paramètres de mémoire, max_connections , etc. De même, faites pg_hba.conf paramètres adaptés à votre environnement. Vous pouvez généralement commencer par copier le pg_hba.conf fichier de l'ancienne instance. Si vous souhaitez utiliser SSL, configurez-le maintenant.

4. Démarrez la nouvelle instance (vide) et vérifiez qu'elle fonctionne à votre satisfaction. Si vous configurez la nouvelle instance sur un nouvel hôte, vérifiez à ce stade que vous pouvez établir une connexion à la base de données (à l'aide de psql) du nouvel hôte à l'ancienne instance de base de données. Nous en aurons besoin dans les étapes suivantes.

5. Copiez les définitions de schéma avec pg_dumpall. (Ou vous pouvez le faire avec pg_dump pour chaque base de données séparément, mais n'oubliez pas les objets globaux tels que les rôles.)

pg_dumpall -s >schemadump.sql
psql -d postgres -f schemadump.sql

Toute modification de schéma après ce point ne sera pas migrée. Vous auriez à les gérer vous-même. Dans de nombreux cas, vous pouvez simplement appliquer le changement DDL sur les deux hôtes, mais exécuter des commandes qui modifient la structure de la table lors d'une mise à niveau est probablement un défi trop important.

6. Dans chaque base de données de l'instance source, créez une publication qui capture toutes les tables :

CREATE PUBLICATION p_upgrade FOR ALL TABLES;

La réplication logique fonctionne séparément dans chaque base de données, elle doit donc être répétée dans chaque base de données. D'un autre côté, vous n'avez pas besoin de mettre à niveau toutes les bases de données en même temps, vous pouvez donc faire cette base de données à la fois ou même ne pas mettre à niveau certaines bases de données.

7. Dans chaque base de données de l'instance cible, créez un abonnement qui s'abonne à la publication que vous venez de créer. Assurez-vous de faire correspondre correctement les bases de données source et cible.

CREATE SUBSCRIPTION s_upgrade CONNECTION 'host=oldhost port=oldport dbname=dbname ...' PUBLICATION p_upgrade;

Définissez les paramètres de connexion comme il convient.

8. Vous attendez maintenant que les abonnements aient copié les données initiales et aient complètement rattrapé l'éditeur. Vous pouvez vérifier l'état de synchronisation initial de chaque table dans un abonnement dans le catalogue système pg_subscription_rel (recherchez r =prêt dans la colonne srsubstate ). Le statut global de la réplication peut être vérifié dans pg_stat_replication côté envoi et pg_stat_subscription du côté de la réception.

9. Comme mentionné ci-dessus, les changements de séquence ne sont pas répliqués. Une solution de contournement possible consiste à copier les valeurs de séquence à l'aide de pg_dump. Vous pouvez obtenir un vidage des valeurs de séquence actuelles en utilisant quelque chose comme ceci :

pg_dump -d dbname --data-only -t '*_seq' >seq-data.sql

(Cela suppose que les noms de séquence correspondent tous à *_seq et aucune table ne correspond à ce nom. Dans des cas plus compliqués, vous pouvez également créer un vidage complet et extraire les données de séquence de la table des matières du vidage.)

Étant donné que les séquences peuvent avancer au fur et à mesure que vous faites cela, peut-être munge le seq-data.sql fichier pour ajouter un peu de mou aux chiffres.

Restaurez ensuite ce fichier dans la nouvelle base de données à l'aide de psql.

10. Showtime :Basculez les applications vers les nouvelles instances. Cela nécessite une certaine réflexion en amont. Dans le scénario le plus simple, vous arrêtez vos programmes d'application, modifiez les paramètres de connexion, redémarrez. Si vous utilisez un proxy de connexion, vous pouvez y basculer la connexion. Vous pouvez également changer les applications clientes une par une, peut-être pour tester un peu les choses ou alléger la charge sur le nouveau système. Cela fonctionnera tant que les applications pointant toujours vers l'ancien serveur et celles pointant vers le nouveau serveur ne font pas d'écritures conflictuelles. (Dans ce cas, vous exécuteriez un système multimaître, au moins pendant une courte période, et c'est un autre ordre de complexité.)

11. Une fois la mise à niveau terminée, vous pouvez supprimer la configuration de la réplication. Dans chaque base de données sur la nouvelle instance, exécutez

DROP SUBSCRIPTION s_upgrade;

Si vous avez déjà arrêté l'ancienne instance, cela échouera car elle ne pourra pas atteindre le serveur distant pour supprimer le slot de réplication. Consultez la page de manuel DROP SUBSCRIPTION pour savoir comment procéder dans cette situation.

Vous pouvez également déposer les publications sur l'instance source, mais ce n'est pas nécessaire puisqu'une publication ne conserve aucune ressource.

12. Enfin, supprimez les anciennes instances si vous n'en avez plus besoin.

Quelques commentaires supplémentaires sur les solutions de contournement pour les éléments que la réplication logique ne prend pas en charge. Si vous utilisez de gros objets, vous pouvez les déplacer en utilisant pg_dump, bien sûr tant qu'ils ne changent pas pendant le processus de mise à jour. Il s'agit d'une limitation importante, donc si vous êtes un gros utilisateur d'objets volumineux, cette méthode n'est peut-être pas pour vous. Si votre application émet TRUNCATE pendant le processus de mise à niveau, ces actions ne seront pas répliquées. Vous pouvez peut-être modifier votre application pour l'empêcher de le faire au moment de la mise à niveau, ou vous pouvez remplacer un DELETE à la place. PostgreSQL 11 prendra en charge la réplication TRUNCATE, mais cela ne fonctionnera que si l'instance source et l'instance de destination sont PostgreSQL 11 ou plus récent.

Quelques commentaires de clôture qui s'appliquent vraiment à toutes les entreprises de mise à niveau :

  • Les applications et tous les programmes clients de base de données doivent être testés avec une nouvelle version majeure de PostgreSQL avant d'être mis en production.
  • À cette fin, vous devez également tester la procédure de mise à niveau avant de l'exécuter dans l'environnement de production.
  • Écrivez les choses ou améliorez le script et automatisez autant que possible.
  • Assurez-vous que votre configuration de sauvegarde, vos systèmes de surveillance et tous les outils et scripts de maintenance sont correctement ajustés pendant la procédure de mise à niveau. Idéalement, ceux-ci doivent être en place et vérifiés avant que le basculement ne soit effectué.

Dans cet esprit, bonne chance et partagez vos expériences.