From dedc8f1d1ab3e75127e31fcee1bc765bb191978e Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Mon, 27 Nov 2023 01:39:13 +0100 Subject: [PATCH v202311272 3/4] tweak ReorderBufferSequenceIsTransactional --- src/backend/replication/logical/decode.c | 2 +- .../replication/logical/reorderbuffer.c | 67 +++++++++---------- src/include/replication/reorderbuffer.h | 3 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c index 9bfed0f5ce..70bf94d8fb 100644 --- a/src/backend/replication/logical/decode.c +++ b/src/backend/replication/logical/decode.c @@ -1439,7 +1439,7 @@ seq_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) */ transactional = ReorderBufferSequenceIsTransactional(ctx->reorder, target_locator, - NULL); + xid, NULL); /* Skip the change if already processed (per the snapshot). */ if (transactional && diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index f21aa340c8..b88b460ae1 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -1013,50 +1013,49 @@ ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid, bool ReorderBufferSequenceIsTransactional(ReorderBuffer *rb, RelFileLocator rlocator, - TransactionId *xid) + TransactionId xidin, + TransactionId *xidout) { bool found = false; - dlist_iter iter; + ReorderBufferTXN *txn; + ReorderBufferSequenceEnt *entry; AssertCheckSequences(rb); /* - * Walk all top-level transactions (some of which may be subxacts, except - * that we haven't processed the assignments yet), and check if any of - * them created the relfilenode. + * Try to lookup transaction with the XID of the change. If it exists, the + * relfilenode would have to be either in it or the top-level transaction + * (if it was created in some earlier subtransaction). + * + * If this is a subxact, we'll search just the top-level hash table. That's + * simpler and likely faster than having to search two hash tables. */ - dlist_foreach(iter, &rb->toplevel_by_lsn) - { - ReorderBufferSequenceEnt *entry; - ReorderBufferTXN *txn = dlist_container(ReorderBufferTXN, node, - iter.cur); + txn = ReorderBufferTXNByXid(rb, xidin, false, NULL, InvalidXLogRecPtr, + false); - /* transaction has no relfilenodes at all */ - if (!txn->sequences_hash) - continue; + if (!txn) + return false; - entry = hash_search(txn->sequences_hash, - (void *) &rlocator, - HASH_FIND, - &found); - /* - * If we found an entry with matchine relfilenode, we're done - we - * have to treat the sequence change as transactional, and replay it - * in the same (sub)transaction just like any other change. - * - * Optionally set XID of the (sub)xact that created the relfilenode. - */ - if (found) - { - if (xid) - *xid = entry->txn->xid; + /* If there's top-level transaction, search that one. */ + txn = (txn->toptxn) ? txn->toptxn : txn; - break; - } - } + /* transaction has no relfilenodes, can't be transactional */ + if (!txn->sequences_hash) + return false; + + entry = hash_search(txn->sequences_hash, + (void *) &rlocator, + HASH_FIND, + &found); + + if (!found) + return false; - return found; + if (xidout) + *xidout = entry->txn->xid; + + return true; } /* @@ -1145,7 +1144,7 @@ ReorderBufferQueueSequence(ReorderBuffer *rb, TransactionId xid, change->data.sequence.tuple = tuplebuf; /* lookup the XID for transaction that created the relfilenode */ - ReorderBufferSequenceIsTransactional(rb, rlocator, &xid); + ReorderBufferSequenceIsTransactional(rb, rlocator, xid, &xid); /* the XID should be valid for a transactional change */ Assert(TransactionIdIsValid(xid)); @@ -1170,7 +1169,7 @@ ReorderBufferQueueSequence(ReorderBuffer *rb, TransactionId xid, Assert(snapshot_now); /* Make sure the sequence is not in any of the hash tables */ - Assert(!ReorderBufferSequenceIsTransactional(rb, rlocator, NULL)); + Assert(!ReorderBufferSequenceIsTransactional(rb, rlocator, xid, NULL)); if (xid != InvalidTransactionId) txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, true); diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index 58a99b7406..a44a0f4dfb 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -790,6 +790,7 @@ extern void ReorderBufferAddRelFileLocator(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn, RelFileLocator rlocator); extern bool ReorderBufferSequenceIsTransactional(ReorderBuffer *rb, RelFileLocator locator, - TransactionId *xid); + TransactionId xidin, + TransactionId *xidout); #endif -- 2.27.0