v20231128-0002-tweak-ReorderBufferSequenceIsTransactional.patch
text/x-patch
Filename: v20231128-0002-tweak-ReorderBufferSequenceIsTransactional.patch
Type: text/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v20231128-0002
Subject: tweak ReorderBufferSequenceIsTransactional
| File | + | − |
|---|---|---|
| src/backend/replication/logical/decode.c | 1 | 1 |
| src/backend/replication/logical/reorderbuffer.c | 32 | 34 |
| src/include/replication/reorderbuffer.h | 2 | 1 |
From bb5d9bf716b407e0df6b062d8e72730b9720dac0 Mon Sep 17 00:00:00 2001
From: Tomas Vondra <tomas@2ndquadrant.com>
Date: Mon, 27 Nov 2023 01:39:13 +0100
Subject: [PATCH v20231128 2/8] tweak ReorderBufferSequenceIsTransactional
---
src/backend/replication/logical/decode.c | 2 +-
.../replication/logical/reorderbuffer.c | 66 +++++++++----------
src/include/replication/reorderbuffer.h | 3 +-
3 files changed, 35 insertions(+), 36 deletions(-)
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index 5adeba4f70c..0248aee83d7 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 5eef0d89a98..61781b62bb8 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -1013,50 +1013,48 @@ 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 there's top-level transaction, search that one. */
+ txn = (txn->toptxn) ? txn->toptxn : txn;
- /*
- * If we found an entry with matching 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;
+ /* transaction has no relfilenodes, can't be transactional */
+ if (!txn->sequences_hash)
+ return false;
- break;
- }
- }
+ entry = hash_search(txn->sequences_hash,
+ (void *) &rlocator,
+ HASH_FIND,
+ &found);
- return found;
+ if (!found)
+ return false;
+
+ if (xidout)
+ *xidout = entry->txn->xid;
+
+ return true;
}
/*
@@ -1145,7 +1143,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 +1168,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 58a99b74060..a44a0f4dfb9 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.41.0