summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2019-03-28 10:34:43 +1300
committerThomas Munro <tmunro@postgresql.org>2019-03-28 18:12:20 +1300
commit2fc7af5e966043a412e8e69c135fae55a2db6d4f (patch)
treeed1c75e994fe6a49e1636ab5180b608a5dfcc423 /src/backend/utils
parent2a96909a4a8c38705163b83a81b228d5aec197f9 (diff)
Add basic infrastructure for 64 bit transaction IDs.
Instead of inferring epoch progress from xids and checkpoints, introduce a 64 bit FullTransactionId type and use it to track xid generation. This fixes an unlikely bug where the epoch is reported incorrectly if the range of active xids wraps around more than once between checkpoints. The only user-visible effect of this commit is to correct the epoch used by txid_current() and txid_status(), also visible with pg_controldata, in those rare circumstances. It also creates some basic infrastructure so that later patches can use 64 bit transaction IDs in more places. The new type is a struct that we pass by value, as a form of strong typedef. This prevents the sort of accidental confusion between TransactionId and FullTransactionId that would be possible if we were to use a plain old uint64. Author: Thomas Munro Reported-by: Amit Kapila Reviewed-by: Andres Freund, Tom Lane, Heikki Linnakangas Discussion: https://postgr.es/m/CAA4eK1%2BMv%2Bmb0HFfWM9Srtc6MVe160WFurXV68iAFMcagRZ0dQ%40mail.gmail.com
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/adt/txid.c13
-rw-r--r--src/backend/utils/misc/pg_controldata.c5
2 files changed, 12 insertions, 6 deletions
diff --git a/src/backend/utils/adt/txid.c b/src/backend/utils/adt/txid.c
index 9958b1a55e8..4483db573f3 100644
--- a/src/backend/utils/adt/txid.c
+++ b/src/backend/utils/adt/txid.c
@@ -91,7 +91,10 @@ typedef struct
static void
load_xid_epoch(TxidEpoch *state)
{
- GetNextXidAndEpoch(&state->last_xid, &state->epoch);
+ FullTransactionId fullXid = ReadNextFullTransactionId();
+
+ state->last_xid = XidFromFullTransactionId(fullXid);
+ state->epoch = EpochFromFullTransactionId(fullXid);
}
/*
@@ -114,8 +117,11 @@ TransactionIdInRecentPast(uint64 xid_with_epoch, TransactionId *extracted_xid)
TransactionId xid = (TransactionId) xid_with_epoch;
uint32 now_epoch;
TransactionId now_epoch_next_xid;
+ FullTransactionId now_fullxid;
- GetNextXidAndEpoch(&now_epoch_next_xid, &now_epoch);
+ now_fullxid = ReadNextFullTransactionId();
+ now_epoch_next_xid = XidFromFullTransactionId(now_fullxid);
+ now_epoch = EpochFromFullTransactionId(now_fullxid);
if (extracted_xid != NULL)
*extracted_xid = xid;
@@ -128,8 +134,7 @@ TransactionIdInRecentPast(uint64 xid_with_epoch, TransactionId *extracted_xid)
return true;
/* If the transaction ID is in the future, throw an error. */
- if (xid_epoch > now_epoch
- || (xid_epoch == now_epoch && xid >= now_epoch_next_xid))
+ if (xid_with_epoch >= U64FromFullTransactionId(now_fullxid))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("transaction ID %s is in the future",
diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c
index e6742dc24b8..e675c33c547 100644
--- a/src/backend/utils/misc/pg_controldata.c
+++ b/src/backend/utils/misc/pg_controldata.c
@@ -16,6 +16,7 @@
#include "postgres.h"
#include "access/htup_details.h"
+#include "access/transam.h"
#include "access/xlog_internal.h"
#include "access/xlog.h"
#include "catalog/pg_control.h"
@@ -164,8 +165,8 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
nulls[5] = false;
values[6] = CStringGetTextDatum(psprintf("%u:%u",
- ControlFile->checkPointCopy.nextXidEpoch,
- ControlFile->checkPointCopy.nextXid));
+ EpochFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid),
+ XidFromFullTransactionId(ControlFile->checkPointCopy.nextFullXid)));
nulls[6] = false;
values[7] = ObjectIdGetDatum(ControlFile->checkPointCopy.nextOid);