Le décodage logique est le processus d'extraction de tous les changements persistants sur des tables d'une base de données, dans un format cohérent et simple à comprendre, et qui peut être interprété sans une connaissance détaillée de l'état interne de la base de données.
Dans PostgreSQL, le décodage logique est implémenté en décodant le contenu des journaux de transaction (WAL), qui décrivent les changements au niveau stockage, dans un format spécifique tel que le flux de lignes ou des ordres SQL.
Dans le contexte de la réplication logique, un slot représente un flux de changements qui peut être rejoué par un client, dans l'ordre dans lequel ils ont été effectués sur le serveur d'origine. Chaque slot envoie dans ce flux une séquence de changements d'une unique base.
PostgreSQL possède également des slots de réplication (voir Section 26.2.5), mais ceux-ci sont utilisés de manière un peu différente ici.
Les slots de réplication ont un identifiant qui est unique à travers toutes les bases d'une instance PostgreSQL. Les slots persistent indépendamment de la connexion les utilisant et sont résistants à un arrêt brutal.
Un slot logique émettra chaque modification une fois en temps normal. La position actuelle de chaque slot est enregistrée seulement lors d'un checkpoint, donc dans le cas d'un crash, le slot pourrait revenir à un ancien LSN, qui sera la cause d'un renvoi des changements récents au redémarrage du serveur. Les clients de décodage logique sont responsables de la bonne gestion de ce fait et doivent éviter les mauvais effets dûs à la gestion du même message plusieurs fois. Les clients peuvent souhaiter enregistrer le dernier LSN qu'ils ont vu lors du décodage pour ignorer toute donnée répétée ou (lors de l'utilisation du protocole de réplication) demander que le décodage commence à partir de ce LSN plutôt que de laisser le serveur déterminer le point de démarrage. La fonctionnalité Replication Progress Tracking est conçue dans ce but, voir les origines de réplication.
De nombreux slots indépendants peuvent exister pour une même base. Chaque slot possède son propre état, autorisant différents consommateurs à recevoir des changements depuis différents points dans le flux de changement de la base. Pour la plupart des utilisations, un slot séparé sera requis pour chaque consommateur.
Un slot de réplication logique ne sait rien sur l'état du ou des destinataire(s). Il est même possible d'avoir plusieurs destinataires différents utilisant un même slot à des moments différents ; ils ne recevront que les changements à partir du moment où le dernier destinataire a arrêté de les consommer. Un seul destinataire peut consommer les changements d'un slot à un instant donné.
Un slot de réplication logique peut aussi être créé sur un serveur
secondaire en hot standby. Pour empêcher VACUUM
de
supprimer les lignes requises des catalogues systèmes,
hot_standby_feedback
doit être configuré sur le
secondaire. Malgré cela, si un des lignes requises est supprimée, le slot
devient invalide. Il est hautement recommandé d'utiliser un slot physique
entre le primaire et le secondaire. Sinon,
hot_standby_feedback
fonctionnera mais uniquement tant
que la connexion est vivante (par exemple le redémarrage d'un nœud
le cassera). Ensuite, le primaire peut supprimer les lignes d'un catalogue
système qui aurait été nécessaire au décodage logique sur le secondaire
(car il ne connait pas la valeur de catalog_xmin
sur le
secondaire). Les
slots logiques existants sur le secondaire deviennent aussi invalides si
wal_level
sur le primaire est configuré à une valeur
inférieure à logical
. Ceci est fait dès que le secondaire
détecte un tel changement dans le flux de journaux. Cela signifie que, pour
les walsenders en retard , certains enregistrements des journaux jusqu'au
changement du paramètre wal_level
sur le primaire ne
seront pas décodés.
La création d'un slot logique requiert des informations sur les
transactions en cours d'exécution. Sur le primaire, cette information est
disponible directement mais sur un secondaire, cette information doit être
obtenue du primaire. De ce fait, la création du slot pourrait devoir
attendre qu'une activité ait lieu sur le primaire. Si le primaire ne fait
rien, créer un slot de réplication sur le secondaire peut prendre beaucoup
de temps. Ceci peut être accéléré en exécutant la fonction
pg_log_standby_snapshot
sur le primaire.
Les slots de réplications persistent après un arrêt brutal et ne
connaissent rien de l'état de leur(s) consommateur(s). Ils empêcheront
la suppression automatique des ressources nécessaires même si aucune
connexion ne les utilise. Cela consomme de l'espace car aucun des
journaux de transactions et aucune des lignes des catalogues systèmes
requis ne peuvent être supprimés par VACUUM
tant
qu'ils sont requis par un slot de réplication. Dans les cas extrêmes,
cela pourrait causer l'arrêt de la base pour empêcher une réutilisation
des identifiants de transactions (voir Section 24.1.5). Par conséquent, si un slot n'est
plus nécessaire, il devrait être supprimé.
Les slots de réplication logiques sur le primaire peuvent être
synchronisés sur le secondaire en utilisant le paramètre
failover
de
pg_create_logical_replication_slot
, ou en
utilisant l'option
failover
de CREATE
SUBSCRIPTION
lors de la création du slot, puis en appelant
pg_sync_replication_slots
sur le secondaire.
En configurant
sync_replication_slots
sur le secondaire, les
slots en failover peuvent être synchronisés périodiquement dans le
worker slotsync. Pour que la synchronisation fonctionne, il est
obligatoire d'avoir un slot de réplication physique entre le primaire et
le secondaire (autrement dit, primary_slot_name
doit être configuré sur le secondaire), et hot_standby_feedback
doit être activé sur le secondaire. Il est aussi nécessaire de spécifier
un nom de base(dbname
) valide dans le paramètre primary_conninfo
.
Il est fortement recommandé que le slot de réplication physique soit
nommé dans la liste synchronized_standby_slots
sur le primaire, pour empêcher l'abonné de consommer les changements
plus rapidement que le secondaire. Même une fois correctement configuré,
une latence est attendue lors de l'envoi des changements aux abonnés
logiques à cause de l'attente des slots nommés dans synchronized_standby_slots
.
Quand synchronized_standby_slots
est utilisé, le serveur
primaire ne va pas s'arrêter complètement jusqu'à ce que les secondaires
correspondants, associés avec les slots de réplication physique indiqués
dans synchronized_standby_slots
, aient confirmé la réception
des journaux de transaction jusqu'à la dernière position vidée sur le
serveur primaire.
La capacité de reprendre la réplication logique après un failover dépend
de la valeur de pg_replication_slots.synced
value pour les slots synchronisés sur le secondaire au moment du
failover. Seuls les slots persistents qui ont atteint l'état synced true
sur le secondaire avant le failover peuvent être utilisés pour la
réplication logique après failover. Les slots temporaires synchronisés
ne peuvent pas être utilisés pour le décodage logique, de ce fait la
réplication logique ne peut être reprise pour ces slots. Par exemple, si
le slot synchronisé n'a pas pu devenir persistent sur le secondaire à
cause d'une souscription désactivée, alors la souscription ne peut être
reprise après un failover même s'il est activé.
Pour reprendre la réplication logique après un failover à partir des
slots logiques synchronisés, le paramètre conninfo de l'abonné doit être
modifié pour pointer vers le nouveau serveur primaire. Ceci se fait en
utilisant ALTER
SUBSCRIPTION ... CONNECTION
. Il est recommandé que les
souscriptions soient tout d'abord désactivées avant de promouvoir le
secondaire, puis réactivées après avoir modifié la chaîne de connexion.
Il est possible que l'ancien primaire soit de nouveau disponible lors de la promotion et, si les souscriptions ne sont pas désactivées, les abonnés logiques pourraient continuer à recevoir des données à partir de l'ancien serveur primaire même après la promotion jusqu'à ce que la chaîne de connexion ne soit modifiée. Ceci pourrait résulter en des données incohérentes, empêchant les abonnés logiques de pouvoir reprendre la réplication à partir du nouveau serveur primaire.
Les plugins de sortie transforment les données depuis la représentation interne dans les journaux de transactions (WAL) vers le format dont le consommateur d'un slot de réplication a besoin.
Quand un nouveau slot de réplication est créé avec l'interface de la
réplication en flux (voir create_replication_slot), un instantané est exporté
(voir Section 9.28.5), qui montrera
exactement l'état de la base de données après lequel tous les changements
seront inclus dans le flux de changement. Cela peut être utilisé pour
créer un nouveau réplicat en utilisant SET TRANSACTION
SNAPSHOT
pour lire l'état de la base au moment où le
slot a été créé. Cette transaction peut alors être utilisée pour
exporter l'état de la base à ce point dans le temps, lequel peut ensuite
être mis à jour en utilisant le contenu des slots sans perdre le moindre
changement.
La création d'un instantané n'est pas toujours possible. En particulier,
cela échouera quand cela est fait à partir d'un serveur secondaire en
lecture seule. Les applications qui ne nécessitent pas d'instantané
exporté peuvent les supprimer avec l'option
NOEXPORT_SNAPSHOT
.