Add single-item cache when looking at topmost XID of a subtrans XID

This change affects SubTransGetTopmostTransaction(), used to find the
topmost transaction ID of a given transaction ID.  The cache is able to
store one value, so as we can save the backend from unnecessary lookups
at pg_subtrans/ on repetitive calls of this routine.  There is a similar
practice in transam.c, for example.

Author: Simon Riggs
Reviewed-by: Andrey Borodin, Julien Rouhaud
Discussion: https://postgr.es/m/CANbhV-G8Co=yq4v4BkW7MJDqVt68K_8A48nAZ_+8UQS7LrwLEQ@mail.gmail.com
This commit is contained in:
Michael Paquier 2022-04-07 14:34:37 +09:00
parent fbfe6910ec
commit 06f5295af6

View File

@ -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 cachedFetchSubXid = 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, cachedFetchSubXid))
return cachedFetchTopmostXid;
while (TransactionIdIsValid(parentXid))
{
previousXid = parentXid;
@ -174,6 +189,9 @@ SubTransGetTopmostTransaction(TransactionId xid)
Assert(TransactionIdIsValid(previousXid));
cachedFetchSubXid = xid;
cachedFetchTopmostXid = previousXid;
return previousXid;
}