Ensure age() returns a stable value rather than the latest value

This commit is contained in:
Simon Riggs 2012-05-11 14:36:24 +01:00
parent 3652d72dd4
commit b06679e012
3 changed files with 26 additions and 5 deletions

View File

@ -391,6 +391,28 @@ GetCurrentTransactionIdIfAny(void)
}
/*
* GetStableLatestTransactionIdIfAny
*
* Get the latest XID once and then return same value for rest of transaction.
* Acts as a useful reference point for maintenance tasks.
*/
TransactionId
GetStableLatestTransactionId(void)
{
static LocalTransactionId lxid = InvalidLocalTransactionId;
static TransactionId stablexid = InvalidTransactionId;
if (lxid != MyProc->lxid ||
!TransactionIdIsValid(stablexid))
{
lxid = MyProc->lxid;
stablexid = ReadNewTransactionId();
}
return stablexid;
}
/*
* AssignTransactionId
*

View File

@ -19,6 +19,7 @@
#include "access/transam.h"
#include "access/xact.h"
#include "libpq/pqformat.h"
#include "storage/proc.h"
#include "utils/builtins.h"
#define PG_GETARG_TRANSACTIONID(n) DatumGetTransactionId(PG_GETARG_DATUM(n))
@ -87,16 +88,13 @@ xideq(PG_FUNCTION_ARGS)
}
/*
* xid_age - compute age of an XID (relative to current xact)
* xid_age - compute age of an XID (relative to latest stable xid)
*/
Datum
xid_age(PG_FUNCTION_ARGS)
{
TransactionId xid = PG_GETARG_TRANSACTIONID(0);
TransactionId now = GetTopTransactionIdIfAny();
if (!TransactionIdIsValid(now))
now = ReadNewTransactionId();
TransactionId now = GetStableLatestTransactionId();
/* Permanent XIDs are always infinitely old */
if (!TransactionIdIsNormal(xid))

View File

@ -209,6 +209,7 @@ extern TransactionId GetTopTransactionId(void);
extern TransactionId GetTopTransactionIdIfAny(void);
extern TransactionId GetCurrentTransactionId(void);
extern TransactionId GetCurrentTransactionIdIfAny(void);
extern TransactionId GetStableLatestTransactionId(void);
extern SubTransactionId GetCurrentSubTransactionId(void);
extern CommandId GetCurrentCommandId(bool used);
extern TimestampTz GetCurrentTransactionStartTimestamp(void);