PostgreSQL Source Code  git master
transam.h File Reference
#include "access/xlogdefs.h"
Include dependency graph for transam.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  FullTransactionId
 
struct  VariableCacheData
 

Macros

#define InvalidTransactionId   ((TransactionId) 0)
 
#define BootstrapTransactionId   ((TransactionId) 1)
 
#define FrozenTransactionId   ((TransactionId) 2)
 
#define FirstNormalTransactionId   ((TransactionId) 3)
 
#define MaxTransactionId   ((TransactionId) 0xFFFFFFFF)
 
#define TransactionIdIsValid(xid)   ((xid) != InvalidTransactionId)
 
#define TransactionIdIsNormal(xid)   ((xid) >= FirstNormalTransactionId)
 
#define TransactionIdEquals(id1, id2)   ((id1) == (id2))
 
#define TransactionIdStore(xid, dest)   (*(dest) = (xid))
 
#define StoreInvalidTransactionId(dest)   (*(dest) = InvalidTransactionId)
 
#define EpochFromFullTransactionId(x)   ((uint32) ((x).value >> 32))
 
#define XidFromFullTransactionId(x)   ((uint32) (x).value)
 
#define U64FromFullTransactionId(x)   ((x).value)
 
#define FullTransactionIdEquals(a, b)   ((a).value == (b).value)
 
#define FullTransactionIdPrecedes(a, b)   ((a).value < (b).value)
 
#define FullTransactionIdPrecedesOrEquals(a, b)   ((a).value <= (b).value)
 
#define FullTransactionIdFollows(a, b)   ((a).value > (b).value)
 
#define FullTransactionIdFollowsOrEquals(a, b)   ((a).value >= (b).value)
 
#define FullTransactionIdIsValid(x)   TransactionIdIsValid(XidFromFullTransactionId(x))
 
#define InvalidFullTransactionId   FullTransactionIdFromEpochAndXid(0, InvalidTransactionId)
 
#define FirstNormalFullTransactionId   FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId)
 
#define FullTransactionIdIsNormal(x)   FullTransactionIdFollowsOrEquals(x, FirstNormalFullTransactionId)
 
#define TransactionIdAdvance(dest)
 
#define TransactionIdRetreat(dest)
 
#define NormalTransactionIdPrecedes(id1, id2)
 
#define NormalTransactionIdFollows(id1, id2)
 
#define FirstGenbkiObjectId   10000
 
#define FirstUnpinnedObjectId   12000
 
#define FirstNormalObjectId   16384
 
#define AssertTransactionIdInAllowableRange(xid)   ((void)true)
 

Typedefs

typedef struct FullTransactionId FullTransactionId
 
typedef struct VariableCacheData VariableCacheData
 
typedef VariableCacheDataVariableCache
 

Functions

static FullTransactionId FullTransactionIdFromEpochAndXid (uint32 epoch, TransactionId xid)
 
static FullTransactionId FullTransactionIdFromU64 (uint64 value)
 
static void FullTransactionIdRetreat (FullTransactionId *dest)
 
static void FullTransactionIdAdvance (FullTransactionId *dest)
 
bool TransactionStartedDuringRecovery (void)
 
bool TransactionIdDidCommit (TransactionId transactionId)
 
bool TransactionIdDidAbort (TransactionId transactionId)
 
void TransactionIdCommitTree (TransactionId xid, int nxids, TransactionId *xids)
 
void TransactionIdAsyncCommitTree (TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn)
 
void TransactionIdAbortTree (TransactionId xid, int nxids, TransactionId *xids)
 
bool TransactionIdPrecedes (TransactionId id1, TransactionId id2)
 
bool TransactionIdPrecedesOrEquals (TransactionId id1, TransactionId id2)
 
bool TransactionIdFollows (TransactionId id1, TransactionId id2)
 
bool TransactionIdFollowsOrEquals (TransactionId id1, TransactionId id2)
 
TransactionId TransactionIdLatest (TransactionId mainxid, int nxids, const TransactionId *xids)
 
XLogRecPtr TransactionIdGetCommitLSN (TransactionId xid)
 
FullTransactionId GetNewTransactionId (bool isSubXact)
 
void AdvanceNextFullTransactionIdPastXid (TransactionId xid)
 
FullTransactionId ReadNextFullTransactionId (void)
 
void SetTransactionIdLimit (TransactionId oldest_datfrozenxid, Oid oldest_datoid)
 
void AdvanceOldestClogXid (TransactionId oldest_datfrozenxid)
 
bool ForceTransactionIdLimitUpdate (void)
 
Oid GetNewObjectId (void)
 
void StopGeneratingPinnedObjectIds (void)
 
static TransactionId ReadNextTransactionId (void)
 
static TransactionId TransactionIdRetreatedBy (TransactionId xid, uint32 amount)
 
static TransactionId TransactionIdOlder (TransactionId a, TransactionId b)
 
static TransactionId NormalTransactionIdOlder (TransactionId a, TransactionId b)
 
static FullTransactionId FullTransactionIdNewer (FullTransactionId a, FullTransactionId b)
 

Variables

PGDLLIMPORT VariableCache ShmemVariableCache
 

Macro Definition Documentation

◆ AssertTransactionIdInAllowableRange

#define AssertTransactionIdInAllowableRange (   xid)    ((void)true)

Definition at line 301 of file transam.h.

◆ BootstrapTransactionId

#define BootstrapTransactionId   ((TransactionId) 1)

Definition at line 32 of file transam.h.

◆ EpochFromFullTransactionId

#define EpochFromFullTransactionId (   x)    ((uint32) ((x).value >> 32))

Definition at line 47 of file transam.h.

◆ FirstGenbkiObjectId

#define FirstGenbkiObjectId   10000

Definition at line 195 of file transam.h.

◆ FirstNormalFullTransactionId

#define FirstNormalFullTransactionId   FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId)

Definition at line 57 of file transam.h.

◆ FirstNormalObjectId

#define FirstNormalObjectId   16384

Definition at line 197 of file transam.h.

◆ FirstNormalTransactionId

#define FirstNormalTransactionId   ((TransactionId) 3)

Definition at line 34 of file transam.h.

◆ FirstUnpinnedObjectId

#define FirstUnpinnedObjectId   12000

Definition at line 196 of file transam.h.

◆ FrozenTransactionId

#define FrozenTransactionId   ((TransactionId) 2)

Definition at line 33 of file transam.h.

◆ FullTransactionIdEquals

#define FullTransactionIdEquals (   a,
  b 
)    ((a).value == (b).value)

Definition at line 50 of file transam.h.

◆ FullTransactionIdFollows

