Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/backend/access/index/genam.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,8 +483,22 @@ systable_beginscan(Relation heapRelation,
static inline void
HandleConcurrentAbort()
{
if (TransactionIdIsValid(CheckXidAlive) &&
!TransactionIdIsInProgress(CheckXidAlive) &&
if (!TransactionIdIsValid(CheckXidAlive))
return;

if (decoding_xid_status_hook)
{
DecodingXidStatus status = decoding_xid_status_hook(CheckXidAlive);

if (status == DECODING_XID_ABORTED)
ereport(ERROR,
(errcode(ERRCODE_TRANSACTION_ROLLBACK),
errmsg("transaction aborted during system catalog scan")));
if (status != DECODING_XID_NOT_HANDLED)
return;
}

if (!TransactionIdIsInProgress(CheckXidAlive) &&
!TransactionIdDidCommit(CheckXidAlive))
ereport(ERROR,
(errcode(ERRCODE_TRANSACTION_ROLLBACK),
Expand Down
2 changes: 2 additions & 0 deletions src/backend/access/transam/xact.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ int synchronous_commit = SYNCHRONOUS_COMMIT_ON;
* concurrent aborts only in systable_* APIs.
*/
TransactionId CheckXidAlive = InvalidTransactionId;

decoding_xid_status_hook_type decoding_xid_status_hook = NULL;
bool bsysscan = false;

/*
Expand Down
19 changes: 17 additions & 2 deletions src/backend/replication/logical/reorderbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,8 @@ ReorderBufferProcessPartialChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
if (ReorderBufferCanStartStreaming(rb) &&
!(rbtxn_has_partial_change(toptxn)) &&
rbtxn_is_serialized(txn) &&
rbtxn_has_streamable_change(toptxn))
rbtxn_has_streamable_change(toptxn) &&
!rbtxn_no_streaming(toptxn))
ReorderBufferStreamTXN(rb, toptxn);
}

Expand Down Expand Up @@ -1999,6 +2000,20 @@ SetupCheckXidLive(TransactionId xid)
* setup CheckXidAlive if it's not committed yet. We don't check if the
* xid is aborted. That will happen during catalog access.
*/
if (decoding_xid_status_hook)
{
DecodingXidStatus status = decoding_xid_status_hook(xid);

if (status != DECODING_XID_NOT_HANDLED)
{
if (status == DECODING_XID_COMMITTED)
CheckXidAlive = InvalidTransactionId;
else
CheckXidAlive = xid;
return;
}
}

if (!TransactionIdDidCommit(xid))
CheckXidAlive = xid;
else
Expand Down Expand Up @@ -3739,7 +3754,7 @@ ReorderBufferLargestStreamableTopTXN(ReorderBuffer *rb)

if ((largest == NULL || txn->total_size > largest_size) &&
(txn->total_size > 0) && !(rbtxn_has_partial_change(txn)) &&
rbtxn_has_streamable_change(txn))
rbtxn_has_streamable_change(txn) && !rbtxn_no_streaming(txn))
{
largest = txn;
largest_size = txn->total_size;
Expand Down
18 changes: 18 additions & 0 deletions src/include/access/xact.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,24 @@ extern PGDLLIMPORT int synchronous_commit;

/* used during logical streaming of a transaction */
extern PGDLLIMPORT TransactionId CheckXidAlive;

/*
* Status of a decoded transaction id as reported by a storage engine whose
* transactions carry logical-only xids (no clog backing). Consulted by the
* concurrent-abort detection during streamed logical decoding instead of
* TransactionIdIsInProgress()/TransactionIdDidCommit(), which would attempt
* a clog lookup for an xid that no transam machinery ever assigned.
*/
typedef enum DecodingXidStatus
{
DECODING_XID_NOT_HANDLED, /* not a logical-only xid; use clog paths */
DECODING_XID_IN_PROGRESS,
DECODING_XID_COMMITTED,
DECODING_XID_ABORTED
} DecodingXidStatus;

typedef DecodingXidStatus (*decoding_xid_status_hook_type) (TransactionId xid);
extern PGDLLIMPORT decoding_xid_status_hook_type decoding_xid_status_hook;
extern PGDLLIMPORT bool bsysscan;

/*
Expand Down
4 changes: 4 additions & 0 deletions src/include/replication/reorderbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ typedef struct ReorderBufferChange
#define RBTXN_HAS_STREAMABLE_CHANGE 0x0100
#define RBTXN_DISTR_INVAL_OVERFLOWED 0x0200
#define RBTXN_DISTR_SKIP_CLEANUP 0x0400
#define RBTXN_NO_STREAMING 0x0800

/* Has a storage engine marked this transaction as not streamable? */
#define rbtxn_no_streaming(txn) ( ((txn)->txn_flags & RBTXN_NO_STREAMING) != 0 )

/* Does the transaction have catalog changes? */
#define rbtxn_has_catalog_changes(txn) \
Expand Down