Как сравнить xmin и txid_current () после обхода идентификатора транзакции?

12

Помимо обычных столбцов в таблицах Postgres также доступны различные системные столбцы . Один из них xminхранит идентификатор транзакции, использованный для создания строки. Его тип данных - xidчетырехбайтовое целое число, которое оборачивается в какой-то момент (т.е. не обязательно уникально). Функция, txid_current()в свою очередь, возвращает идентификатор текущей транзакции, но bigint, поскольку, он «расширен счетчиком« эпохи », поэтому он не будет меняться в течение срока службы установки» (цитируя руководство ).

Если обход транзакций еще не произошел, оба значения, кажется, совпадают:

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

Но мне интересно: эти два значения всегда сопоставимы? Насколько я понимаю, txid_current()будет продолжать доставлять уникальные значения после обхода идентификатора транзакции (не более 2 ^ 32 транзакций) и xminбудет начинаться с нуля. Это означает, что оба начинают возвращать разные значения в этой точке?

И если это так, то есть ли способ извлечь регулярные xidиз txid_current()результата , так что он будет соответствовать xminзаписям в таблице (например , литье txid_current()в целое число)?

Изменить : прояснить, что я забочусь о том, что происходит после обхода идентификатора транзакции, что, скорее всего, происходит задолго до 2 ^ 32 транзакций. Спасибо Даниэлю Верите за то, что отметили это в комментариях.

Томка
источник
1
Вы игнорируете тот факт, что система будет VACUUM FREEZEперезаписывать xminстроки строк задолго до перехода на 2 ^ 32. Проверьте Freezing Your Tuples Off для обзора предмета.
Даниэль Верите
Правда, я оставил этот факт вне вопроса, спасибо за указание на него. И действительно, замерзание произойдет задолго до 2 ^ 32. Тем не менее, даже когда старое xminстановится замороженным, вопрос все еще остается в том, как более новое (обычное) xminсравнение с тогда исполняемым txid_current().
Томка
1
Стоит отметить, что PostgreSQL завершит работу, если до завершения операции останется менее 1 миллиона транзакций .
user103153

Ответы:

6

Вы можете удалить добавленную эпоху, чтобы она соответствовала значению xmin, то есть извлечь 4-байт integerиз bigint. Поскольку xminэто тип, xidа не (подписано!) integer, Мы сравниваем textпредставление:

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

Детальное объяснение:

Эрвин Брандштеттер
источник