PostgreSQL идентификатор транзакции (xmin) появляется в подтвержденной версии последовательно? - PullRequest
2 голосов
/ 12 февраля 2020

Из-за PostgreSQL документов https://www.postgresql.org/docs/current/ddl-system-columns.html

xmin Идентификатор (идентификатор транзакции) транзакции вставки для этой версии строки (A версия строки - это отдельное состояние строки; каждое обновление строки создает новую версию строки для той же логической строки).

Мы используем ее (не спрашивайте, почему, просто происходит) для синхронизации данных и извлечения (E в ETL) изменений из PostgreSQL исходной БД мы сделали это с помощью сканирования интервалов, в частности интервалов xmin, например, мы синхронизировали интервал xmin от 0 до 10002, а когда мы сделали следующую синхронизацию c в этом случае мы будем искать xmin, начиная с 10003. Если каждая зафиксированная и видимая транзакция пронумерована последовательно, проблем нет, все изменения данных будут последовательно пронумерованы, но если транзакции пронумерованы в момент их инициализации, может произойти следующий случай:

  • транзакция 10001 началась в 15:01
  • транзакция 10002 началась в 15: 02
  • транзакция 10002 зафиксирована в 15:02
  • транзакция 10001 зафиксирована в 15: 03

и если мы сделали syn c в 15:02 и получили max xmin в целевой базе данных: 10002 в этом случае в следующем syn c, начиная с xmin 10003, мы пропустим xmin 10001 и потеряем изменения.

Также появляется ли PostgreSQL идентификатор транзакции (xmin) в подтвержденной версии последовательно?


Существует также xmax в том же самом do c:

xmax Идентификатор (идентификатор транзакции) удаляемой транзакции или ноль для версии строки без восстановления. Этот столбец может быть ненулевым в видимой версии строки. Обычно это означает, что удаляемая транзакция еще не зафиксирована или что попытка удаления была отменена.

Итак, мы видим транзакцию, которая планирует удалить строку (если она будет зафиксирована), поэтому может быть, xmin также показывает транзакцию, которая изменит строку? но это не может быть правдой из-за описания xmin:

... для этой версии строки. (Версия строки - это отдельное состояние строки; каждое обновление строки создает новую версию строки для той же логической строки.)

, поскольку, как написано, она должна соответствовать версии строки, которую мы читать, что может быть возможно только с грязным чтением (когда мы видим незафиксированные данные), но это не может произойти в PostgreSQL https://www.postgresql.org/docs/current/transaction-iso.html

Грязное чтение : разрешено, но не в PG

Ответы [ 2 ]

0 голосов
/ 12 февраля 2020

Ваша идея хороша (за исключением того, что вы должны взять txid_snapshot_xmin в качестве точки отсечения), но она страдает двумя недостатками:

  • идентификаторы транзакций генерируются из 4 -байтовый счетчик целых чисел без знака, который в какой-то момент обернется. Тогда сравнение xmin больше не будет работать.

  • Чтобы избежать этой проблемы, PostgreSQL в какой-то момент установит флаг «заморожен» в старых строках, который не виден из SQL. Для замороженных рядов xmin и xmax должны игнорироваться.

Так что я думаю, что милая техника обречена.

Вы должны заглянуть в логично декодирование , особенно плагин wal2 json. Это позволит вам надежно фиксировать все изменения в данных.

0 голосов
/ 12 февраля 2020

Во время написания этого вопроса я нашел следующие слайды: https://momjian.us/main/writings/pgsql/mvcc.pdf и из-за его части "MV CC Snapshot Timeline" я предположил, что появление xmin в снимке может быть не последовательным.

Но я нашел решение здесь: https://www.postgresql.org/docs/9.6/functions-info.html#FUNCTIONS -TXID-SNAPSHOT

txid_snapshot_xip (txid_snapshot) [setof bigint] get Идентификаторы выполняемой транзакции в снимке

Таким образом, я могу получить набор еще не зафиксированных транзакций и проверить, что они содержат xids, которые меньше максимального xid, который закрывает текущий процесс syn c интервал, и если содержит, то нужно подождать некоторое время, затем проверить еще раз и продолжить извлечение данных, если все транзакции в интервале syn c завершены, в противном случае для выхода из процесса с ошибкой.

...