¿Cómo comparar xmin y txid_current () después de la identificación de transacciones envolvente?

12

Además de sus columnas regulares, las tablas de Postgres también tienen varias columnas del sistema disponibles. Uno de ellos, xminalmacena la ID de transacción utilizada para crear una fila. Su tipo de datos es xidun entero de cuatro bytes que se envuelve en algún momento (es decir, no necesariamente único). La función txid_current()a su vez devuelve la ID de transacción actual, pero como bigint, porque "se extiende con un contador" de época "para que no se ajuste durante la vida de una instalación" (para citar el manual ).

Si aún no se realizaron las transacciones, ambos valores parecen coincidir:

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

Pero me pregunto: ¿son estos dos valores siempre comparables? Según tengo entendido, txid_current()continuará entregando valores únicos después de la identificación de la transacción (como máximo 2 ^ 32 transacciones) y xmincomenzará desde cero. ¿Esto significa que ambos comienzan a devolver valores diferentes en ese punto?

Y si esto es cierto, ¿hay alguna forma de extraer xidun txid_current()resultado regular para que coincida con las xminentradas de una tabla (por ejemplo, convertir txid_current()a entero)?

Editar : deje en claro que me importa lo que sucede después de que se envuelve un ID de transacción, lo que muy probablemente ocurre mucho antes de 2 ^ 32 transacciones. Gracias a Daniel Vérité por notar esto en los comentarios.

tomka
fuente
1
Estás ignorando el hecho de que el sistema VACUUM FREEZEsobrescribirá las xminfilas mucho antes de la envoltura 2 ^ 32. Echa un vistazo a Freezing Your Tuples Off para obtener una descripción general del tema.
Daniel Vérité
Es cierto, dejé este hecho fuera de cuestión, gracias por señalarlo. Y de hecho, la congelación ocurrirá mucho antes de 2 ^ 32. Sin embargo, incluso cuando el viejo xminse congela, la pregunta sigue siendo qué tan nuevo (regular) se xmincompara con un entonces ejecutado txid_current().
tomka
1
Vale la pena señalar que PostgreSQL se cerrará si quedan menos de 1 millón de transacciones hasta que finalice .
user103153

Respuestas:

5

Puede quitar la época agregada para que coincida con el valor xmin, es decir, extraer el byte integerde 4 bigint. Como xmines tipo xidy no (¡firmado!) integer, Comparamos la textrepresentación en su lugar:

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

Explicación detallada:

Erwin Brandstetter
fuente