#define FullTransactionIdFollows (   a,
  b 
)    ((a).value > (b).value)

Definition at line 53 of file transam.h.

◆ FullTransactionIdFollowsOrEquals

#define FullTransactionIdFollowsOrEquals (   a,
  b 
)    ((a).value >= (b).value)

Definition at line 54 of file transam.h.

◆ FullTransactionIdIsNormal

#define FullTransactionIdIsNormal (   x)    FullTransactionIdFollowsOrEquals(x, FirstNormalFullTransactionId)

Definition at line 58 of file transam.h.

◆ FullTransactionIdIsValid

#define FullTransactionIdIsValid (   x)    TransactionIdIsValid(XidFromFullTransactionId(x))

Definition at line 55 of file transam.h.

◆ FullTransactionIdPrecedes

#define FullTransactionIdPrecedes (   a,
  b 
)    ((a).value < (b).value)

Definition at line 51 of file transam.h.

◆ FullTransactionIdPrecedesOrEquals

#define FullTransactionIdPrecedesOrEquals (   a,
  b 
)    ((a).value <= (b).value)

Definition at line 52 of file transam.h.

◆ InvalidFullTransactionId

#define InvalidFullTransactionId   FullTransactionIdFromEpochAndXid(0, InvalidTransactionId)

Definition at line 56 of file transam.h.

◆ InvalidTransactionId

#define InvalidTransactionId   ((TransactionId) 0)

Definition at line 31 of file transam.h.

◆ MaxTransactionId

#define MaxTransactionId   ((TransactionId) 0xFFFFFFFF)

Definition at line 35 of file transam.h.

◆ NormalTransactionIdFollows

#define NormalTransactionIdFollows (   id1,
  id2 
)
Value:
(int32) ((id1) - (id2)) > 0)
#define AssertMacro(condition)
Definition: c.h:848
signed int int32
Definition: c.h:483
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

Definition at line 152 of file transam.h.

◆ NormalTransactionIdPrecedes

#define NormalTransactionIdPrecedes (   id1,
  id2 
)
Value:
(int32) ((id1) - (id2)) < 0)

Definition at line 147 of file transam.h.

◆ StoreInvalidTransactionId

#define StoreInvalidTransactionId (   dest)    (*(dest) = InvalidTransactionId)

Definition at line 45 of file transam.h.

◆ TransactionIdAdvance

#define TransactionIdAdvance (   dest)
Value:
do { \
(dest)++; \
} while(0)
#define FirstNormalTransactionId
Definition: transam.h:34

Definition at line 91 of file transam.h.

◆ TransactionIdEquals

#define TransactionIdEquals (   id1,
  id2 
)    ((id1) == (id2))

Definition at line 43 of file transam.h.

◆ TransactionIdIsNormal

#define TransactionIdIsNormal (   xid)    ((xid) >= FirstNormalTransactionId)

Definition at line 42 of file transam.h.

◆ TransactionIdIsValid

#define TransactionIdIsValid (   xid)    ((xid) != InvalidTransactionId)

Definition at line 41 of file transam.h.

◆ TransactionIdRetreat

#define TransactionIdRetreat (   dest)
Value:
do { \
(dest)--; \

Definition at line 141 of file transam.h.

◆ TransactionIdStore

#define TransactionIdStore (   xid,
  dest 
)    (*(dest) = (xid))

Definition at line 44 of file transam.h.

◆ U64FromFullTransactionId

#define U64FromFullTransactionId (   x)    ((x).value)

Definition at line 49 of file transam.h.

◆ XidFromFullTransactionId

#define XidFromFullTransactionId (   x)    ((uint32) (x).value)

Definition at line 48 of file transam.h.

Typedef Documentation

◆ FullTransactionId

◆ VariableCache

Definition at line 257 of file transam.h.

◆ VariableCacheData

Function Documentation

◆ AdvanceNextFullTransactionIdPastXid()

void AdvanceNextFullTransactionIdPastXid ( TransactionId  xid)

Definition at line 277 of file varsup.c.

278 {
279  FullTransactionId newNextFullXid;
280  TransactionId next_xid;
281  uint32 epoch;
282 
283  /*
284  * It is safe to read nextXid without a lock, because this is only called
285  * from the startup process or single-process mode, meaning that no other
286  * process can modify it.
287  */
289 
290  /* Fast return if this isn't an xid high enough to move the needle. */
292  if (!TransactionIdFollowsOrEquals(xid, next_xid))
293  return;
294 
295  /*
296  * Compute the FullTransactionId that comes after the given xid. To do
297  * this, we preserve the existing epoch, but detect when we've wrapped
298  * into a new epoch. This is necessary because WAL records and 2PC state
299  * currently contain 32 bit xids. The wrap logic is safe in those cases
300  * because the span of active xids cannot exceed one epoch at any given
301  * point in the WAL stream.
302  */
305  if (unlikely(xid < next_xid))
306  ++epoch;
307  newNextFullXid = FullTransactionIdFromEpochAndXid(epoch, xid);
308 
309  /*
310  * We still need to take a lock to modify the value when there are
311  * concurrent readers.
312  */
313  LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
314  ShmemVariableCache->nextXid = newNextFullXid;
315  LWLockRelease(XidGenLock);
316 }
unsigned int uint32
Definition: c.h:495
#define unlikely(x)
Definition: c.h:300
uint32 TransactionId
Definition: c.h:641
bool IsUnderPostmaster
Definition: globals.c:113
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1195
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
@ LW_EXCLUSIVE
Definition: lwlock.h:116
#define AmStartupProcess()
Definition: miscadmin.h:452
FullTransactionId nextXid
Definition: transam.h:220
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:329
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
#define XidFromFullTransactionId(x)
Definition: transam.h:48
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
#define TransactionIdAdvance(dest)
Definition: transam.h:91
VariableCache ShmemVariableCache
Definition: varsup.c:34
static const unsigned __int64 epoch

References AmStartupProcess, Assert(), epoch, EpochFromFullTransactionId, FullTransactionIdFromEpochAndXid(), IsUnderPostmaster, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::nextXid, ShmemVariableCache, TransactionIdAdvance, TransactionIdFollowsOrEquals(), unlikely, and XidFromFullTransactionId.

Referenced by ApplyWalRecord(), multixact_redo(), ProcArrayApplyRecoveryInfo(), ProcessTwoPhaseBuffer(), RecordKnownAssignedTransactionIds(), xact_redo_abort(), and xact_redo_commit().

◆ AdvanceOldestClogXid()

void AdvanceOldestClogXid ( TransactionId  oldest_datfrozenxid)

Definition at line 328 of file varsup.c.

