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

12

Outre ses colonnes régulières, les tables Postgres ont également différentes colonnes système disponibles. L'un d'eux, xminstocke l'ID de transaction utilisé pour créer une ligne. Son type de données est xidun entier de quatre octets qui se termine à un moment donné (c'est-à-dire pas nécessairement unique). La fonction txid_current()retourne à son tour l'ID de transaction actuel, mais comme bigint, car il "est étendu avec un compteur" epoch "afin qu'il 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 xmincommencera à 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 régulièrement xidun txid_current()résultat afin qu'il corresponde aux xminentrées d'une table (par exemple, un cast txid_current()en entier)?

Edit : clarifiez que je me soucie de ce qui se passe après un bouclage 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.

tomka
la source
1
Vous ignorez le fait que le système VACUUM FREEZEécrasera et remplacera les xminlignes bien avant le bouclage 2 ^ 32. Consultez Freezing Your Tuples Off pour un aperçu du sujet.
Daniel Vérité
Certes, j'ai laissé ce fait hors de question, merci de l'avoir signalé. Et en effet, le gel se produira bien avant 2 ^ 32. Cependant, même avec l'ancien xmingelé, la question reste de savoir comment les nouveaux (réguliers) se xmincomparent à ceux qui sont exécutés txid_current().
tomka
1
Il convient de noter que PostgreSQL s'arrêtera s'il reste moins de 1 million de transactions avant la fin .
user103153

Réponses:

6

Vous pouvez supprimer l'époque ajoutée pour qu'elle corresponde à la valeur de xmin, c'est- à -dire extraire les 4 octets integerdu bigint. Puisque xminest type xidet non (signé!) integer, Nous comparons textplutôt la représentation:

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

Explication détaillée:

Erwin Brandstetter
la source