aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Riggs <simon@2ndQuadrant.com>2012-05-11 14:38:11 +0100
committerSimon Riggs <simon@2ndQuadrant.com>2012-05-11 14:38:11 +0100
commit1a4bc2db6cb80a6e52aed8f5a68b895231653d6c (patch)
tree2882f193163ac3fac7c582f1bb9fcc1498219d88
parent153b1dbaa0b94143041ab1e0cf249a02380f0acf (diff)
downloadpostgresql-1a4bc2db6cb80a6e52aed8f5a68b895231653d6c.tar.gz
postgresql-1a4bc2db6cb80a6e52aed8f5a68b895231653d6c.zip
Ensure age() returns a stable value rather than the latest value
-rw-r--r--src/backend/access/transam/xact.c22
-rw-r--r--src/backend/utils/adt/xid.c8
-rw-r--r--src/include/access/xact.h1
3 files changed, 26 insertions, 5 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 901fff059a1..be4905181e0 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -394,6 +394,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
*
* Assigns a new permanent XID to the given TransactionState.
diff --git a/src/backend/utils/adt/xid.c b/src/backend/utils/adt/xid.c
index 229e8e43e69..eecfee4e2ad 100644
--- a/src/backend/utils/adt/xid.c
+++ b/src/backend/utils/adt/xid.c
@@ -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))
diff --git a/src/include/access/xact.h b/src/include/access/xact.h
index cb440d41f14..29ef4a1bce3 100644
--- a/src/include/access/xact.h
+++ b/src/include/access/xact.h
@@ -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);