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

12

In Postgres-Tabellen stehen neben den regulären Spalten auch verschiedene Systemspalten zur Verfügung. Einer von ihnen xminspeichert die Transaktions-ID, die zum Erstellen einer Zeile verwendet wurde. Sein Datentyp ist xideine 4-Byte-Ganzzahl, die sich irgendwann umgibt (dh nicht unbedingt eindeutig ist). Die Funktion gibt txid_current()ihrerseits die aktuelle Transaktions-ID zurück, jedoch als bigint, weil sie "um einen" Epochen "-Zähler erweitert ist, so dass sie sich während der Lebensdauer einer Installation nicht umhüllt" (um das Handbuch zu zitieren ).

Wenn der Transaktionsumlauf noch nicht stattgefunden hat, stimmen anscheinend beide Werte überein:

# 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ß, txid_current()werden nach dem Umlauf der Transaktions-ID (höchstens 2 ^ 32 Transaktionen) weiterhin eindeutige Werte geliefert und xminbei Null begonnen. Dies bedeutet, dass beide zu diesem Zeitpunkt unterschiedliche Werte zurückgeben.

Und wenn dies zutrifft, gibt es eine Möglichkeit, xidein txid_current()Ergebnis so zu extrahieren , dass es mit xminEinträgen in einer Tabelle übereinstimmt (z. B. Umwandlung txid_current()in eine Ganzzahl)?

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

Tomka
quelle
1
Sie ignorieren die Tatsache, dass das System VACUUM FREEZEdie xminon-Zeilen lange vor dem 2 ^ 32-Wraparound überschreibt . Schauen Sie sich Freezing Your Tuples Off an, um einen Überblick zu diesem Thema zu erhalten.
Daniel Vérité
Es stimmt, ich habe diese Tatsache außer Frage gestellt, danke, dass Sie darauf hingewiesen haben. Und tatsächlich wird das Einfrieren lange vor 2 ^ 32 geschehen. Doch auch bei xmineingefrorenem Altem stellt sich die Frage, wie neuere (reguläre) im xminVergleich zu einem dann ausgeführten txid_current().
Tomka
1
Es ist erwähnenswert, dass PostgreSQL heruntergefahren wird, wenn weniger als 1 Million Transaktionen bis zum Wraparound übrig sind .
user103153

Antworten:

5

Sie können die hinzugefügte Epoche entfernen, um sie dem Wert in xminanzupassen, dh das 4-Byte integeraus der extrahieren bigint. Da xmines sich um Typ xidund nicht (signiert!) integerHandelt, vergleichen wir textstattdessen die Darstellung:

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

Ausführliche Erklärung:

Erwin Brandstetter
quelle