1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-14 08:21:07 +03:00

Make TransactionIdIsInProgress check transam.c's single-item XID status cache

before it goes groveling through the ProcArray.  In situations where the same
recently-committed transaction ID is checked repeatedly by tqual.c, this saves
a lot of shared-memory searches.  And it's cheap enough that it shouldn't
hurt noticeably when it doesn't help.
Concept and patch by Simon, some minor tweaking and comment-cleanup by Tom.
This commit is contained in:
Tom Lane
2008-03-11 20:20:35 +00:00
parent ba8a9a9282
commit 611b4393f2
3 changed files with 67 additions and 32 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.73 2008/01/01 19:45:48 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/transam.c,v 1.74 2008/03/11 20:20:35 tgl Exp $
*
* NOTES
* This file contains the high level access-method interface to the
@ -25,12 +25,11 @@
#include "utils/tqual.h"
static XidStatus TransactionLogFetch(TransactionId transactionId);
static void TransactionLogUpdate(TransactionId transactionId,
XidStatus status, XLogRecPtr lsn);
/*
* Single-item cache for results of TransactionLogFetch.
* Single-item cache for results of TransactionLogFetch. 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 XidStatus cachedFetchXidStatus;
@ -39,9 +38,14 @@ static XLogRecPtr cachedCommitLSN;
/* Handy constant for an invalid xlog recptr */
static const XLogRecPtr InvalidXLogRecPtr = {0, 0};
/* Local functions */
static XidStatus TransactionLogFetch(TransactionId transactionId);
static void TransactionLogUpdate(TransactionId transactionId,
XidStatus status, XLogRecPtr lsn);
/* ----------------------------------------------------------------
* postgres log access method interface
* Postgres log access method interface
*
* TransactionLogFetch
* TransactionLogUpdate
@ -82,8 +86,8 @@ TransactionLogFetch(TransactionId transactionId)
xidstatus = TransactionIdGetStatus(transactionId, &xidlsn);
/*
* DO NOT cache status for unfinished or sub-committed transactions! We
* only cache status that is guaranteed not to change.
* Cache it, but DO NOT cache status for unfinished or sub-committed
* transactions! We only cache status that is guaranteed not to change.
*/
if (xidstatus != TRANSACTION_STATUS_IN_PROGRESS &&
xidstatus != TRANSACTION_STATUS_SUB_COMMITTED)
@ -96,12 +100,11 @@ TransactionLogFetch(TransactionId transactionId)
return xidstatus;
}
/* --------------------------------
/*
* TransactionLogUpdate
*
* Store the new status of a transaction. The commit record LSN must be
* passed when recording an async commit; else it should be InvalidXLogRecPtr.
* --------------------------------
*/
static inline void
TransactionLogUpdate(TransactionId transactionId,
@ -131,32 +134,27 @@ TransactionLogMultiUpdate(int nxids, TransactionId *xids,
TransactionIdSetStatus(xids[i], status, lsn);
}
/* ----------------------------------------------------------------
* Interface functions
*
* TransactionId DidCommit
* TransactionId DidAbort
* TransactionId IsInProgress
* TransactionIdDidCommit
* TransactionIdDidAbort
* ========
* these functions test the transaction status of
* a specified transaction id.
*
* TransactionId Commit
* TransactionId Abort
* TransactionIdCommit
* TransactionIdAbort
* ========
* these functions set the transaction status
* of the specified xid.
*
* See also TransactionIdIsInProgress, which once was in this module
* but now lives in procarray.c.
* ----------------------------------------------------------------
*/
/* --------------------------------
* TransactionId DidCommit
* TransactionId DidAbort
* TransactionId IsInProgress
* --------------------------------
*/
/*
* TransactionIdDidCommit
* True iff transaction associated with the identifier did commit.
@ -262,11 +260,33 @@ TransactionIdDidAbort(TransactionId transactionId)
return false;
}
/* --------------------------------
* TransactionId Commit
* TransactionId Abort
* --------------------------------
/*
* TransactionIdIsKnownCompleted
* True iff transaction associated with the identifier is currently
* known to have either committed or aborted.
*
* This does NOT look into pg_clog but merely probes our local cache
* (and so it's not named TransactionIdDidComplete, which would be the
* appropriate name for a function that worked that way). The intended
* use is just to short-circuit TransactionIdIsInProgress calls when doing
* repeated tqual.c checks for the same XID. If this isn't extremely fast
* then it will be counterproductive.
*
* Note:
* Assumes transaction identifier is valid.
*/
bool
TransactionIdIsKnownCompleted(TransactionId transactionId)
{
if (TransactionIdEquals(transactionId, cachedFetchXid))
{
/* If it's in the cache at all, it must be completed. */
return true;
}
return false;
}
/*
* TransactionIdCommit
@ -292,7 +312,6 @@ TransactionIdAsyncCommit(TransactionId transactionId, XLogRecPtr lsn)
TransactionLogUpdate(transactionId, TRANSACTION_STATUS_COMMITTED, lsn);
}
/*
* TransactionIdAbort
* Aborts the transaction associated with the identifier.
@ -352,7 +371,6 @@ TransactionIdAsyncCommitTree(int nxids, TransactionId *xids, XLogRecPtr lsn)
lsn);
}
/*
* TransactionIdAbortTree
* Marks all the given transaction ids as aborted.
@ -368,6 +386,7 @@ TransactionIdAbortTree(int nxids, TransactionId *xids)
InvalidXLogRecPtr);
}
/*
* TransactionIdPrecedes --- is id1 logically < id2?
*/