PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 15.10 » Programmation serveur » Décodage logique (Logical Decoding) » Envoi en flux de grosses transactions pour le décodage logique

49.9. Envoi en flux de grosses transactions pour le décodage logique

Les fonctions callbacks simples pour le plugin de sortie (soit begin_cb, change_cb, commit_cb et message_cb) sont uniquement appelées quand la transaction se termine avec un COMMIT. Les changements sont toujours décodés à partir des journaux de transactions, mais sont seulement passés au plugin de sortie à la validation de la transaction (et ignorés si la transaction est annulée).

Ceci signifie que, bien que le décodage survient de façon incrémental et pourrait déborder sur disque pour que l'utilisation de la mémoire reste sous contrôle, tous les changements décodés seront transmis au moment de la validation de la transaction (ou plus précisément quand le COMMIT sera décodé du journal de transaction). Suivant la taille de la transaction et la bande passante du réseau, le temps de transfert pourrait augmenter de façon significative le délai du rejeu.

Pour réduire le délai de rejeu causé par les grosses transactions, un plugin de sortie peut fournir des fonctions callback supplémentaires pour accepter un flux incrémental de transactions en cours. Il existe plusieurs fonctions callback requises pour un flux (stream_start_cb, stream_stop_cb, stream_abort_cb, stream_commit_cb et stream_change_cb) et deux fonctions callback optionnelles (stream_message_cb et stream_truncate_cb).

Lors du flux d'une transaction en cours, les changements (et les messages) sont envoyés en blocs démarqués par les fonctions stream_start_cb et stream_stop_cb. Une fois que tous les changements décodés ont été transmis, la transaction peut être validée en utilisant la fonction callback stream_commit_cb(ou possiblement annulée en utilisant la fonction callback stream_abort_cb). Si les validations en deux phases sont supportées, la transaction peut être préparée en utilisant la fonction callback stream_prepare_cb, la commande de validation COMMIT PREPARED en utilisant la fonction callback commit_prepared_cb, et la commande d'annulation en utilisant la fonction callback rollback_prepared_cb.

Une séquence d'exemple d'appels de callbacks pour un flux sur une transaction pourrait ressembler à ceci :

stream_start_cb(...);   <-- début du premier bloc de changements
  stream_change_cb(...);
  stream_change_cb(...);
  stream_message_cb(...);
  stream_change_cb(...);
  ...
  stream_change_cb(...);
stream_stop_cb(...);    <-- fin du premier bloc de changements

stream_start_cb(...);   <-- début du deuxième bloc de changements
  stream_change_cb(...);
  stream_change_cb(...);
  stream_change_cb(...);
  ...
  stream_message_cb(...);
  stream_change_cb(...);
stream_stop_cb(...);    <-- fin du deuxième bloc de changements


[a. when using normal commit]
stream_commit_cb(...);  <-- validation de la transaction en flux

[b. when using two-phase commit]
stream_prepare_cb(...);   <-- prépare la transaction en flux
commit_prepared_cb(...);  <-- commit de la transaction préparée

La séquence réelle d'appels de fonctions callback pourrait être plus compliquée bien sûr. Il pourrait y avoir des blocs pour plusieurs transactions en flux, certaines des transactions pourraient être annulées, etc.

De façon similaire au comportement de débordement sur disque, le flux est déclenché quand la quantité totale de changements décodés du WAL (pour toutes les transactions en cours) dépasse la limite définie par le paramètre logical_decoding_work_mem. À ce moment-là, la transaction de haut niveau la plus large (mesuré par la quantité de mémoire actuellement utilisée pour les changements décodés) est sélectionnée et envoyée en flux. Néanmoins, dans certains cas, nous avons encore besoin de déborder sur disque même si le flux est activé parce que nous dépassons la limite de mémoire, mais nous n'avons pas encore décodé la ligne complète, par exemple seulement le décodage de l'insertion d'un TOAST, mais pas celle de la table principale.

Même lors de flux de grosses transactions, les changements sont toujours appliqués dans l'ordre des validations, préservant les mêmes garanties que le mode sans flux.