Texte de décodage logique du commit en deux phases dans PostgreSQL 14

Mise à jour : 2 juillet 2023

Texte de décodage logique du commit en deux phases dans PostgreSQL 14

L'équipe Fujitsu OSS et la communauté open source PostgreSQL ont coopéré pour ajouter la fonction de décryptage du commit en deux phases dans la réplication logique dans PG14. Voyons quelle est cette fonctionnalité ?

fond

La validation en deux phases est un mécanisme dans lequel les transactions sont validées en deux phases. Généralement utilisé dans les bases de données distribuées pour assurer la cohérence. Les deux phases de la transaction sont la phase PREPARE et la phase COMMIT/ROLLBACK. Les commandes soumises en deux phases dans PG sont :

PRÉPARER LA TRANSACTION

ENGAGEMENT PRÉPARÉ

ROLLBACK PRÉPARÉ

PG prend déjà en charge la validation en deux phases dans la version 8.0 et la version 10.0 prend en charge la réplication logique. Cependant, la validation en deux phases n'a jamais été prise en charge dans la réplication logique. Les commandes PREPARE TRANSACTION, COMMIT PREPARED et ROLLBACK PREPARED ont été prises en charge dans une seule instance, mais lorsque ces commandes doivent être logiquement copiées sur la machine de secours, elles ne conservent plus leur signification d'origine. La commande PREPARE TRANSACTION est traitée comme un NOP et n'est pas décodée du tout. La commande COMMIT PREPARED est considérée comme COMMIT et la commande ROLLBACK PREPARED est considérée comme ABORT.

Qu'est-ce qu'un commit en deux phases

La validation en deux phases est un protocole de validation atomique qui aide à maintenir la cohérence entre les bases de données distribuées. Les commits ordinaires qui fournissent l'atomicité au sein de la base de données ne sont pas suffisants pour assurer la cohérence des transactions entre bases de données. Pour illustrer ce problème, donnons un exemple :

1) John a 300$ dans la banque A

2) Mark a 100 dans la banque B

3) John veut transférer 100$ à Mark

Lors de la transaction, vous devez retirer 100$ de la banque A à la banque B. À la fin de la transaction, il devrait y avoir 200$. Si une transaction échoue à tout moment pendant le processus de transfert, l'état du compte doit être restauré à l'état avant le début du transfert. La transaction peut échouer pour diverses raisons. Si une interruption se produit avant la validation de la transaction, la transaction sera annulée. Dans notre exemple, si une interruption se produit lorsque le compte de John est déduit, le compte de John du port d'interruption ne doit pas être réduit. C'est ainsi qu'un simple commit maintient la cohérence au sein de la base de données.

Mais nous considérons une telle situation, c'est-à-dire que la transaction qui déduit 100 $ du compte de John réussit dans une soumission, mais la transaction qui ajoute 100 $ au compte de Mark dans la banque B échoue et est annulée. Une fois cette opération terminée, bien que le compte de Jean ait été débité, Marc ne recevra pas le montant. 100$ ont disparu. Lorsqu'il s'agit de transactions distribuées, une simple validation peut échouer.

Exécution pas à pas des transactions distribuées

Pour la validation en deux phases, l'une des bases de données agit en tant que coordinateur des transactions distribuées.

Étape 1

Une base de données commence à appliquer les transactions, puis à se préparer. Il envoie les transactions préparées à d'autres bases de données sous la forme de messages de préparation. La deuxième base de données reçoit le message Préparer, puis prépare la transaction. Préparer implique des modifications dans la transaction, mais ne valide pas. Les données modifiées sont écrites sur le disque pour la persistance. Une fois que toutes les bases de données ont préparé la transaction et que toutes les informations sur la transaction sont stockées sur le disque, la phase de préparation est terminée.

Étape 2

Ensuite, l'arbitre commence la phase de commit. Si la deuxième base de données ne parvient pas à préparer la transaction pour une raison quelconque, l'arbitre démarre la phase de restauration. Par conséquent, selon que la préparation est réussie, la transaction est validée ou annulée. L'interruption de la phase de validation finale peut être récupérée, car la transaction de préparation requise a été écrite sur le disque et peut être réappliquée.

La validation en deux phases n'est pas liée aux bases de données à instance unique, mais elle est pertinente lorsque les données sont répliquées sur plusieurs instances de base de données.

Il est très important de prendre en charge la validation en deux phases dans la réplication logique.

Aperçu fonctionnel

Avant la version PG14, les transactions de réplication logique étaient décodées et répliquées uniquement après la validation de la transaction. Cela permet d'éviter que la transaction de réplication ne soit finalement abandonnée.

