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:
@ -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?
|
||||
*/
|
||||
|
Reference in New Issue
Block a user