329 {
330  LWLockAcquire(XactTruncationLock, LW_EXCLUSIVE);
332  oldest_datfrozenxid))
333  {
334  ShmemVariableCache->oldestClogXid = oldest_datfrozenxid;
335  }
336  LWLockRelease(XactTruncationLock);
337 }
TransactionId oldestClogXid
Definition: transam.h:253
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280

References LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::oldestClogXid, ShmemVariableCache, and TransactionIdPrecedes().

Referenced by BootStrapXLOG(), clog_redo(), StartupXLOG(), and TruncateCLOG().

◆ ForceTransactionIdLimitUpdate()

bool ForceTransactionIdLimitUpdate ( void  )

Definition at line 490 of file varsup.c.

491 {
492  TransactionId nextXid;
493  TransactionId xidVacLimit;
494  TransactionId oldestXid;
495  Oid oldestXidDB;
496 
497  /* Locking is probably not really necessary, but let's be careful */
498  LWLockAcquire(XidGenLock, LW_SHARED);
500  xidVacLimit = ShmemVariableCache->xidVacLimit;
501  oldestXid = ShmemVariableCache->oldestXid;
502  oldestXidDB = ShmemVariableCache->oldestXidDB;
503  LWLockRelease(XidGenLock);
504 
505  if (!TransactionIdIsNormal(oldestXid))
506  return true; /* shouldn't happen, but just in case */
507  if (!TransactionIdIsValid(xidVacLimit))
508  return true; /* this shouldn't happen anymore either */
509  if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit))
510  return true; /* past xidVacLimit, don't delay updating */
512  return true; /* could happen, per comments above */
513  return false;
514 }
@ LW_SHARED
Definition: lwlock.h:117
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
unsigned int Oid
Definition: postgres_ext.h:31
TransactionId oldestXid
Definition: transam.h:222
TransactionId xidVacLimit
Definition: transam.h:223
@ DATABASEOID
Definition: syscache.h:55
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:191
#define TransactionIdIsValid(xid)
Definition: transam.h:41

References DATABASEOID, LW_SHARED, LWLockAcquire(), LWLockRelease(), VariableCacheData::nextXid, ObjectIdGetDatum(), VariableCacheData::oldestXid, VariableCacheData::oldestXidDB, SearchSysCacheExists1, ShmemVariableCache, TransactionIdFollowsOrEquals(), TransactionIdIsNormal, TransactionIdIsValid, XidFromFullTransactionId, and VariableCacheData::xidVacLimit.

Referenced by vac_update_datfrozenxid().

◆ FullTransactionIdAdvance()

static void FullTransactionIdAdvance ( FullTransactionId dest)
inlinestatic

Definition at line 128 of file transam.h.

129 {
130  dest->value++;
131 
132  /* see FullTransactionIdAdvance() */
134  return;
135 
137  dest->value++;
138 }
#define FirstNormalFullTransactionId
Definition: transam.h:57
#define FullTransactionIdPrecedes(a, b)
Definition: transam.h:51

References generate_unaccent_rules::dest, FirstNormalFullTransactionId, FirstNormalTransactionId, FullTransactionIdPrecedes, and XidFromFullTransactionId.

Referenced by GetNewTransactionId(), and GetSnapshotData().

◆ FullTransactionIdFromEpochAndXid()

static FullTransactionId FullTransactionIdFromEpochAndXid ( uint32  epoch,
TransactionId  xid 
)
inlinestatic

Definition at line 71 of file transam.h.

72 {
73  FullTransactionId result;
74 
75  result.value = ((uint64) epoch) << 32 | xid;
76 
77  return result;
78 }
uint64 value
Definition: transam.h:67

References epoch, and FullTransactionId::value.

Referenced by AdvanceNextFullTransactionIdPastXid(), BootStrapXLOG(), FullTransactionIdFromXidAndCtx(), GetNewTransactionId(), GistPageGetDeleteXid(), GuessControlValues(), main(), widen_snapshot_xid(), and XLogRecGetFullXid().

◆ FullTransactionIdFromU64()

static FullTransactionId FullTransactionIdFromU64 ( uint64  value)
inlinestatic

Definition at line 81 of file transam.h.

82 {
83  FullTransactionId result;
84 
85  result.value = value;
86 
87  return result;
88 }
static struct @148 value

References FullTransactionId::value, and value.

Referenced by DatumGetFullTransactionId(), FullTransactionIdFromXidAndCtx(), FullXidRelativeTo(), parse_snapshot(), pg_snapshot_recv(), xid8in(), and xid8recv().

◆ FullTransactionIdNewer()

static FullTransactionId FullTransactionIdNewer ( FullTransactionId  a,
FullTransactionId  b 
)
inlinestatic

Definition at line 360 of file transam.h.

361 {
363  return b;
364 
366  return a;
367 
369  return a;
370  return b;
371 }
int b
Definition: isn.c:70
int a
Definition: isn.c:69
#define FullTransactionIdFollows(a, b)
Definition: transam.h:53
#define FullTransactionIdIsValid(x)
Definition: transam.h:55

References a, b, FullTransactionIdFollows, and FullTransactionIdIsValid.

Referenced by GetSnapshotData(), and GlobalVisUpdateApply().

◆ FullTransactionIdRetreat()

static void FullTransactionIdRetreat ( FullTransactionId dest)
inlinestatic

Definition at line 103 of file transam.h.

104 {
105  dest->value--;
106 
107  /*
108  * In contrast to 32bit XIDs don't step over the "actual" special xids.
109  * For 64bit xids these can't be reached as part of a wraparound as they
110  * can in the 32bit case.
111  */
113  return;
114 
115  /*
116  * But we do need to step over XIDs that'd appear special only for 32bit
117  * XIDs.
118  */
120  dest->value--;
121 }

References generate_unaccent_rules::dest, FirstNormalFullTransactionId, FirstNormalTransactionId, FullTransactionIdPrecedes, and XidFromFullTransactionId.

Referenced by StartupXLOG().

◆ GetNewObjectId()

Oid GetNewObjectId ( void  )

Definition at line 528 of file varsup.c.