Décoder la transaction lors de la validation

La réplication logique de PG14 prend en charge les commandes PREPARE TRANSACTION, COMMIT PREPARED et ROOLBACK PREPARED. Lorsque la commande PREPARE TRANSACTION est décodée, la transaction est décodée et copiée. PREPARE TRANSACTION lance la relecture et le décodage de la transaction tout comme COMMIT dans WAL SENDER.

Décodage de la transaction pendant la préparation

Nous avons également défini un nouveau rappel de plug-in pour permettre aux plug-ins de décodage logique de prendre en charge la soumission en deux phases.

Rappel

décrire

filtre, préparer, cb

Autoriser le plugin à filtrer les transactions qui n'ont pas besoin d'être décodées lors de la préparation selon le GID utilisé dans la commande PREPARE TRANSACTION

commencer_préparer_cb

Début de la transaction de préparation

préparer, cb

Appelé lorsque la commande PREPARE TRANSACTION est décodée

commit_préparé_cb

Appelé lorsque la commande COMMIT PREPARED est décodée

restauration_préparé_cb

Appelé lorsque la commande ROLLBACK PREPARED est décodée

Modification de plug-in

test, décodage

Le plug-in est un plug-in de sortie de décodage logique, à titre d'exemple pour aider les utilisateurs à développer leur propre plug-in de décodage logique. test_decoding reçoit le WAL via un mécanisme de décodage logique et le décode en une représentation textuelle de l'opération effectuée.

Il a été modifié pour pouvoir utiliser la nouvelle fonction de rappel en deux étapes et décoder la transaction lors de la préparation

Modification des API

pg_créer_logement_logique_de_réplication()

L'API ajoute une nouvelle option pour spécifier si le slot prend en charge la validation en deux phases. Le plug-in de sortie peut utiliser un emplacement de réplication avec une option en deux phases pour prendre en charge la validation en deux phases.

pg_create_logical_replication_slot(slot_name name, nom du plugin [, booléen temporaire, booléen à deux_phases ] )

Étude de cas

Voyons comment détecter la sortie décodée de la transaction de validation en deux phases :

1) Créer un slot de réplication

Utilisez test_decoding comme plug-in de sortie et transmettez true pour que l'emplacement prenne en charge la soumission et le décodage en deux étapes.

postgres=# SELECTIONNER * FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding', false, true);

emplacement_nom | lsn

??

régression_slot | 0/16B1970

(1 rangée)

2) Créer un tableau

postgres=# CREATE TABLE data(id clé primaire série, data text);

CREER LA TABLE

3) Détecter le contenu de sortie décodé de la transaction de préparation et de validation de la transaction

postgres=# COMMENCER;

postgres=*# INSÉRER DANS data(data) VALUES('5');

postgres=*# PRÉPARER LA TRANSACTION 'test_préparé1';

postgres=# SELECT FROM pg_logical_slot_get_changes('regression_slot', NULL, NULL);

lsn | xid | données

??

0/1689DC0 | 529 | COMMENCER 529

0/1689DC0 | 529 | table publique.data: INSERT: id[entier]:3 données[texte]:'5'

0/1689FC0 | 529 | PRÉPARER LA TRANSACTION 'test_prepared1', txid 529

(3 rangées)

postgres=# COMMIT PRÉPARÉ 'test_préparé1';

postgres=# sélectionnez * depuis pg_logical_slot_get_changes('regression_slot', NULL, NULL);

lsn | xid | données

??

0/168A060 529 | COMMIT PREPARED 'test_prepared1', txid 529

(4 rangées)

postgres=# sélectionnez * à partir des données;

identifiant | données

??

1 5

(1 rangée)

avenir

Le changement de PG14 à cette fonction a une infrastructure côté décodeur qui permet la soumission en deux étapes du décodage pendant la préparation. Nous avons également modifié le plugin test_decoding pour profiter de cette infrastructure.

L'étape suivante consiste à implémenter la prise en charge en deux étapes du plus grand plug-in de décodage logique dans PG, le plug-in pgoutput. Ce plug-in prend en charge le mode PUBLISHER/SUBSCRIBER de réplication logique. C'est le plug-in le plus utilisé en réplication logique. L'équipe Fujitsu OSS travaille avec la communauté open source pour ajouter cette fonctionnalité à PG15.

Pour la transaction en deux phases dans la base de données distribuée, PG doit également prendre en charge : la machine de secours informe l'hôte que PREPARE a échoué et lance une annulation. Ce mécanisme de rétroaction n'est pas pris en charge dans PG et est l'une des directions d'amélioration future.

  Liens:

6mbi25l-120

rm500uz-2h