LOXODATA

PostgreSQL et la réplication logique

2024-05-14   932 mots, 5 minutes de lecture

Nous vous présentions la réplication logique native dans cet article de Sébastien Lardière.

Depuis son intégration à PostgreSQL en version 10, cette fonctionnalité n’a cessé d'être améliorée. Dans cet article, nous vous proposons de faire la chronologie des changements.

Il est possible d’extraire les fonctionnalités ajoutées par chaque version majeure de PostgreSQL via la matrice de fonctionnalités.

Apport de la version 11

  • Prise en compte de la commande TRUNCATE. Auparavant seules les commandes INSERT, UPDATE et DELETE étaient répliquées.

Apports de la version 12

  • Possibilité de copier les slots de réplication logique, à des fins de debug ou pour sélectionner d’autres plugins de sortie.

Apports de la version 13

  • Ajout de la réplication des tables partitionnées ;
  • Ajout du paramètre logical_decoding_work_mem afin de contrôler la quantité de mémoire allouée à un processus walsender. Cela détermine la quantité de modifications conservée en mémoire avant l'écriture sur disque (valeur par défaut à 64MB) ;
  • Ajout du paramètre max_slot_wal_keep_size (valeur par défaut à -1, pas de limite) afin de limiter le volume total de fichiers WAL que les slots de réplication peuvent conserver dans le répertoire pg_wal. Cela permet de limiter la saturation disque, avec le risque, toutefois, de rendre inopérante la réplication connectée à ce slot, si des WAL nécessaires n’ont pas été conservés.

Apports de la version 14

  • Ajout du streaming des longues transactions en cours au lieu d’attendre la fin des transactions. Cela permet de réduire le retard d’application des modifications ;
  • Possibilité de transférer les données au format binaire au lieu de texte pour les types de données applicables ;
  • Utilisation de plusieurs transactions au lieu d’une seule lors de la phase de synchronisation des tables. Cela permet d’accélérer la recopie initiale des données ;
  • Amélioration du décodage des transactions préparées afin d’initier le décodage au moment du prepare time et non plus seulement du commit ;
  • Ajout de la vue pg_stat_replication_slots pour reporter l’activité des slots de réplication, et ainsi estimer la quantité de données envoyée aux souscripteurs.

Apports de la version 15

  • Ajout du support des transactions préparées (two-phase commit) à la réplication logique native, et compatibilité avec l’option de streaming également :
CREATE SUBSCRIPTION mysub
    CONNECTION 'conninfo'
    PUBLICATION mypub
    WITH (two-phase = on, streaming = true);
  • Ajout de la possibilité de filtrer les colonnes d’une table sur une publication :
CREATE PUBLICATION mypub FOR TABLE sales (order_id, ordered_at);
  • Ajout de la possibilité de filtrer des lignes d’une table sur une publication par l’ajout d’une clause WHERE :
CREATE PUBLICATION mypub FOR TABLE sensor WHERE (device = `rpi`);
  • Ajout de la possibilité de publier toutes les tables d’un schéma à une publication :
CREATE PUBLICATION mypub FOR ALL TABLES IN SCHEMA auditing;
  • Ajout de la désactivation automatique d’une souscription sur erreur avec le paramètre disable_on_error :
CREATE SUBSCRIPTION mysub
    CONNECTION 'conninfo'
    PUBLICATION mypub
    WITH (disable_on_error = true);

Apports de la version 16

  • Ajout d’un paramètre origin sur les souscriptions pour prévenir les boucles de réplication bidirectionnelle :
CREATE SUBSCRIPTION <sub-name> CONNECTION 'conninfo' PUBLICATION <pub-list> [WITH (origin = NONE|ANY)]

Le paramètre origin = NONE permet de filtrer les transactions n’ayant pas de nœud d’origine, alors que origin = ANY envoie toutes les transactions ;

  • Ajout du décodage logique depuis un serveur standby. Il est nécessaire de passer le paramètre wal_level à logical sur le primaire et le standby. Il est possible d’utiliser la vue pg_replication_slots afin de vérifier si un slot de réplication est invalidé (champs conflicting) par un conflit avec le primaire.

  • Ajout du paramètre run_as_owner sur la souscription (par défaut à false). Permet d’exécuter la réplication logique avec les privilèges du propriétaire des tables en lieu et place des privilèges du propriétaire de la souscription ;

  • Possibilité d’autoriser les rôles non superuser à créer des souscriptions, en octroyant le rôle pg_create_subscription, le privilège CREATE sur la base de données et un mot de passe pour l’authentification ;

  • Parallélisation de l’application des changements pour les transactions longues via l’utilisation de workers supplémentaires (si disponible) et l’introduction côté souscription d’une nouvelle valeur parallel pour le paramètre streaming. Un nouveau paramètre, max_parallel_apply_workers_per_subscription, permet de limiter le nombre de parallel apply worker (valeur par défaut à 2). Les workers utilisent le pool défini par le paramètre max_logical_replication_workers (par défaut à 4), qui inclut le worker principal, les workers parallèles et les workers de synchronisation de tables. Le pool max_logical_replication_workers est lui même pris dans le pool défini par max_workers_processes (par défaut à 8);

  • Possibilité pour la réplication logique de copier les tables au format binaire, pendant la phase de synchronisation. Auparavant, même avec le paramètre binary = true côté souscription, la synchronisation des tables se faisait au format texte ;

  • Possibilité d’utiliser d’autres index que PRIMARY KEY et REPLICA IDENTITY sur les souscriptions pour accélérer les opérations UPDATE ou DELETE. Sans cela, il fallait exécuter un scan séquentiel de la table. Les index utilisables sont les index btree non-partiels avec au moins une colonne référencée. Pour rappel, REPLICA IDENTITY permet de modifier quelles sont les informations inscrites dans les WAL pour identifier les lignes qui sont mises à jour ou supprimées. Les valeurs possibles sont :

    • DEFAULT (valeur par défaut pour les tables utilisateurs)
    • USING INDEX index_name
    • FULL
    • NOTHING (valeur par défaut pour les tables systèmes)

Qu’attendre de la version 17

  • Migration des slots de réplication avec pg_upgrade sur le nouveau cluster ;
  • Synchronisation des slots de réplication du primaire vers les standbys, afin d’assurer la bascule d’une souscription sur une nouvelle publication (standby promu) lors d’un failover ;
  • Réplication des séquences ;
  • Réplication des opérations DDL.