529 {
530  Oid result;
531 
532  /* safety check, we should never get this far in a HS standby */
533  if (RecoveryInProgress())
534  elog(ERROR, "cannot assign OIDs during recovery");
535 
536  LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
537 
538  /*
539  * Check for wraparound of the OID counter. We *must* not return 0
540  * (InvalidOid), and in normal operation we mustn't return anything below
541  * FirstNormalObjectId since that range is reserved for initdb (see
542  * IsCatalogRelationOid()). Note we are relying on unsigned comparison.
543  *
544  * During initdb, we start the OID generator at FirstGenbkiObjectId, so we
545  * only wrap if before that point when in bootstrap or standalone mode.
546  * The first time through this routine after normal postmaster start, the
547  * counter will be forced up to FirstNormalObjectId. This mechanism
548  * leaves the OIDs between FirstGenbkiObjectId and FirstNormalObjectId
549  * available for automatic assignment during initdb, while ensuring they
550  * will never conflict with user-assigned OIDs.
551  */
553  {
555  {
556  /* wraparound, or first post-initdb assignment, in normal mode */
559  }
560  else
561  {
562  /* we may be bootstrapping, so don't enforce the full range */
564  {
565  /* wraparound in standalone mode (unlikely but possible) */
568  }
569  }
570  }
571 
572  /* If we run out of logged for use oids then we must log more */
573  if (ShmemVariableCache->oidCount == 0)
574  {
577  }
578 
579  result = ShmemVariableCache->nextOid;
580 
583 
584  LWLockRelease(OidGenLock);
585 
586  return result;
587 }
#define ERROR
Definition: elog.h:39
bool IsPostmasterEnvironment
Definition: globals.c:112
uint32 oidCount
Definition: transam.h:215
#define FirstGenbkiObjectId
Definition: transam.h:195
#define FirstNormalObjectId
Definition: transam.h:197
#define VAR_OID_PREFETCH
Definition: varsup.c:31
bool RecoveryInProgress(void)
Definition: xlog.c:5948
void XLogPutNextOid(Oid nextOid)
Definition: xlog.c:7531

References elog(), ERROR, FirstGenbkiObjectId, FirstNormalObjectId, IsPostmasterEnvironment, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::nextOid, VariableCacheData::oidCount, RecoveryInProgress(), ShmemVariableCache, VAR_OID_PREFETCH, and XLogPutNextOid().

Referenced by GetNewOidWithIndex(), and GetNewRelFileNumber().

◆ GetNewTransactionId()

FullTransactionId GetNewTransactionId ( bool  isSubXact)

Definition at line 50 of file varsup.c.

