postgresql: включает ли логическая репликация транзакцию отката?

Анализирует ли логическая репликация файлы WAL в единице транзакции? Как насчет транзакции отката?

И что такое API для ввода изменений данных на стороне получателя, не воспроизводя их на уровне SQL? Так же, как встроенный приемник потоковой репликации postgresql, независимо от того, логический или физический.

Редактировать:

Позвольте мне прояснить мой вопрос больше.

Поток логической потоковой передачи показан ниже:

Экземпляр postgresql (отправитель, создать слот с определенным выходным плагином) ------- потоковый протокол ----------> Экземпляр postgresql (получатель, получить данные для копирования)

Здесь формат данных копирования определяется выходным плагином, предположим, что это обычный текст. Тогда простым способом мы могли бы рассматривать это как операторы SQL и воспроизводить их в получателе postgresql, но это, очевидно, неэффективно. Существует ли какой-либо низкоуровневый API для доступа к данным копирования?

1 ответ

Решение

Я занимаюсь поиском исходников и пытаюсь ответить на вопрос сам.

  • Postgresql Walsender включает только совершенные транзакции, игнорируя отмененные.

Путь к коду и фрагмент кода:

pg_logical_slot_get_changes_guts() -> LogicalDecodingProcessRecord() -> DecodeXactOp() -> 
ReorderBufferCommit() -> ReorderBufferIterTXNNext()

DecodeXactOp ():

switch (info)
{
    case XLOG_XACT_COMMIT:
    case XLOG_XACT_COMMIT_PREPARED:
        {
            xl_xact_commit *xlrec;
            xl_xact_parsed_commit parsed;
            TransactionId xid;

            xlrec = (xl_xact_commit *) XLogRecGetData(r);
            ParseCommitRecord(XLogRecGetInfo(buf->record), xlrec, &parsed);

            if (!TransactionIdIsValid(parsed.twophase_xid))
                xid = XLogRecGetXid(r);
            else
                xid = parsed.twophase_xid;

            DecodeCommit(ctx, buf, &parsed, xid);
            break;
        }
  • Встроенный логический работник применения не воспроизводит SQL, но использует множество внутренних API для применения изменений на стороне получателя.

https://github.com/postgres/postgres/blob/master/src/backend/replication/logical/worker.c#L585

/* Input functions may need an active snapshot, so get one */
PushActiveSnapshot(GetTransactionSnapshot());

/* Process and store remote tuple in the slot */
oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
slot_store_cstrings(remoteslot, rel, newtup.values);
slot_fill_defaults(rel, estate, remoteslot);
MemoryContextSwitchTo(oldctx);

ExecOpenIndices(estate->es_result_relation_info, false);

/* Do the insert. */
ExecSimpleRelationInsert(estate, remoteslot);

/* Cleanup. */
ExecCloseIndices(estate->es_result_relation_info);
PopActiveSnapshot();

Логическая репликация PG10 использует pgoutput как плагин вывода, который находится в двоичном формате и подходит для непосредственного доступа к данным.

https://github.com/postgres/postgres/blob/master/src/backend/replication/pgoutput/pgoutput.c

Другие вопросы по тегам