subtrans_single_item_cache.v1.patch
application/octet-stream
Filename: subtrans_single_item_cache.v1.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/access/transam/subtrans.c | 18 | 0 |
diff --git a/src/backend/access/transam/subtrans.c b/src/backend/access/transam/subtrans.c
index 6a8e521f89..8aa3d9e53c 100644
--- a/src/backend/access/transam/subtrans.c
+++ b/src/backend/access/transam/subtrans.c
@@ -54,6 +54,14 @@
#define TransactionIdToPage(xid) ((xid) / (TransactionId) SUBTRANS_XACTS_PER_PAGE)
#define TransactionIdToEntry(xid) ((xid) % (TransactionId) SUBTRANS_XACTS_PER_PAGE)
+/*
+ * Single-item cache for results of SubTransGetTopmostTransaction. It's worth having
+ * such a cache because we frequently find ourselves repeatedly checking the
+ * same XID, for example when scanning a table just after a bulk insert,
+ * update, or delete.
+ */
+static TransactionId cachedFetchXid = InvalidTransactionId;
+static TransactionId cachedFetchTopmostXid = InvalidTransactionId;
/*
* Link to shared-memory data structures for SUBTRANS control
@@ -155,6 +163,13 @@ SubTransGetTopmostTransaction(TransactionId xid)
/* Can't ask about stuff that might not be around anymore */
Assert(TransactionIdFollowsOrEquals(xid, TransactionXmin));
+ /*
+ * Before going to the subtrans log, check our single item cache to
+ * see if we know the result from a previous/recent request.
+ */
+ if (TransactionIdEquals(xid, cachedFetchXid))
+ return cachedFetchTopmostXid;
+
while (TransactionIdIsValid(parentXid))
{
previousXid = parentXid;
@@ -174,6 +189,9 @@ SubTransGetTopmostTransaction(TransactionId xid)
Assert(TransactionIdIsValid(previousXid));
+ cachedFetchXid = xid;
+ cachedFetchTopmostXid = previousXid;
+
return previousXid;
}