Re: [PATCH] add concurrent_abort callback for output plugin

From: Markus Wanner <markus(dot)wanner(at)enterprisedb(dot)com>
To: Andres Freund <andres(at)anarazel(dot)de>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org, amit(dot)kapila16(at)gmail(dot)com, itsajin(at)gmail(dot)com
Subject: Re: [PATCH] add concurrent_abort callback for output plugin
Date: 2021-03-25 22:15:50
Message-ID: 6eaa32bc-764f-2eb5-d485-f9e985822a93@enterprisedb.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 25.03.21 21:21, Andres Freund wrote:
> ... the code added as part of 7259736a6e5b7c75 ...

That's the streaming part, which can be thought of as a more general
variant of the two-phase decoding in that it allows multiple "flush
points" (invoking ReorderBufferProcessTXN). Unlike the PREPARE of a
two-phase commit, where the reorderbuffer can be sure there's no further
change to be processed after the PREPARE. Nor is there any invocation
of ReorderBufferProcessTXN before that fist one at PREPARE time. With
that in mind, I'm surprised support for streaming got committed before
2PC. It clearly has different use cases, though.

However, I'm sure your inputs on how to improve and cleanup the
implementation will be appreciated. The single tiny problem this patch
addresses is the same for 2PC and streaming decoding: the output plugin
currently has no way to learn about a concurrent abort of a transaction
still being decoded, at the time this happens.

Both, 2PC and streaming do require the reorderbuffer to forward changes
(possibly) prior to the transaction's commit. That's the whole point of
these two features. Therefore, I don't think we can get around
concurrent aborts.

> You may have only meant it as a shorthand: But imo output plugins have
> absolutely no business "invoking actions downstream".

From my point of view, that's the raison d'être for an output plugin.
Even if it does so merely by forwarding messages. But yeah, of course a
whole bunch of other components and changes are needed to implement the
kind of global two-phase commit system I tried to describe.

I'm open to suggestions on how to reference that use case.

>> diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
>> index c291b05a423..a6d044b870b 100644
>> --- a/src/backend/replication/logical/reorderbuffer.c
>> +++ b/src/backend/replication/logical/reorderbuffer.c
>> @@ -2488,6 +2488,12 @@ ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
>> errdata = NULL;
>> curtxn->concurrent_abort = true;
>>
>> + /*
>> + * Call the cleanup hook to inform the output plugin that the
>> + * transaction just started had to be aborted.
>> + */
>> + rb->concurrent_abort(rb, txn, streaming, commit_lsn);
>> +
>> /* Reset the TXN so that it is allowed to stream remaining data. */
>> ReorderBufferResetTXN(rb, txn, snapshot_now,
>> command_id, prev_lsn,
>
> I don't think this would be ok, errors thrown in the callback wouldn't
> be handled as they would be in other callbacks.

That's a good point. Maybe the CATCH block should only set a flag,
allowing for the callback to be invoked outside of it.

Regards

Markus my-callbacks-do-not-throw-error Wanner

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Magnus Hagander 2021-03-25 22:52:58 Re: shared memory stats: high level design decisions: consistency, dropping
Previous Message Bruce Momjian 2021-03-25 22:15:49 Re: [PATCH] More docs on what to do and not do in extension code