Re: [HACKERS] logical decoding of two-phase transactions - Mailing list pgsql-hackers

From Amit Kapila
Subject Re: [HACKERS] logical decoding of two-phase transactions
Date
Msg-id CAA4eK1LuDDzF-JLV6CCdGisA0GVuxoEM_AVorFC4d5Du7=Emmw@mail.gmail.com
Whole thread Raw
In response to Re: [HACKERS] logical decoding of two-phase transactions  (Ajin Cherian <itsajin@gmail.com>)
Responses Re: [HACKERS] logical decoding of two-phase transactions
List pgsql-hackers
On Wed, Dec 2, 2020 at 12:47 PM Ajin Cherian <itsajin@gmail.com> wrote:
>
> On Tue, Dec 1, 2020 at 6:26 PM Amit Kapila <amit.kapila16@gmail.com> wrote:
> > > One idea could be that the subscriber skips the transaction if it sees
> > > the transaction is already prepared.
> > >
> >
> > To skip it, we need to send GID in begin message and then on
> > subscriber-side, check if the prepared xact already exists, if so then
> > set a flag. The flag needs to be set in begin/start_stream and reset
> > in stop_stream/commit/abort. Using the flag, we can skip the entire
> > contents of the prepared xact. In ReorderFuffer-side also, we need to
> > get and set GID in txn even when we skip it because we need to send
> > the same at commit time. In this solution, we won't be able to send it
> > during normal start_stream because by that time we won't know GID and
> > I think that won't be required. Note that this is only required when
> > we skipped sending prepare, otherwise, we just need to send
> > Commit-Prepared at commit time.
> >
>
> After going through both the solutions, I think the above one is a better idea.
> I also think, rather than change the protocol for the regular begin,
> we could have
> a special begin_prepare for prepared txns specifically. This way we won't affect
> non-prepared transactions. We will need to add in a begin_prepare callback
> as well, which has the gid as one of the parameters. Other than this,
> in ReorderBufferFinishPrepared, if the txn hasn't already been
> prepared (because it was skipped in DecodePrepare), then we set
> prepared flag and call
> ReorderBufferReplay before calling commit-prepared callback.
>
> At the subscriber side, on receipt of the special begin-prepare, we
> first check if the gid is of an already
> prepared txn, if yes, then we set a flag such that the rest of the
> transaction are not applied but skipped, If it's not
> a gid that has already been prepared, then continue to apply changes
> as you would otherwise.

The above sketch sounds good to me and additionally you might want to
add Asserts in streaming APIs on the subscriber-side to ensure that we
should never reach the already prepared case there. We should never
need to stream the changes when we are skipping prepare either because
the snapshot was not consistent by that time or we have already sent
those changes before restart.

> So, this is the
> approach I'd pick. The drawback is probably that we send extra
> prepares after a restart, which might be quite common
> while using test_decoding but not so common when using the pgoutput
> and real world scenarios of pub/sub.
>

The restarts would be rare. It depends on how one uses test_decoding
module, this is primarily for testing and if you write a test in way
that it tries to perform wal decoding again and again for the same WAL
(aka simulating restarts) then probably you would see it again but
otherwise, one shouldn't see it.

-- 
With Regards,
Amit Kapila.



pgsql-hackers by date:

Previous
From: Julien Rouhaud
Date:
Subject: Re: pg_stat_statements oddity with track = all
Next
From: Bharath Rupireddy
Date:
Subject: Re: A new function to wait for the backend exit after termination