]> granicus.if.org Git - postgresql/commitdiff
Ensure age() returns a stable value rather than the latest value
authorSimon Riggs <simon@2ndQuadrant.com>
Fri, 11 May 2012 13:38:11 +0000 (14:38 +0100)
committerSimon Riggs <simon@2ndQuadrant.com>
Fri, 11 May 2012 13:38:11 +0000 (14:38 +0100)
src/backend/access/transam/xact.c
src/backend/utils/adt/xid.c
src/include/access/xact.h

index 901fff059a1e9480e82179b8488d9663209f388f..be4905181e00e7aa7e8d4c0b1f3197d0eaf30aef 100644 (file)
@@ -393,6 +393,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 229e8e43e69eedb8794bcbb821c4d9a5e4eceef0..eecfee4e2ade63bac17495a2a3c66b753b77a8c8 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 cb440d41f1401f69698481e2c175eb903f879fed..29ef4a1bce388e90304b3ccaee06169d8b27cb14 100644 (file)
@@ -198,6 +198,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);