Re: [HACKERS] logical decoding of two-phase transactions
Amit Kapila <amit.kapila16@gmail.com>
On Tue, Sep 29, 2020 at 5:08 PM Ajin Cherian <itsajin@gmail.com> wrote: > > On Wed, Sep 23, 2020 at 2:39 PM Amit Kapila <amit.kapila16@gmail.com> wrote: > > > If the transaction is prepared which you can ensure via > > ReorderBufferTxnIsPrepared() (considering you have a proper check in > > that function), it should not require skipping the transaction in > > Abort. One way it could happen is if you clean up the ReorderBufferTxn > > in Prepare which you were doing in earlier version of patch which I > > pointed out was wrong, if you have changed that then I don't know why > > it could fail, may be someplace else during prepare the patch is > > freeing it. Just check that. > > I had a look at this problem. The problem happens when decoding is > done after a prepare but before the corresponding rollback > prepared/commit prepared. > For eg: > > Begin; > <change 1> > <change 2> > PREPARE TRANSACTION '<prepare#1>'; > SELECT data FROM pg_logical_slot_get_changes(...); > : > : > ROLLBACK PREPARED '<prepare#1>'; > SELECT data FROM pg_logical_slot_get_changes(...); > > Since the prepare is consumed in the first call to > pg_logical_slot_get_changes, subsequently when it is encountered in > the second call, it is skipped (as already decoded) in DecodePrepare > and the txn->flags are not set to > reflect the fact that it was prepared. The same behaviour is seen when > it is commit prepared after the original prepare was consumed. > Initially I was thinking about the following approach to fix it in DecodePrepare > Approach 1: > 1. Break the big Skip check in DecodePrepare into 2 parts. > Return if the following conditions are true: > If (parsed->dbId != InvalidOid && parsed->dbId != > ctx->slot->data.database) || > ctx->fast_forward || FilterByOrigin(ctx, origin_id)) > > 2. Check If this condition is true: > SnapBuildXactNeedsSkip(ctx->snapshot_builder, buf->origptr) > > Then this means we are skipping because this has already > been decoded, then instead of returning, call a new function > ReorderBufferMarkPrepare() which will only update the flags in the txn > to indicate that the transaction is prepared > Then later in DecodeAbort or DecodeCommit, we can confirm > that the transaction has been Prepared by checking if the flag is set > and call ReorderBufferFinishPrepared appropriately. > > But then, thinking about this some more, I thought of a second approach. > Approach 2: > If the only purpose of all this was to differentiate between > Abort vs Rollback Prepared and Commit vs Commit Prepared, then we dont > need this. We already know the exact operation > in DecodeXactOp and can differentiate there. We only > overloaded DecodeAbort and DecodeCommit for convenience, we can always > call these functions with an extra flag to denote that we are either > commit or aborting a > previously prepared transaction and call > ReorderBufferFinishPrepared accordingly. > The second approach sounds better but you can see if there is not much you want to reuse from DecodeCommit/DecodeAbort then you can even write new functions DecodeCommitPrepared/DecodeAbortPrepared. OTOH, if there is a common code among them then passing the flag would be a better way. -- With Regards, Amit Kapila.
Commits
-
Add prepare API support for streaming transactions in logical replication.
- 63cf61cdeb7b 15.0 landed
-
Doc: minor improvements for logical replication protocol documentation.
- a5cb4f9829fb 15.0 cited
-
Fix test failure in 021_twophase.pl.
- eaf5321c3524 15.0 landed
-
Refactor to make common functions in proto.c and worker.c.
- 91f9861242cd 15.0 landed
-
Unify PostgresNode's new() and get_new_node() methods
- 201a76183e20 15.0 cited
-
Fix potential buffer overruns in proto.c.
- 01c3adcdd85f 15.0 landed
-
Add support for prepared transactions to built-in logical replication.
- a8fd13cab0ba 15.0 cited
-
Refactor function parse_subscription_options.
- 8aafb0261675 15.0 cited
-
Allow enabling two-phase option via replication protocol.
- cda03cfed6b8 15.0 cited
-
Don't use Asserts to check for violations of replication protocol.
- fe6a20ce54cb 14.0 cited
-
Improve psql tab completion for options of subcriptions and publications
- d08237b5b494 14.0 cited
-
Rearrange logrep worker's snapshot handling some more.
- 3a09d75b4f6c 14.0 cited
-
doc: Update information of new messages for logical replication.
- 15c1a9d9cb76 14.0 cited
-
ALTER SUBSCRIPTION ... ADD/DROP PUBLICATION
- 82ed7748b710 14.0 cited
-
Allow pgoutput to send logical decoding messages.
- ac4645c0157f 14.0 cited
-
Refactor function parse_output_parameters.
- 531737ddad21 14.0 cited
-
Avoid repeated decoding of prepared transactions after a restart.
- 8bdb1332eb51 14.0 cited
-
Fix an oversight in ReorderBufferFinishPrepared.
- ade89ba5f408 14.0 landed
-
Allow multiple xacts during table sync in logical replication.
- ce0fdbfe9722 14.0 cited
-
Fix replication of in-progress transactions in tablesync worker.
- 0926e96c4934 14.0 cited
-
Fix 'skip-empty-xacts' option in test_decoding for streaming mode.
- 9653f24ad830 14.0 cited
-
Use Enum for top level logical replication message types.
- 644f0d7cc9c2 14.0 cited
-
Add support for streaming to built-in logical replication.
- 464824323e57 14.0 cited
-
Fix the logical streaming test.
- 82a0ba7707e0 14.0 cited
-
Implement streaming mode in ReorderBuffer.
- 7259736a6e5b 14.0 cited
-
Extend the logical decoding output plugin API with stream methods.
- 45fdc9738b36 14.0 cited
-
Store 2PC GID in commit/abort WAL recs for logical decoding
- 1eb6d6527aae 11.0 cited