Ensure age() returns a stable value rather than the latest value
authorSimon Riggs
Fri, 11 May 2012 13:38:53 +0000 (14:38 +0100)
committerSimon Riggs
Fri, 11 May 2012 13:38:53 +0000 (14:38 +0100)
src/backend/access/transam/xact.c
src/backend/utils/adt/xid.c
src/include/access/xact.h

index 750725a43af15785e05e252eb24a911539b6c568..df790c0693e3e327e666b58ff6ae300b9e29cb77 100644 (file)
@@ -387,6 +387,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
  *
index 7db6bb1a66083e4d4f25e0f6d20f2ed46d1d1721..a9046cc964cff7811bc6efe113560338e26d5300 100644 (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))
index 12ec693f4431f805aa105086928e32d4bedf61ae..daa42d9243551779c9d5e6825ba3d7313c23751a 100644 (file)
@@ -177,6 +177,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);