Como comparar xmin e txid_current () após a identificação da transação envolvente?

12

Além de suas colunas regulares, as tabelas do Postgres também têm várias colunas do sistema disponíveis. Um deles xmin,, armazena o ID da transação usada para criar uma linha. Seu tipo de dado é xidum número inteiro de quatro bytes que envolve algum ponto (ou seja, não é necessariamente único). A função, txid_current()por sua vez, retorna o ID da transação atual, mas como bigint, porque "é estendido com um contador de" época ", não envolve a vida útil da instalação" (para citar o manual ).

Se as transações abrangentes ainda não ocorreram, ambos os valores parecem corresponder:

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

Mas eu me pergunto: esses dois valores são sempre comparáveis? Tanto quanto eu entendo, txid_current()continuará a fornecer valores exclusivos após a identificação da transação (no máximo 2 ^ 32 transações) e xmincomeçará do zero. Isso significa que ambos começam a retornar valores diferentes nesse ponto?

E se isso for verdade, existe uma maneira de extrair xidum txid_current()resultado regular para que ele corresponda às xminentradas de uma tabela (por exemplo, conversão txid_current()para inteiro)?

Editar : deixe mais claro que eu me importo com o que acontece após a identificação de uma transação, o que provavelmente acontece muito antes de 2 ^ 32 transações. Agradecemos a Daniel Vérité por observar isso nos comentários.

tomka
fonte
1
Você está ignorando o fato de que o sistema VACUUM FREEZEsubstituirá as xminlinhas muito antes da envolvente 2 ^ 32. Confira Congelando suas tuplas desativadas para uma visão geral do assunto.
Daniel Vérité
É verdade que deixei esse fato fora de questão, obrigado por apontá-lo. E, de fato, o congelamento acontecerá muito antes de 2 ^ 32. No entanto, mesmo com xmino congelamento dos antigos, a questão ainda permanece: como os mais recentes (regulares) se xmincomparam aos que foram executados txid_current().
Tomka
1
Vale ressaltar que o PostgreSQL será encerrado se houver menos de 1 milhão de transações restantes até a conclusão .
user103153

Respostas:

5

Você pode retirar a época adicionada para corresponder ao valor xmin, ou seja, extrair os 4 bytes integerdo bigint. Como xminé do tipo xide não (assinado!) integer, Comparamos otext representação:

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

Explicação detalhada:

Erwin Brandstetter
fonte