Можно ли получить текущий 64-битный идентификатор транзакции (с эпохой) в плагине логической репликации postgreSQL

Я создаю систему захвата изменений, которая использует Postgres WAL через подключаемый модуль вывода логического декодирования.

В обратных вызовах очень легко получить доступ к текущему идентификатору транзакции (https://doxygen.postgresql.org/structReorderBufferTXN.html#ad3ff4a8f320f2ec21e3e07688d29c741), но это 32-разрядная версия, которая может выполняться после фиксации 4B, поэтому она ненадежна в качестве логического счетчика.

Postgres внутренне поддерживает 64-битный идентификатор транзакции, который не повторяется (выберите txid_current()): https://www.postgresql.org/docs/9.4/functions-info.html#FUNCTIONS-TXID-SNAPSHOT

https://github.com/postgres/postgres/blob/3412030205211079f9b0510e2244083e4ee7b15a/src/backend/access/transam/xact.c#L473-L488

Можно ли получить доступ к этому идентификатору из плагина логического декодирования? А если нет, то в чем причина?

Спасибо


person fpacifici    schedule 20.06.2019    source источник


Ответы (1)


У вас есть два варианта:

  1. Вы используете OidFunctionCall0 для вызова функции SQL txid_current().

  2. Вы копируете код из txid_current, load_xid_epoch и convert_xid из src/backend/utils/adt/txid.c.

Второй вариант будет быстрее, но придется дублировать код.

person Laurenz Albe    schedule 21.06.2019
comment
Нет, условий гонки нет. Если вы используете функцию в транзакции изменения данных, она не будет генерировать новый txid, но вернет текущий. - person Laurenz Albe; 21.06.2019
comment
Спасибо Laurenz, за оба варианта они вернут следующий xid (где я полагаю, что txid_current() фактически создаст транзакцию, а load_xid_epoch не будет github.com/postgres/postgres/blob/…). Действительно ли возможно, что две фиксации, происходящие почти в одно и то же время в двух разных процессах, будут генерировать один и тот же идентификатор следующей транзакции, если две транзакции параллельны и между первым и вторым событием фиксации не начинается новая транзакция? - person fpacifici; 21.06.2019
comment
извините, я удалил комментарий, чтобы лучше сформулировать идею, прежде чем пришел ответ. Первоначальный ответ, на который Лоренц ответил, был: Спасибо, Лоренц, насчет обоих вариантов, они вернут следующий xid (где я полагаю, что txid_current() фактически создаст транзакция, а load_xid_epoch не будет github.com/postgres/postgres/blob/…). Будет ли это синхронизировано с фиксацией транзакции, которую я использую в WAL? Или я могу столкнуться с проблемами многопоточности, такими как две фиксации, происходящие почти в одно и то же время, возвращающие один и тот же следующий xid? - person fpacifici; 21.06.2019
comment
txid_current() будет возвращать другой txid при вызове из разных транзакций (иначе PostgreSQL не будет работать). Мне интересно, зачем вам это нужно в плагине логического декодирования. - person Laurenz Albe; 22.06.2019