it-swarm.com.de

Wie vergleiche ich xmin und txid_current () nach dem Umlauf der Transaktions-ID?

Neben den regulären Spalten stehen in Postgres-Tabellen auch verschiedene Systemspalten zur Verfügung. Einer von ihnen, xmin, speichert die Transaktions-ID, die zum Erstellen einer Zeile verwendet wird. Sein Datentyp ist xid, eine 4-Byte-Ganzzahl, die sich irgendwann umschließt (d. H. Nicht unbedingt eindeutig). Die Funktion txid_current() gibt wiederum die aktuelle Transaktions-ID zurück, jedoch als bigint, da sie "um einen" Epoch "-Zähler erweitert wird, damit sie während der Laufzeit einer Installation nicht umbrochen wird." (um das Handbuch zu zitieren).

Wenn der Umlauf der Transaktionen noch nicht stattgefunden hat, scheinen beide Werte übereinzustimmen:

# 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)

Aber ich frage mich: Sind diese beiden Werte immer vergleichbar? Soweit ich weiß, liefert txid_current() nach dem Umlauf der Transaktions-ID (höchstens 2 ^ 32 Transaktionen) weiterhin eindeutige Werte, und xmin beginnt bei Null. Dies bedeutet, dass beide an diesem Punkt unterschiedliche Werte zurückgeben.

Und wenn dies zutrifft, gibt es eine Möglichkeit, reguläres xid eines txid_current() -Ergebnisses so zu extrahieren, dass es mit xmin -Einträgen in einer Tabelle übereinstimmt (z. B. Casting txid_current() zur ganzen Zahl)?

Bearbeiten : Machen Sie klarer, dass es mir wichtig ist, was nach einem Umlauf der Transaktions-ID passiert, was sehr wahrscheinlich lange vor 2 ^ 32 Transaktionen geschieht. Vielen Dank an Daniel Vérité, der dies in den Kommentaren erwähnt hat.

12
tomka

Sie können die hinzugefügte Epoche entfernen, um dem Wert in xmin zu entsprechen, d. H. Das 4-Byte integer aus dem bigint extrahieren. Da xmin vom Typ xid und nicht (signiert!) integer ist, vergleichen wir stattdessen die Darstellung text:

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

Ausführliche Erklärung:

6