v202311272-0003-tweak-ReorderBufferSequenceIsTransactiona.txt
text/plain
Filename: v202311272-0003-tweak-ReorderBufferSequenceIsTransactiona.txt
Type: text/plain
Part: 2
From dedc8f1d1ab3e75127e31fcee1bc765bb191978e Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@2ndquadrant.com>
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