51 {
52  FullTransactionId full_xid;
53  TransactionId xid;
54 
55  /*
56  * Workers synchronize transaction state at the beginning of each parallel
57  * operation, so we can't account for new XIDs after that point.
58  */
59  if (IsInParallelMode())
60  elog(ERROR, "cannot assign TransactionIds during a parallel operation");
61 
62  /*
63  * During bootstrap initialization, we return the special bootstrap
64  * transaction id.
65  */
67  {
68  Assert(!isSubXact);
72  }
73 
74  /* safety check, we should never get this far in a HS standby */
75  if (RecoveryInProgress())
76  elog(ERROR, "cannot assign TransactionIds during recovery");
77 
78  LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
79 
80  full_xid = ShmemVariableCache->nextXid;
81  xid = XidFromFullTransactionId(full_xid);
82 
83  /*----------
84  * Check to see if it's safe to assign another XID. This protects against
85  * catastrophic data loss due to XID wraparound. The basic rules are:
86  *
87  * If we're past xidVacLimit, start trying to force autovacuum cycles.
88  * If we're past xidWarnLimit, start issuing warnings.
89  * If we're past xidStopLimit, refuse to execute transactions, unless
90  * we are running in single-user mode (which gives an escape hatch
91  * to the DBA who somehow got past the earlier defenses).
92  *
93  * Note that this coding also appears in GetNewMultiXactId.
94  *----------
95  */
97  {
98  /*
99  * For safety's sake, we release XidGenLock while sending signals,
100  * warnings, etc. This is not so much because we care about
101  * preserving concurrency in this situation, as to avoid any
102  * possibility of deadlock while doing get_database_name(). First,
103  * copy all the shared values we'll need in this path.
104  */
108  Oid oldest_datoid = ShmemVariableCache->oldestXidDB;
109 
110  LWLockRelease(XidGenLock);
111 
112  /*
113  * To avoid swamping the postmaster with signals, we issue the autovac
114  * request only once per 64K transaction starts. This still gives
115  * plenty of chances before we get into real trouble.
116  */
117  if (IsUnderPostmaster && (xid % 65536) == 0)
119 
120  if (IsUnderPostmaster &&
121  TransactionIdFollowsOrEquals(xid, xidStopLimit))
122  {
123  char *oldest_datname = get_database_name(oldest_datoid);
124 
125  /* complain even if that DB has disappeared */
126  if (oldest_datname)
127  ereport(ERROR,
128  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
129  errmsg("database is not accepting commands to avoid wraparound data loss in database \"%s\"",
130  oldest_datname),
131  errhint("Stop the postmaster and vacuum that database in single-user mode.\n"
132  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
133  else
134  ereport(ERROR,
135  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
136  errmsg("database is not accepting commands to avoid wraparound data loss in database with OID %u",
137  oldest_datoid),
138  errhint("Stop the postmaster and vacuum that database in single-user mode.\n"
139  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
140  }
141  else if (TransactionIdFollowsOrEquals(xid, xidWarnLimit))
142  {
143  char *oldest_datname = get_database_name(oldest_datoid);
144 
145  /* complain even if that DB has disappeared */
146  if (oldest_datname)
148  (errmsg("database \"%s\" must be vacuumed within %u transactions",
149  oldest_datname,
150  xidWrapLimit - xid),
151  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
152  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
153  else
155  (errmsg("database with OID %u must be vacuumed within %u transactions",
156  oldest_datoid,
157  xidWrapLimit - xid),
158  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
159  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
160  }
161 
162  /* Re-acquire lock and start over */
163  LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
164  full_xid = ShmemVariableCache->nextXid;
165  xid = XidFromFullTransactionId(full_xid);
166  }
167 
168  /*
169  * If we are allocating the first XID of a new page of the commit log,
170  * zero out that commit-log page before returning. We must do this while
171  * holding XidGenLock, else another xact could acquire and commit a later
172  * XID before we zero the page. Fortunately, a page of the commit log
173  * holds 32K or more transactions, so we don't have to do this very often.
174  *
175  * Extend pg_subtrans and pg_commit_ts too.
176  */
177  ExtendCLOG(xid);
178  ExtendCommitTs(xid);
179  ExtendSUBTRANS(xid);
180 
181  /*
182  * Now advance the nextXid counter. This must not happen until after we
183  * have successfully completed ExtendCLOG() --- if that routine fails, we
184  * want the next incoming transaction to try it again. We cannot assign
185  * more XIDs until there is CLOG space for them.
186  */
188 
189  /*
190  * We must store the new XID into the shared ProcArray before releasing
191  * XidGenLock. This ensures that every active XID older than
192  * latestCompletedXid is present in the ProcArray, which is essential for
193  * correct OldestXmin tracking; see src/backend/access/transam/README.
194  *
195  * Note that readers of ProcGlobal->xids/PGPROC->xid should be careful to
196  * fetch the value for each proc only once, rather than assume they can
197  * read a value multiple times and get the same answer each time. Note we
198  * are assuming that TransactionId and int fetch/store are atomic.
199  *
200  * The same comments apply to the subxact xid count and overflow fields.
201  *
202  * Use of a write barrier prevents dangerous code rearrangement in this
203  * function; other backends could otherwise e.g. be examining my subxids
204  * info concurrently, and we don't want them to see an invalid
205  * intermediate state, such as an incremented nxids before the array entry
206  * is filled.
207  *
208  * Other processes that read nxids should do so before reading xids
209  * elements with a pg_read_barrier() in between, so that they can be sure
210  * not to read an uninitialized array element; see
211  * src/backend/storage/lmgr/README.barrier.
212  *
213  * If there's no room to fit a subtransaction XID into PGPROC, set the
214  * cache-overflowed flag instead. This forces readers to look in
215  * pg_subtrans to map subtransaction XIDs up to top-level XIDs. There is a
216  * race-condition window, in that the new XID will not appear as running
217  * until its parent link has been placed into pg_subtrans. However, that
218  * will happen before anyone could possibly have a reason to inquire about
219  * the status of the XID, so it seems OK. (Snapshots taken during this
220  * window *will* include the parent XID, so they will deliver the correct
221  * answer later on when someone does have a reason to inquire.)
222  */
223  if (!isSubXact)
224  {
229 
230  /* LWLockRelease acts as barrier */
231  MyProc->xid = xid;
232  ProcGlobal->xids[MyProc->pgxactoff] = xid;
233  }
234  else
235  {
237  int nxids = MyProc->subxidStatus.count;
238 
239  Assert(substat->count == MyProc->subxidStatus.count);
241 
242  if (nxids < PGPROC_MAX_CACHED_SUBXIDS)
243  {
244  MyProc->subxids.xids[nxids] = xid;
246  MyProc->subxidStatus.count = substat->count = nxids + 1;
247  }
248  else
249  MyProc->subxidStatus.overflowed = substat->overflowed = true;
250  }
251 
252  LWLockRelease(XidGenLock);
253 
254  return full_xid;
255 }
#define pg_write_barrier()
Definition: atomics.h:154
void ExtendCLOG(TransactionId newestXact)
Definition: clog.c:839
void ExtendCommitTs(TransactionId newestXact)
Definition: commit_ts.c:796
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3084
int errhint(const char *fmt,...)
Definition: elog.c:1316
int errcode(int sqlerrcode)
Definition: elog.c:858
int errmsg(const char *fmt,...)
Definition: elog.c:1069
#define WARNING
Definition: elog.h:36
#define ereport(elevel,...)
Definition: elog.h:149
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:414
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:181
@ PMSIGNAL_START_AUTOVAC_LAUNCHER
Definition: pmsignal.h:38
#define PGPROC_MAX_CACHED_SUBXIDS
Definition: proc.h:38
PGPROC * MyProc
Definition: proc.c:66
PROC_HDR * ProcGlobal
Definition: proc.c:78
int pgxactoff
Definition: proc.h:188
XidCacheStatus subxidStatus
Definition: proc.h:254
TransactionId xid
Definition: proc.h:173
struct XidCache subxids
Definition: proc.h:256
XidCacheStatus * subxidStates
Definition: proc.h:371
TransactionId * xids
Definition: proc.h:365
TransactionId xidWrapLimit
Definition: transam.h:226
TransactionId xidWarnLimit
Definition: transam.h:224
TransactionId xidStopLimit
Definition: transam.h:225
bool overflowed
Definition: proc.h:45
uint8 count
Definition: proc.h:43
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]
Definition: proc.h:50
void ExtendSUBTRANS(TransactionId newestXact)
Definition: subtrans.c:308
#define BootstrapTransactionId
Definition: transam.h:32
static void FullTransactionIdAdvance(FullTransactionId *dest)
Definition: transam.h:128
bool IsInParallelMode(void)
Definition: xact.c:1069

References Assert(), BootstrapTransactionId, XidCacheStatus::count, elog(), ereport, errcode(), errhint(), errmsg(), ERROR, ExtendCLOG(), ExtendCommitTs(), ExtendSUBTRANS(), FullTransactionIdAdvance(), FullTransactionIdFromEpochAndXid(), get_database_name(), IsBootstrapProcessingMode, IsInParallelMode(), IsUnderPostmaster, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyProc, VariableCacheData::nextXid, VariableCacheData::oldestXidDB, XidCacheStatus::overflowed, pg_write_barrier, PGPROC_MAX_CACHED_SUBXIDS, PGPROC::pgxactoff, PMSIGNAL_START_AUTOVAC_LAUNCHER, ProcGlobal, RecoveryInProgress(), SendPostmasterSignal(), ShmemVariableCache, PGPROC::subxids, PROC_HDR::subxidStates, PGPROC::subxidStatus, TransactionIdFollowsOrEquals(), WARNING, PGPROC::xid, XidFromFullTransactionId, XidCache::xids, PROC_HDR::xids, VariableCacheData::xidStopLimit, VariableCacheData::xidVacLimit, VariableCacheData::xidWarnLimit, and VariableCacheData::xidWrapLimit.

Referenced by AssignTransactionId().

◆ NormalTransactionIdOlder()

static TransactionId NormalTransactionIdOlder ( TransactionId  a,
TransactionId  b 
)
inlinestatic

Definition at line 349 of file transam.h.

350 {
354  return a;
355  return b;
356 }
#define NormalTransactionIdPrecedes(id1, id2)
Definition: transam.h:147

References a, Assert(), b, NormalTransactionIdPrecedes, and TransactionIdIsNormal.

◆ ReadNextFullTransactionId()

FullTransactionId ReadNextFullTransactionId ( void  )

◆ ReadNextTransactionId()

◆ SetTransactionIdLimit()

void SetTransactionIdLimit ( TransactionId  oldest_datfrozenxid,
Oid  oldest_datoid 
)

Definition at line 345 of file varsup.c.

346 {
347  TransactionId xidVacLimit;
348  TransactionId xidWarnLimit;
349  TransactionId xidStopLimit;
350  TransactionId xidWrapLimit;
351  TransactionId curXid;
352 
353  Assert(TransactionIdIsNormal(oldest_datfrozenxid));
354 
355  /*
356  * The place where we actually get into deep trouble is halfway around
357  * from the oldest potentially-existing XID. (This calculation is
358  * probably off by one or two counts, because the special XIDs reduce the
359  * size of the loop a little bit. But we throw in plenty of slop below,
360  * so it doesn't matter.)
361  */
362  xidWrapLimit = oldest_datfrozenxid + (MaxTransactionId >> 1);
363  if (xidWrapLimit < FirstNormalTransactionId)
364  xidWrapLimit += FirstNormalTransactionId;
365 
366  /*
367  * We'll refuse to continue assigning XIDs in interactive mode once we get
368  * within 3M transactions of data loss. This leaves lots of room for the
369  * DBA to fool around fixing things in a standalone backend, while not
370  * being significant compared to total XID space. (VACUUM requires an XID
371  * if it truncates at wal_level!=minimal. "VACUUM (ANALYZE)", which a DBA
372  * might do by reflex, assigns an XID. Hence, we had better be sure
373  * there's lots of XIDs left...) Also, at default BLCKSZ, this leaves two
374  * completely-idle segments. In the event of edge-case bugs involving
375  * page or segment arithmetic, idle segments render the bugs unreachable
376  * outside of single-user mode.
377  */
378  xidStopLimit = xidWrapLimit - 3000000;
379  if (xidStopLimit < FirstNormalTransactionId)
380  xidStopLimit -= FirstNormalTransactionId;
381 
382  /*
383  * We'll start complaining loudly when we get within 40M transactions of
384  * data loss. This is kind of arbitrary, but if you let your gas gauge
385  * get down to 2% of full, would you be looking for the next gas station?
386  * We need to be fairly liberal about this number because there are lots
387  * of scenarios where most transactions are done by automatic clients that
388  * won't pay attention to warnings. (No, we're not gonna make this
389  * configurable. If you know enough to configure it, you know enough to
390  * not get in this kind of trouble in the first place.)
391  */
392  xidWarnLimit = xidWrapLimit - 40000000;
393  if (xidWarnLimit < FirstNormalTransactionId)
394  xidWarnLimit -= FirstNormalTransactionId;
395 
396  /*
397  * We'll start trying to force autovacuums when oldest_datfrozenxid gets
398  * to be more than autovacuum_freeze_max_age transactions old.
399  *
400  * Note: guc.c ensures that autovacuum_freeze_max_age is in a sane range,
401  * so that xidVacLimit will be well before xidWarnLimit.
402  *
403  * Note: autovacuum_freeze_max_age is a PGC_POSTMASTER parameter so that
404  * we don't have to worry about dealing with on-the-fly changes in its
405  * value. It doesn't look practical to update shared state from a GUC
406  * assign hook (too many processes would try to execute the hook,
407  * resulting in race conditions as well as crashes of those not connected
408  * to shared memory). Perhaps this can be improved someday. See also
409  * SetMultiXactIdLimit.
410  */
411  xidVacLimit = oldest_datfrozenxid + autovacuum_freeze_max_age;
412  if (xidVacLimit < FirstNormalTransactionId)
413  xidVacLimit += FirstNormalTransactionId;
414 
415  /* Grab lock for just long enough to set the new limit values */
416  LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
417  ShmemVariableCache->oldestXid = oldest_datfrozenxid;
418  ShmemVariableCache->xidVacLimit = xidVacLimit;
419  ShmemVariableCache->xidWarnLimit = xidWarnLimit;
420  ShmemVariableCache->xidStopLimit = xidStopLimit;
421  ShmemVariableCache->xidWrapLimit = xidWrapLimit;
422  ShmemVariableCache->oldestXidDB = oldest_datoid;
424  LWLockRelease(XidGenLock);
425 
426  /* Log the info */
427  ereport(DEBUG1,
428  (errmsg_internal("transaction ID wrap limit is %u, limited by database with OID %u",
429  xidWrapLimit, oldest_datoid)));
430 
431  /*
432  * If past the autovacuum force point, immediately signal an autovac
433  * request. The reason for this is that autovac only processes one
434  * database per invocation. Once it's finished cleaning up the oldest
435  * database, it'll call here, and we'll signal the postmaster to start
436  * another iteration immediately if there are still any old databases.
437  */
438  if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) &&
441 
442  /* Give an immediate warning if past the wrap warn point */
443  if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit) && !InRecovery)
444  {
445  char *oldest_datname;
446 
447  /*
448  * We can be called when not inside a transaction, for example during
449  * StartupXLOG(). In such a case we cannot do database access, so we
450  * must just report the oldest DB's OID.
451  *
452  * Note: it's also possible that get_database_name fails and returns
453  * NULL, for example because the database just got dropped. We'll
454  * still warn, even though the warning might now be unnecessary.
455  */
456  if (IsTransactionState())
457  oldest_datname = get_database_name(oldest_datoid);
458  else
459  oldest_datname = NULL;
460 
461  if (oldest_datname)
463  (errmsg("database \"%s\" must be vacuumed within %u transactions",
464  oldest_datname,
465  xidWrapLimit - curXid),
466  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
467  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
468  else
470  (errmsg("database with OID %u must be vacuumed within %u transactions",
471  oldest_datoid,
472  xidWrapLimit - curXid),
473  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
474  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
475  }
476 }
int autovacuum_freeze_max_age
Definition: autovacuum.c:126
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1156
#define DEBUG1
Definition: elog.h:30
#define MaxTransactionId
Definition: transam.h:35
bool IsTransactionState(void)
Definition: xact.c:378
bool InRecovery
Definition: xlogutils.c:53

References Assert(), autovacuum_freeze_max_age, DEBUG1, ereport, errhint(), errmsg(), errmsg_internal(), FirstNormalTransactionId, get_database_name(), InRecovery, IsTransactionState(), IsUnderPostmaster, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MaxTransactionId, VariableCacheData::nextXid, VariableCacheData::oldestXid, VariableCacheData::oldestXidDB, PMSIGNAL_START_AUTOVAC_LAUNCHER, SendPostmasterSignal(), ShmemVariableCache, TransactionIdFollowsOrEquals(), TransactionIdIsNormal, WARNING, XidFromFullTransactionId, VariableCacheData::xidStopLimit, VariableCacheData::xidVacLimit, VariableCacheData::xidWarnLimit, and VariableCacheData::xidWrapLimit.

Referenced by BootStrapXLOG(), StartupXLOG(), vac_truncate_clog(), and xlog_redo().

◆ StopGeneratingPinnedObjectIds()

void StopGeneratingPinnedObjectIds ( void  )

Definition at line 625 of file varsup.c.

626 {
628 }
#define FirstUnpinnedObjectId
Definition: transam.h:196
static void SetNextObjectId(Oid nextOid)
Definition: varsup.c:596

References FirstUnpinnedObjectId, and SetNextObjectId().

Referenced by pg_stop_making_pinned_objects().

◆ TransactionIdAbortTree()

void TransactionIdAbortTree ( TransactionId  xid,
int  nxids,
TransactionId xids 
)

Definition at line 270 of file transam.c.

271 {
272  TransactionIdSetTreeStatus(xid, nxids, xids,
274 }
void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
Definition: clog.c:162
#define TRANSACTION_STATUS_ABORTED
Definition: clog.h:29
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28

References InvalidXLogRecPtr, TRANSACTION_STATUS_ABORTED, and TransactionIdSetTreeStatus().

Referenced by RecordTransactionAbort(), RecordTransactionAbortPrepared(), and xact_redo_abort().

◆ TransactionIdAsyncCommitTree()

void TransactionIdAsyncCommitTree ( TransactionId  xid,
int  nxids,
TransactionId xids,
XLogRecPtr  lsn 
)

Definition at line 252 of file transam.c.

254 {
255  TransactionIdSetTreeStatus(xid, nxids, xids,
257 }
#define TRANSACTION_STATUS_COMMITTED
Definition: clog.h:28

References TRANSACTION_STATUS_COMMITTED, and TransactionIdSetTreeStatus().

Referenced by RecordTransactionCommit(), and xact_redo_commit().

◆ TransactionIdCommitTree()

void TransactionIdCommitTree ( TransactionId  xid,
int  nxids,
TransactionId xids 
)

◆ TransactionIdDidAbort()

bool TransactionIdDidAbort ( TransactionId  transactionId)

Definition at line 188 of file transam.c.

189 {
190  XidStatus xidstatus;
191 
192  xidstatus = TransactionLogFetch(transactionId);
193 
194  /*
195  * If it's marked aborted, it's aborted.
196  */
197  if (xidstatus == TRANSACTION_STATUS_ABORTED)
198  return true;
199 
200  /*
201  * If it's marked subcommitted, we have to check the parent recursively.
202  * However, if it's older than TransactionXmin, we can't look at
203  * pg_subtrans; instead assume that the parent crashed without cleaning up
204  * its children.
205  */
206  if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
207  {
208  TransactionId parentXid;
209 
210  if (TransactionIdPrecedes(transactionId, TransactionXmin))
211  return true;
212  parentXid = SubTransGetParent(transactionId);
213  if (!TransactionIdIsValid(parentXid))
214  {
215  /* see notes in TransactionIdDidCommit */
216  elog(WARNING, "no pg_subtrans entry for subcommitted XID %u",
217  transactionId);
218  return true;
219  }
220  return TransactionIdDidAbort(parentXid);
221  }
222 
223  /*
224  * It's not aborted.
225  */
226  return false;
227 }
int XidStatus
Definition: clog.h:25
#define TRANSACTION_STATUS_SUB_COMMITTED
Definition: clog.h:30
TransactionId TransactionXmin
Definition: snapmgr.c:104
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:109
static XidStatus TransactionLogFetch(TransactionId transactionId)
Definition: transam.c:52
bool TransactionIdDidAbort(TransactionId transactionId)
Definition: transam.c:188

References elog(), SubTransGetParent(), TRANSACTION_STATUS_ABORTED, TRANSACTION_STATUS_SUB_COMMITTED, TransactionIdIsValid, TransactionIdPrecedes(), TransactionLogFetch(), TransactionXmin, and WARNING.

Referenced by DoesMultiXactIdConflict(), heap_lock_updated_tuple_rec(), heap_update(), ProcArrayApplyRecoveryInfo(), ProcessTwoPhaseBuffer(), StandbyAcquireAccessExclusiveLock(), test_lockmode_for_conflict(), and TransactionIdIsInProgress().

◆ TransactionIdDidCommit()

bool TransactionIdDidCommit ( TransactionId  transactionId)

Definition at line 126 of file transam.c.

127 {
128  XidStatus xidstatus;
129 
130  xidstatus = TransactionLogFetch(transactionId);
131 
132  /*
133  * If it's marked committed, it's committed.
134  */
135  if (xidstatus == TRANSACTION_STATUS_COMMITTED)
136  return true;
137 
138  /*
139  * If it's marked subcommitted, we have to check the parent recursively.
140  * However, if it's older than TransactionXmin, we can't look at
141  * pg_subtrans; instead assume that the parent crashed without cleaning up
142  * its children.
143  *
144  * Originally we Assert'ed that the result of SubTransGetParent was not
145  * zero. However with the introduction of prepared transactions, there can
146  * be a window just after database startup where we do not have complete
147  * knowledge in pg_subtrans of the transactions after TransactionXmin.
148  * StartupSUBTRANS() has ensured that any missing information will be
149  * zeroed. Since this case should not happen under normal conditions, it
150  * seems reasonable to emit a WARNING for it.
151  */
152  if (xidstatus == TRANSACTION_STATUS_SUB_COMMITTED)
153  {
154  TransactionId parentXid;
155 
156  if (TransactionIdPrecedes(transactionId, TransactionXmin))
157  return false;
158  parentXid = SubTransGetParent(transactionId);
159  if (!TransactionIdIsValid(parentXid))
160  {
161  elog(WARNING, "no pg_subtrans entry for subcommitted XID %u",
162  transactionId);
163  return false;
164  }
165  return TransactionIdDidCommit(parentXid);
166  }
167 
168  /*
169  * It's not committed.
170  */
171  return false;
172 }
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:126

References elog(), SubTransGetParent(), TRANSACTION_STATUS_COMMITTED, TRANSACTION_STATUS_SUB_COMMITTED, TransactionIdIsValid, TransactionIdPrecedes(), TransactionLogFetch(), TransactionXmin, and WARNING.

Referenced by asyncQueueProcessPageEntries(), check_safe_enum_use(), compute_new_xmax_infomask(), FreezeMultiXactId(), HandleConcurrentAbort(), heap_freeze_execute_prepared(), HeapTupleHeaderAdvanceConflictHorizon(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesHistoricMVCC(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuumHorizon(), MultiXactIdExpand(), pg_xact_status(), ProcArrayApplyRecoveryInfo(), ProcessTwoPhaseBuffer(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), SetupCheckXidLive(), StandbyAcquireAccessExclusiveLock(), test_lockmode_for_conflict(), UpdateLogicalMappings(), and UpdateXmaxHintBits().

◆ TransactionIdFollows()

◆ TransactionIdFollowsOrEquals()

◆ TransactionIdGetCommitLSN()

XLogRecPtr TransactionIdGetCommitLSN ( TransactionId  xid)

Definition at line 382 of file transam.c.

383 {
384  XLogRecPtr result;
385 
386  /*
387  * Currently, all uses of this function are for xids that were just
388  * reported to be committed by TransactionLogFetch, so we expect that
389  * checking TransactionLogFetch's cache will usually succeed and avoid an
390  * extra trip to shared memory.
391  */
393  return cachedCommitLSN;
394 
395  /* Special XIDs are always known committed */
396  if (!TransactionIdIsNormal(xid))
397  return InvalidXLogRecPtr;
398 
399  /*
400  * Get the transaction status.
401  */
402  (void) TransactionIdGetStatus(xid, &result);
403 
404  return result;
405 }
XidStatus TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
Definition: clog.c:638
static TransactionId cachedFetchXid
Definition: transam.c:33
static XLogRecPtr cachedCommitLSN
Definition: transam.c:35
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
uint64 XLogRecPtr
Definition: xlogdefs.h:21

References cachedCommitLSN, cachedFetchXid, InvalidXLogRecPtr, TransactionIdEquals, TransactionIdGetStatus(), and TransactionIdIsNormal.

Referenced by SetHintBits().

◆ TransactionIdLatest()

TransactionId TransactionIdLatest ( TransactionId  mainxid,
int  nxids,
const TransactionId xids 
)

Definition at line 345 of file transam.c.

347 {
348  TransactionId result;
349 
350  /*
351  * In practice it is highly likely that the xids[] array is sorted, and so
352  * we could save some cycles by just taking the last child XID, but this
353  * probably isn't so performance-critical that it's worth depending on
354  * that assumption. But just to show we're not totally stupid, scan the
355  * array back-to-front to avoid useless assignments.
356  */
357  result = mainxid;
358  while (--nxids >= 0)
359  {
360  if (TransactionIdPrecedes(result, xids[nxids]))
361  result = xids[nxids];
362  }
363  return result;
364 }

References TransactionIdPrecedes().

Referenced by FinishPreparedTransaction(), ProcArrayApplyXidAssignment(), RecordTransactionAbort(), RecordTransactionCommit(), xact_redo_abort(), and xact_redo_commit().

◆ TransactionIdOlder()

static TransactionId TransactionIdOlder ( TransactionId  a,
TransactionId  b 
)
inlinestatic

Definition at line 334 of file transam.h.

335 {
336  if (!TransactionIdIsValid(a))
337  return b;
338 
339  if (!TransactionIdIsValid(b))
340  return a;
341 
342  if (TransactionIdPrecedes(a, b))
343  return a;
344  return b;
345 }
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280

References a, b, TransactionIdIsValid, and TransactionIdPrecedes().

Referenced by ComputeXidHorizons(), and GetSnapshotData().

◆ TransactionIdPrecedes()

bool TransactionIdPrecedes ( TransactionId  id1,
TransactionId  id2 
)

Definition at line 280 of file transam.c.

281 {
282  /*
283  * If either ID is a permanent XID then we can just do unsigned
284  * comparison. If both are normal, do a modulo-2^32 comparison.
285  */
286  int32 diff;
287 
288  if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
289  return (id1 < id2);
290 
291  diff = (int32) (id1 - id2);
292  return (diff < 0);
293 }

References TransactionIdIsNormal.

Referenced by AdvanceOldestClogXid(), AdvanceOldestCommitTsXid(), bt_check_every_level(), check_exclusion_or_unique_constraint(), check_tuple_visibility(), CheckTargetForConflictsIn(), CLOGPagePrecedes(), collect_corrupt_items(), CommitTsPagePrecedes(), copy_table_data(), do_start_worker(), ExpireOldKnownAssignedTransactionIds(), ExportSnapshot(), FreezeMultiXactId(), get_relation_info(), GetOldestActiveTransactionId(), GetOldestSafeDecodingTransactionId(), GetRunningTransactionData(), heap_abort_speculative(), heap_page_is_all_visible(), heap_prepare_freeze_tuple(), heap_prune_record_prunable(), heap_tuple_should_freeze(), HeapCheckForSerializableConflictOut(), HeapTupleHeaderAdvanceConflictHorizon(), HeapTupleSatisfiesHistoricMVCC(), HeapTupleSatisfiesVacuum(), KnownAssignedXidsAdd(), KnownAssignedXidsGetAndSetXmin(), KnownAssignedXidsSearch(), lazy_scan_prune(), logical_rewrite_heap_tuple(), MaintainLatestCompletedXid(), MaintainLatestCompletedXidRecovery(), multixact_redo(), PhysicalReplicationSlotNewXmin(), PrescanPreparedTransactions(), ProcArrayApplyRecoveryInfo(), ProcArrayApplyXidAssignment(), ProcessStandbyHSFeedbackMessage(), RecordKnownAssignedTransactionIds(), relation_needs_vacanalyze(), ReorderBufferAbortOld(), ReplicationSlotsComputeRequiredXmin(), rewrite_heap_tuple(), SerialGetMinConflictCommitSeqNo(), SerialPagePrecedesLogically(), SerialSetActiveSerXmin(), SetCommitTsLimit(), SetNewSxactGlobalXmin(), SnapBuildCommitTxn(), SnapBuildProcessChange(), SnapBuildRestore(), SnapshotResetXmin(), StandbyReleaseOldLocks(), SubTransGetTopmostTransaction(), SubTransPagePrecedes(), TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdGetCommitTsData(), TransactionIdInRecentPast(), TransactionIdIsActive(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), TransactionIdLatest(), TransactionIdOlder(), TransactionTreeSetCommitTsData(), tuple_all_visible(), vac_truncate_clog(), vac_update_datfrozenxid(), vac_update_relstats(), vacuum_get_cutoffs(), vacuum_xid_failsafe_check(), vacuumRedirectAndPlaceholder(), XidInMVCCSnapshot(), XidIsConcurrent(), xidLogicalComparator(), xlog_redo(), and xmin_cmp().

◆ TransactionIdPrecedesOrEquals()

◆ TransactionIdRetreatedBy()

static TransactionId TransactionIdRetreatedBy ( TransactionId  xid,
uint32  amount 
)
inlinestatic

Definition at line 322 of file transam.h.

323 {
324  xid -= amount;
325 
326  while (xid < FirstNormalTransactionId)
327  xid--;
328 
329  return xid;
330 }

References FirstNormalTransactionId.

◆ TransactionStartedDuringRecovery()

bool TransactionStartedDuringRecovery ( void  )

Definition at line 1027 of file xact.c.

1028 {
1030 }
bool startedInRecovery
Definition: xact.c:207
static TransactionState CurrentTransactionState
Definition: xact.c:254

References CurrentTransactionState, and TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

Variable Documentation

◆ ShmemVariableCache