web-dev-qa-db-fra.com

Comment comparer xmin et txid_current () après le bouclage d'ID de transactions?

Outre ses colonnes régulières, les tables Postgres ont également divers colonnes système disponibles. L'un d'eux, xmin, stocke l'ID de transaction utilisé pour créer une ligne. Son type de données est xid, un entier de quatre octets qui entoure à un moment donné (c'est-à-dire pas nécessairement unique). La fonction txid_current() retourne à son tour l'ID de transaction en cours, mais sous la forme bigint, car elle "est étendue avec un compteur" Epoch "afin qu'elle ne se termine pas pendant la durée de vie d'une installation" (pour citer le manuel ).

Si le bouclage des transactions ne s'est pas encore produit, les deux valeurs semblent correspondre:

# CREATE TABLE test (label text);
CREATE TABLE
# INSERT INTO test VALUES ('test') RETURNING txid_current();
 txid_current 
--------------
   674500
(1 row)
INSERT 0 1
# SELECT xmin FROM test;
  xmin  
--------
 674500
(1 row)

Mais je me demande: ces deux valeurs sont-elles toujours comparables? Pour autant que je sache, txid_current() continuera à fournir des valeurs uniques après le bouclage de l'ID de transaction (au plus 2 ^ 32 transactions) et xmin commencera à partir de zéro. Cela signifie que les deux commencent à renvoyer des valeurs différentes à ce point?

Et si cela est vrai, existe-t-il un moyen d'extraire le résultat régulier de xid d'un txid_current() afin qu'il corresponde aux entrées de xmin dans une table (par exemple, cast txid_current() en entier)?

Edit : Précisez que je me soucie de ce qui se passe après un enveloppement d'ID de transaction, ce qui se produit très probablement bien avant 2 ^ 32 transactions. Merci à Daniel Vérité de l'avoir noté dans les commentaires.

12
tomka

Vous pouvez supprimer l'Epoch ajoutée pour qu'elle corresponde à la valeur dans xmin, c'est-à-dire extraire les 4 octets integer des bigint. Puisque xmin est de type xid et non (signé!) integer, nous comparons plutôt la représentation text:

SELECT * FROM test
WHERE  xmin::text = (txid_current() % (2^32)::bigint)::text;

Explication détaillée:

6
Erwin Brandstetter