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 FullTransactionIdPrecedes(a, b)   ((a).value < (b).value)
 
#define FullTransactionIdIsValid(x)   TransactionIdIsValid(XidFromFullTransactionId(x))
 
#define InvalidFullTransactionId   FullTransactionIdFromEpochAndXid(0, InvalidTransactionId)
 
#define TransactionIdAdvance(dest)
 
#define TransactionIdRetreat(dest)
 
#define NormalTransactionIdPrecedes(id1, id2)
 
#define NormalTransactionIdFollows(id1, id2)
 
#define FirstGenbkiObjectId   10000
 
#define FirstBootstrapObjectId   12000
 
#define FirstNormalObjectId   16384
 

Typedefs

typedef struct FullTransactionId FullTransactionId
 
typedef struct VariableCacheData VariableCacheData
 
typedef VariableCacheDataVariableCache
 

Functions

static FullTransactionId FullTransactionIdFromEpochAndXid (uint32 epoch, TransactionId xid)
 
static void FullTransactionIdAdvance (FullTransactionId *dest)
 
bool TransactionStartedDuringRecovery (void)
 
bool TransactionIdDidCommit (TransactionId transactionId)
 
bool TransactionIdDidAbort (TransactionId transactionId)
 
bool TransactionIdIsKnownCompleted (TransactionId transactionId)
 
void TransactionIdAbort (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)
 
static TransactionId ReadNewTransactionId (void)
 

Variables

PGDLLIMPORT VariableCache ShmemVariableCache
 

Macro Definition Documentation

◆ BootstrapTransactionId

#define BootstrapTransactionId   ((TransactionId) 1)

Definition at line 32 of file transam.h.

Referenced by GetNewTransactionId(), and TransactionLogFetch().

◆ EpochFromFullTransactionId

◆ FirstBootstrapObjectId

◆ FirstGenbkiObjectId

#define FirstGenbkiObjectId   10000

Definition at line 139 of file transam.h.

Referenced by is_builtin().

◆ FirstNormalObjectId

◆ FirstNormalTransactionId

◆ FrozenTransactionId

#define FrozenTransactionId   ((TransactionId) 2)

◆ FullTransactionIdIsValid

◆ FullTransactionIdPrecedes

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

Definition at line 50 of file transam.h.

Referenced by xlog_redo().

◆ InvalidFullTransactionId

◆ InvalidTransactionId

#define InvalidTransactionId   ((TransactionId) 0)

Definition at line 31 of file transam.h.

Referenced by _bt_cachemetadata(), _bt_check_unique(), _bt_delitems_delete(), _bt_getroot(), _bt_initmetapage(), _bt_upgrademetapage(), AbortTransaction(), ActivateCommitTs(), AdvanceOldestCommitTsXid(), AlterSequence(), apply_returning_filter(), asyncQueueAddEntries(), asyncQueueReadAllNotifications(), BackendIdGetTransactionIds(), BackendXidGetPid(), BootStrapXLOG(), btvacuumscan(), BuildCachedPlan(), CheckForSerializableConflictOut(), collect_corrupt_items(), CommitTransaction(), CommitTsShmemInit(), compute_new_xmax_infomask(), CreateCheckPoint(), CreateDecodingContext(), CreateInitDecodingContext(), CreateSharedProcArray(), DeactivateCommitTs(), DefineIndex(), DefineQueryRewrite(), do_analyze_rel(), ExpireAllKnownAssignedTransactionIds(), fill_seq_with_data(), FreezeMultiXactId(), GetOldestXmin(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetStableLatestTransactionId(), gistprunepage(), GuessControlValues(), heap_abort_speculative(), heap_compute_xid_horizon_for_tuples(), heap_create(), heap_execute_freeze_tuple(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_lock_updated_tuple_rec(), heap_page_is_all_visible(), heap_page_prune(), heap_page_prune_opt(), heap_prepare_freeze_tuple(), heap_prune_chain(), heap_update(), heap_vacuum_rel(), heap_xlog_delete(), heapam_index_build_range_scan(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuum(), ImportSnapshot(), index_compute_xid_horizon_for_tuples(), index_create(), index_drop(), index_set_state_flags(), InitAuxiliaryProcess(), InitPredicateLocks(), InitProcess(), KnownAssignedXidsGet(), KnownAssignedXidsGetOldestXmin(), lazy_cleanup_index(), lazy_scan_heap(), logical_begin_heap_rewrite(), LogicalConfirmReceivedLocation(), main(), make_tuple_from_result_row(), MarkAsPreparingGuts(), message_cb_wrapper(), MinimumActiveBackends(), MultiXactIdGetUpdateXid(), OldSerXidInit(), OldSerXidSetActiveSerXmin(), pg_get_replication_slots(), PhysicalReplicationSlotNewXmin(), predicatelock_twophase_recover(), ProcArrayApplyRecoveryInfo(), ProcArrayApplyXidAssignment(), ProcArrayClearTransaction(), ProcArrayEndTransaction(), ProcArrayEndTransactionInternal(), ProcessStandbyHSFeedbackMessage(), read_seq_tuple(), RecordTransactionAbort(), RecordTransactionCommit(), recoveryStopsAfter(), recoveryStopsBefore(), RegisterPredicateLockingXid(), RelationSetNewRelfilenode(), ReleaseOneSerializableXact(), RemoveProcFromArray(), ReorderBufferAllocate(), ReorderBufferCommit(), ReorderBufferGetOldestXmin(), ReorderBufferProcessXid(), ReorderBufferQueueMessage(), ReorderBufferReturnTXN(), ReplicationSlotCreate(), ReplicationSlotRelease(), ReplicationSlotsComputeRequiredXmin(), ResetSequence(), ResolveRecoveryConflictWithTablespace(), RestoreSlotFromDisk(), set_status_by_pages(), SetCommitTsLimit(), SetNewSxactGlobalXmin(), SimpleLruFlush(), SlruInternalWritePage(), SnapBuildFindSnapshot(), SnapBuildProcessRunningXacts(), SnapMgrInit(), SnapshotResetXmin(), spgFormDeadTuple(), SubTransGetParent(), SubTransSetParent(), swap_relation_files(), TwoPhaseGetGXact(), txid_current_if_assigned(), UpdateXmaxHintBits(), vacuumRedirectAndPlaceholder(), WriteEmptyXLOG(), and XLogWalRcvSendHSFeedback().

◆ MaxTransactionId

#define MaxTransactionId   ((TransactionId) 0xFFFFFFFF)

Definition at line 35 of file transam.h.

Referenced by SetTransactionIdLimit(), and StartupSUBTRANS().

◆ NormalTransactionIdFollows

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

Definition at line 103 of file transam.h.

Referenced by SnapBuildCommitTxn(), and TransactionIdLimitedForOldSnapshots().

◆ NormalTransactionIdPrecedes

#define NormalTransactionIdPrecedes (   id1,
  id2 
)
Value:
(int32) ((id1) - (id2)) < 0)
#define AssertMacro(condition)
Definition: c.h:733
signed int int32
Definition: c.h:346
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

Definition at line 98 of file transam.h.

Referenced by GetOldestXmin(), GetSnapshotData(), SnapBuildFindSnapshot(), SnapBuildInitialSnapshot(), and SnapBuildPurgeCommittedTxn().

◆ StoreInvalidTransactionId

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

Definition at line 45 of file transam.h.

◆ TransactionIdAdvance

◆ TransactionIdEquals

◆ TransactionIdIsNormal

◆ TransactionIdIsValid

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

Definition at line 41 of file transam.h.

Referenced by _bt_check_unique(), _bt_doinsert(), _bt_vacuum_needs_cleanup(), AssignTransactionId(), bt_check_every_level(), btvacuumpage(), check_exclusion_or_unique_constraint(), CheckCachedPlan(), CheckForSerializableConflictOut(), CheckPointPredicate(), CheckTableForSerializableConflictIn(), ClearOldPredicateLocks(), ConditionalXactLockTableWait(), copy_table_data(), DecodeHeapOp(), DecodeXactOp(), DropAllPredicateLocksFromTable(), ExportSnapshot(), ForceTransactionIdLimitUpdate(), FreezeMultiXactId(), GetConflictingVirtualXIDs(), GetCurrentVirtualXIDs(), GetMultiXactIdMembers(), GetOldestSafeDecodingTransactionId(), GetOldestXmin(), GetRunningTransactionData(), GetRunningTransactionLocks(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetStableLatestTransactionId(), heap_abort_speculative(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_lock_updated_tuple_rec(), heap_page_prune_opt(), heap_prepare_freeze_tuple(), heap_prune_chain(), heap_prune_record_prunable(), heap_update(), heap_xlog_clean(), heapam_index_build_range_scan(), heapam_tuple_lock(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuum(), index_getnext_tid(), KnownAssignedXidExists(), KnownAssignedXidsGetAndSetXmin(), KnownAssignedXidsRemove(), KnownAssignedXidsRemovePreceding(), KnownAssignedXidsRemoveTree(), LogicalConfirmReceivedLocation(), MultiXactIdCreate(), MultiXactIdExpand(), OldSerXidAdd(), OldSerXidGetMinConflictCommitSeqNo(), OldSerXidSetActiveSerXmin(), pg_stat_get_activity(), predicatelock_twophase_recover(), PredicateLockPageSplit(), PredicateLockTuple(), ProcArrayApplyRecoveryInfo(), ProcArrayEndTransaction(), ProcArrayGroupClearXid(), ProcArrayRemove(), RecordKnownAssignedTransactionIds(), RecordTransactionAbort(), RecordTransactionCommit(), RegisterPredicateLockingXid(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), ReorderBufferTXNByXid(), ReplicationSlotRelease(), ReplicationSlotsComputeRequiredXmin(), ResolveRecoveryConflictWithSnapshot(), SetHintBits(), SetNewSxactGlobalXmin(), SnapBuildAddCommittedTxn(), SnapBuildCommitTxn(), SnapBuildDistributeNewCatalogSnapshot(), SnapBuildInitialSnapshot(), SpeculativeInsertionWait(), spgFormDeadTuple(), spgRedoVacuumRedirect(), StandbyAcquireAccessExclusiveLock(), StandbyReleaseLocks(), StandbyReleaseOldLocks(), StandbyTransactionIdIsPrepared(), StartupXLOG(), SubTransGetTopmostTransaction(), SubTransSetParent(), SummarizeOldestCommittedSxact(), swap_relation_files(), TransactionGroupUpdateXidStatus(), TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdGetCommitTsData(), TransactionIdInRecentPast(), TransactionIdIsActive(), TransactionIdIsInProgress(), TransactionIdSetPageStatusInternal(), txid_status(), vac_update_datfrozenxid(), vacuum_log_cleanup_info(), vacuumRedirectAndPlaceholder(), xact_desc_abort(), xact_desc_commit(), xact_redo_abort(), xact_redo_commit(), XactLockTableWait(), XactLogAbortRecord(), XactLogCommitRecord(), XidCacheRemoveRunningXids(), XidIsConcurrent(), and XLogWalRcvSendHSFeedback().

◆ TransactionIdRetreat

#define TransactionIdRetreat (   dest)

◆ 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.

Referenced by StartupXLOG(), and TransactionIdInRecentPast().

◆ XidFromFullTransactionId

Typedef Documentation

◆ FullTransactionId

◆ VariableCache

Definition at line 192 of file transam.h.

◆ VariableCacheData

Function Documentation

◆ AdvanceNextFullTransactionIdPastXid()

void AdvanceNextFullTransactionIdPastXid ( TransactionId  xid)

Definition at line 262 of file varsup.c.

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

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

263 {
264  FullTransactionId newNextFullXid;
265  TransactionId next_xid;
266  uint32 epoch;
267 
268  /*
269  * It is safe to read nextFullXid without a lock, because this is only
270  * called from the startup process or single-process mode, meaning that no
271  * other process can modify it.
272  */
274 
275  /* Fast return if this isn't an xid high enough to move the needle. */
277  if (!TransactionIdFollowsOrEquals(xid, next_xid))
278  return;
279 
280  /*
281  * Compute the FullTransactionId that comes after the given xid. To do
282  * this, we preserve the existing epoch, but detect when we've wrapped
283  * into a new epoch. This is necessary because WAL records and 2PC state
284  * currently contain 32 bit xids. The wrap logic is safe in those cases
285  * because the span of active xids cannot exceed one epoch at any given
286  * point in the WAL stream.
287  */
290  if (unlikely(xid < next_xid))
291  ++epoch;
292  newNextFullXid = FullTransactionIdFromEpochAndXid(epoch, xid);
293 
294  /*
295  * We still need to take a lock to modify the value when there are
296  * concurrent readers.
297  */
298  LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
299  ShmemVariableCache->nextFullXid = newNextFullXid;
300  LWLockRelease(XidGenLock);
301 }
#define TransactionIdAdvance(dest)
Definition: transam.h:75
#define AmStartupProcess()
Definition: miscadmin.h:412
uint32 TransactionId
Definition: c.h:507
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
FullTransactionId nextFullXid
Definition: transam.h:164
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
bool IsUnderPostmaster
Definition: globals.c:109
VariableCache ShmemVariableCache
Definition: varsup.c:34
unsigned int uint32
Definition: c.h:358
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
#define Assert(condition)
Definition: c.h:732
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:65
static const unsigned __int64 epoch
Definition: gettimeofday.c:34
#define unlikely(x)
Definition: c.h:208

◆ AdvanceOldestClogXid()

void AdvanceOldestClogXid ( TransactionId  oldest_datfrozenxid)

Definition at line 313 of file varsup.c.

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

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

314 {
315  LWLockAcquire(CLogTruncationLock, LW_EXCLUSIVE);
317  oldest_datfrozenxid))
318  {
319  ShmemVariableCache->oldestClogXid = oldest_datfrozenxid;
320  }
321  LWLockRelease(CLogTruncationLock);
322 }
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
TransactionId oldestClogXid
Definition: transam.h:188
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122

◆ ForceTransactionIdLimitUpdate()

bool ForceTransactionIdLimitUpdate ( void  )

Definition at line 471 of file varsup.c.

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

Referenced by vac_update_datfrozenxid().

472 {
473  TransactionId nextXid;
474  TransactionId xidVacLimit;
475  TransactionId oldestXid;
476  Oid oldestXidDB;
477 
478  /* Locking is probably not really necessary, but let's be careful */
479  LWLockAcquire(XidGenLock, LW_SHARED);
481  xidVacLimit = ShmemVariableCache->xidVacLimit;
482  oldestXid = ShmemVariableCache->oldestXid;
483  oldestXidDB = ShmemVariableCache->oldestXidDB;
484  LWLockRelease(XidGenLock);
485 
486  if (!TransactionIdIsNormal(oldestXid))
487  return true; /* shouldn't happen, but just in case */
488  if (!TransactionIdIsValid(xidVacLimit))
489  return true; /* this shouldn't happen anymore either */
490  if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit))
491  return true; /* past VacLimit, don't delay updating */
493  return true; /* could happen, per comments above */
494  return false;
495 }
uint32 TransactionId
Definition: c.h:507
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId oldestXid
Definition: transam.h:166
FullTransactionId nextFullXid
Definition: transam.h:164
unsigned int Oid
Definition: postgres_ext.h:31
TransactionId xidVacLimit
Definition: transam.h:167
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ FullTransactionIdAdvance()

static void FullTransactionIdAdvance ( FullTransactionId dest)
inlinestatic

Definition at line 84 of file transam.h.

References FirstNormalTransactionId, FullTransactionId::value, and XidFromFullTransactionId.

Referenced by GetNewTransactionId().

85 {
86  dest->value++;
88  dest->value++;
89 }
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define FirstNormalTransactionId
Definition: transam.h:34
uint64 value
Definition: transam.h:61

◆ FullTransactionIdFromEpochAndXid()

static FullTransactionId FullTransactionIdFromEpochAndXid ( uint32  epoch,
TransactionId  xid 
)
inlinestatic

Definition at line 65 of file transam.h.

References FullTransactionId::value.

Referenced by AdvanceNextFullTransactionIdPastXid(), BootStrapXLOG(), GetNewTransactionId(), GuessControlValues(), and main().

66 {
67  FullTransactionId result;
68 
69  result.value = ((uint64) epoch) << 32 | xid;
70 
71  return result;
72 }
uint64 value
Definition: transam.h:61
static const unsigned __int64 epoch
Definition: gettimeofday.c:34

◆ GetNewObjectId()

Oid GetNewObjectId ( void  )

Definition at line 509 of file varsup.c.

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

Referenced by GetNewOidWithIndex(), and GetNewRelFileNode().

510 {
511  Oid result;
512 
513  /* safety check, we should never get this far in a HS standby */
514  if (RecoveryInProgress())
515  elog(ERROR, "cannot assign OIDs during recovery");
516 
517  LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
518 
519  /*
520  * Check for wraparound of the OID counter. We *must* not return 0
521  * (InvalidOid), and in normal operation we mustn't return anything below
522  * FirstNormalObjectId since that range is reserved for initdb (see
523  * IsCatalogClass()). Note we are relying on unsigned comparison.
524  *
525  * During initdb, we start the OID generator at FirstBootstrapObjectId, so
526  * we only wrap if before that point when in bootstrap or standalone mode.
527  * The first time through this routine after normal postmaster start, the
528  * counter will be forced up to FirstNormalObjectId. This mechanism
529  * leaves the OIDs between FirstBootstrapObjectId and FirstNormalObjectId
530  * available for automatic assignment during initdb, while ensuring they
531  * will never conflict with user-assigned OIDs.
532  */
534  {
536  {
537  /* wraparound, or first post-initdb assignment, in normal mode */
540  }
541  else
542  {
543  /* we may be bootstrapping, so don't enforce the full range */
545  {
546  /* wraparound in standalone mode (unlikely but possible) */
549  }
550  }
551  }
552 
553  /* If we run out of logged for use oids then we must log more */
554  if (ShmemVariableCache->oidCount == 0)
555  {
558  }
559 
560  result = ShmemVariableCache->nextOid;
561 
564 
565  LWLockRelease(OidGenLock);
566 
567  return result;
568 }
bool IsPostmasterEnvironment
Definition: globals.c:108
uint32 oidCount
Definition: transam.h:159
#define VAR_OID_PREFETCH
Definition: varsup.c:31
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:7884
#define FirstNormalObjectId
Definition: transam.h:141
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#define ERROR
Definition: elog.h:43
void XLogPutNextOid(Oid nextOid)
Definition: xlog.c:9326
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define FirstBootstrapObjectId
Definition: transam.h:140
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
#define elog(elevel,...)
Definition: elog.h:226

◆ GetNewTransactionId()

FullTransactionId GetNewTransactionId ( bool  isSubXact)

Definition at line 49 of file varsup.c.

References Assert, BootstrapTransactionId, elog, ereport, errcode(), errhint(), errmsg(), ERROR, ExtendCLOG(), ExtendCommitTs(), ExtendSUBTRANS(), FullTransactionIdAdvance(), FullTransactionIdFromEpochAndXid(), get_database_name(), IsBootstrapProcessingMode, IsInParallelMode(), IsUnderPostmaster, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyPgXact, MyProc, VariableCacheData::nextFullXid, PGXACT::nxids, VariableCacheData::oldestXidDB, PGXACT::overflowed, pg_write_barrier, PGPROC_MAX_CACHED_SUBXIDS, PMSIGNAL_START_AUTOVAC_LAUNCHER, RecoveryInProgress(), SendPostmasterSignal(), PGPROC::subxids, TransactionIdFollowsOrEquals(), WARNING, PGXACT::xid, XidFromFullTransactionId, XidCache::xids, VariableCacheData::xidStopLimit, VariableCacheData::xidVacLimit, VariableCacheData::xidWarnLimit, and VariableCacheData::xidWrapLimit.

Referenced by AssignTransactionId().

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

◆ ReadNewTransactionId()

static TransactionId ReadNewTransactionId ( void  )
inlinestatic

◆ ReadNextFullTransactionId()

FullTransactionId ReadNextFullTransactionId ( void  )

Definition at line 246 of file varsup.c.

References LW_SHARED, LWLockAcquire(), LWLockRelease(), and VariableCacheData::nextFullXid.

Referenced by load_xid_epoch(), ReadNewTransactionId(), TransactionIdInRecentPast(), and XLogWalRcvSendHSFeedback().

247 {
248  FullTransactionId fullXid;
249 
250  LWLockAcquire(XidGenLock, LW_SHARED);
251  fullXid = ShmemVariableCache->nextFullXid;
252  LWLockRelease(XidGenLock);
253 
254  return fullXid;
255 }
FullTransactionId nextFullXid
Definition: transam.h:164
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122

◆ SetTransactionIdLimit()

void SetTransactionIdLimit ( TransactionId  oldest_datfrozenxid,
Oid  oldest_datoid 
)

Definition at line 330 of file varsup.c.

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

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

331 {
332  TransactionId xidVacLimit;
333  TransactionId xidWarnLimit;
334  TransactionId xidStopLimit;
335  TransactionId xidWrapLimit;
336  TransactionId curXid;
337 
338  Assert(TransactionIdIsNormal(oldest_datfrozenxid));
339 
340  /*
341  * The place where we actually get into deep trouble is halfway around
342  * from the oldest potentially-existing XID. (This calculation is
343  * probably off by one or two counts, because the special XIDs reduce the
344  * size of the loop a little bit. But we throw in plenty of slop below,
345  * so it doesn't matter.)
346  */
347  xidWrapLimit = oldest_datfrozenxid + (MaxTransactionId >> 1);
348  if (xidWrapLimit < FirstNormalTransactionId)
349  xidWrapLimit += FirstNormalTransactionId;
350 
351  /*
352  * We'll refuse to continue assigning XIDs in interactive mode once we get
353  * within 1M transactions of data loss. This leaves lots of room for the
354  * DBA to fool around fixing things in a standalone backend, while not
355  * being significant compared to total XID space. (Note that since
356  * vacuuming requires one transaction per table cleaned, we had better be
357  * sure there's lots of XIDs left...)
358  */
359  xidStopLimit = xidWrapLimit - 1000000;
360  if (xidStopLimit < FirstNormalTransactionId)
361  xidStopLimit -= FirstNormalTransactionId;
362 
363  /*
364  * We'll start complaining loudly when we get within 10M transactions of
365  * the stop point. This is kind of arbitrary, but if you let your gas
366  * gauge get down to 1% of full, would you be looking for the next gas
367  * station? We need to be fairly liberal about this number because there
368  * are lots of scenarios where most transactions are done by automatic
369  * clients that won't pay attention to warnings. (No, we're not gonna make
370  * this configurable. If you know enough to configure it, you know enough
371  * to not get in this kind of trouble in the first place.)
372  */
373  xidWarnLimit = xidStopLimit - 10000000;
374  if (xidWarnLimit < FirstNormalTransactionId)
375  xidWarnLimit -= FirstNormalTransactionId;
376 
377  /*
378  * We'll start trying to force autovacuums when oldest_datfrozenxid gets
379  * to be more than autovacuum_freeze_max_age transactions old.
380  *
381  * Note: guc.c ensures that autovacuum_freeze_max_age is in a sane range,
382  * so that xidVacLimit will be well before xidWarnLimit.
383  *
384  * Note: autovacuum_freeze_max_age is a PGC_POSTMASTER parameter so that
385  * we don't have to worry about dealing with on-the-fly changes in its
386  * value. It doesn't look practical to update shared state from a GUC
387  * assign hook (too many processes would try to execute the hook,
388  * resulting in race conditions as well as crashes of those not connected
389  * to shared memory). Perhaps this can be improved someday. See also
390  * SetMultiXactIdLimit.
391  */
392  xidVacLimit = oldest_datfrozenxid + autovacuum_freeze_max_age;
393  if (xidVacLimit < FirstNormalTransactionId)
394  xidVacLimit += FirstNormalTransactionId;
395 
396  /* Grab lock for just long enough to set the new limit values */
397  LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
398  ShmemVariableCache->oldestXid = oldest_datfrozenxid;
399  ShmemVariableCache->xidVacLimit = xidVacLimit;
400  ShmemVariableCache->xidWarnLimit = xidWarnLimit;
401  ShmemVariableCache->xidStopLimit = xidStopLimit;
402  ShmemVariableCache->xidWrapLimit = xidWrapLimit;
403  ShmemVariableCache->oldestXidDB = oldest_datoid;
405  LWLockRelease(XidGenLock);
406 
407  /* Log the info */
408  ereport(DEBUG1,
409  (errmsg("transaction ID wrap limit is %u, limited by database with OID %u",
410  xidWrapLimit, oldest_datoid)));
411 
412  /*
413  * If past the autovacuum force point, immediately signal an autovac
414  * request. The reason for this is that autovac only processes one
415  * database per invocation. Once it's finished cleaning up the oldest
416  * database, it'll call here, and we'll signal the postmaster to start
417  * another iteration immediately if there are still any old databases.
418  */
419  if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) &&
422 
423  /* Give an immediate warning if past the wrap warn point */
424  if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit) && !InRecovery)
425  {
426  char *oldest_datname;
427 
428  /*
429  * We can be called when not inside a transaction, for example during
430  * StartupXLOG(). In such a case we cannot do database access, so we
431  * must just report the oldest DB's OID.
432  *
433  * Note: it's also possible that get_database_name fails and returns
434  * NULL, for example because the database just got dropped. We'll
435  * still warn, even though the warning might now be unnecessary.
436  */
437  if (IsTransactionState())
438  oldest_datname = get_database_name(oldest_datoid);
439  else
440  oldest_datname = NULL;
441 
442  if (oldest_datname)
444  (errmsg("database \"%s\" must be vacuumed within %u transactions",
445  oldest_datname,
446  xidWrapLimit - curXid),
447  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
448  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
449  else
451  (errmsg("database with OID %u must be vacuumed within %u transactions",
452  oldest_datoid,
453  xidWrapLimit - curXid),
454  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
455  "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
456  }
457 }
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:974
uint32 TransactionId
Definition: c.h:507
bool InRecovery
Definition: xlog.c:200
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId oldestXid
Definition: transam.h:166
FullTransactionId nextFullXid
Definition: transam.h:164
TransactionId xidVacLimit
Definition: transam.h:167
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1726
#define FirstNormalTransactionId
Definition: transam.h:34
int autovacuum_freeze_max_age
Definition: autovacuum.c:121
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2059
TransactionId xidStopLimit
Definition: transam.h:169
bool IsUnderPostmaster
Definition: globals.c:109
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define ereport(elevel, rest)
Definition: elog.h:141
#define WARNING
Definition: elog.h:40
#define MaxTransactionId
Definition: transam.h:35
#define Assert(condition)
Definition: c.h:732
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1122
bool IsTransactionState(void)
Definition: xact.c:357
TransactionId xidWarnLimit
Definition: transam.h:168
int errmsg(const char *fmt,...)
Definition: elog.c:784
TransactionId xidWrapLimit
Definition: transam.h:170
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:146
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ TransactionIdAbort()

void TransactionIdAbort ( TransactionId  transactionId)

◆ TransactionIdAbortTree()

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

Definition at line 290 of file transam.c.

References InvalidXLogRecPtr, TRANSACTION_STATUS_ABORTED, and TransactionIdSetTreeStatus().

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

291 {
292  TransactionIdSetTreeStatus(xid, nxids, xids,
294 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
Definition: clog.c:163
#define TRANSACTION_STATUS_ABORTED
Definition: clog.h:28

◆ TransactionIdAsyncCommitTree()

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

Definition at line 272 of file transam.c.

References TRANSACTION_STATUS_COMMITTED, and TransactionIdSetTreeStatus().

Referenced by RecordTransactionCommit(), and xact_redo_commit().

274 {
275  TransactionIdSetTreeStatus(xid, nxids, xids,
277 }
#define TRANSACTION_STATUS_COMMITTED
Definition: clog.h:27
void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
Definition: clog.c:163

◆ TransactionIdCommitTree()

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

Definition at line 260 of file transam.c.

References InvalidXLogRecPtr, TRANSACTION_STATUS_COMMITTED, and TransactionIdSetTreeStatus().

Referenced by RecordTransactionCommit(), RecordTransactionCommitPrepared(), and xact_redo_commit().

261 {
262  TransactionIdSetTreeStatus(xid, nxids, xids,
265 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define TRANSACTION_STATUS_COMMITTED
Definition: clog.h:27
void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
Definition: clog.c:163

◆ TransactionIdDidAbort()

bool TransactionIdDidAbort ( TransactionId  transactionId)

Definition at line 181 of file transam.c.

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

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

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

◆ TransactionIdDidCommit()

bool TransactionIdDidCommit ( TransactionId  transactionId)

Definition at line 125 of file transam.c.

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

Referenced by asyncQueueProcessPageEntries(), check_safe_enum_use(), compute_new_xmax_infomask(), FreezeMultiXactId(), heap_prepare_freeze_tuple(), HeapTupleHeaderAdvanceLatestRemovedXid(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesHistoricMVCC(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuum(), MultiXactIdExpand(), ProcArrayApplyRecoveryInfo(), ProcessTwoPhaseBuffer(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), StandbyAcquireAccessExclusiveLock(), test_lockmode_for_conflict(), TransactionIdDidCommit(), txid_status(), UpdateLogicalMappings(), and UpdateXmaxHintBits().

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

◆ TransactionIdFollows()

◆ TransactionIdFollowsOrEquals()

◆ TransactionIdGetCommitLSN()

XLogRecPtr TransactionIdGetCommitLSN ( TransactionId  xid)

Definition at line 402 of file transam.c.

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

Referenced by SetHintBits().

403 {
404  XLogRecPtr result;
405 
406  /*
407  * Currently, all uses of this function are for xids that were just
408  * reported to be committed by TransactionLogFetch, so we expect that
409  * checking TransactionLogFetch's cache will usually succeed and avoid an
410  * extra trip to shared memory.
411  */
413  return cachedCommitLSN;
414 
415  /* Special XIDs are always known committed */
416  if (!TransactionIdIsNormal(xid))
417  return InvalidXLogRecPtr;
418 
419  /*
420  * Get the transaction status.
421  */
422  (void) TransactionIdGetStatus(xid, &result);
423 
424  return result;
425 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
static XLogRecPtr cachedCommitLSN
Definition: transam.c:35
uint64 XLogRecPtr
Definition: xlogdefs.h:21
XidStatus TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
Definition: clog.c:641
static TransactionId cachedFetchXid
Definition: transam.c:33
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ TransactionIdIsKnownCompleted()

bool TransactionIdIsKnownCompleted ( TransactionId  transactionId)

Definition at line 238 of file transam.c.

References cachedFetchXid, and TransactionIdEquals.

Referenced by TransactionIdIsInProgress().

239 {
240  if (TransactionIdEquals(transactionId, cachedFetchXid))
241  {
242  /* If it's in the cache at all, it must be completed. */
243  return true;
244  }
245 
246  return false;
247 }
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
static TransactionId cachedFetchXid
Definition: transam.c:33

◆ TransactionIdLatest()

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

Definition at line 365 of file transam.c.

References TransactionIdPrecedes().

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

367 {
368  TransactionId result;
369 
370  /*
371  * In practice it is highly likely that the xids[] array is sorted, and so
372  * we could save some cycles by just taking the last child XID, but this
373  * probably isn't so performance-critical that it's worth depending on
374  * that assumption. But just to show we're not totally stupid, scan the
375  * array back-to-front to avoid useless assignments.
376  */
377  result = mainxid;
378  while (--nxids >= 0)
379  {
380  if (TransactionIdPrecedes(result, xids[nxids]))
381  result = xids[nxids];
382  }
383  return result;
384 }
uint32 TransactionId
Definition: c.h:507
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300

◆ TransactionIdPrecedes()

bool TransactionIdPrecedes ( TransactionId  id1,
TransactionId  id2 
)

Definition at line 300 of file transam.c.

References TransactionIdIsNormal.

Referenced by _bt_page_recyclable(), _bt_vacuum_needs_cleanup(), AdvanceOldestClogXid(), AdvanceOldestCommitTsXid(), bt_check_every_level(), btvacuumpage(), check_exclusion_or_unique_constraint(), CheckForSerializableConflictOut(), CheckTargetForConflictsIn(), CLOGPagePrecedes(), collect_corrupt_items(), CommitTsPagePrecedes(), convert_xid(), copy_table_data(), do_start_worker(), ExpireTreeKnownAssignedTransactionIds(), ExportSnapshot(), FreezeMultiXactId(), get_relation_info(), GetOldestActiveTransactionId(), GetOldestSafeDecodingTransactionId(), GetOldestXmin(), GetRunningTransactionData(), GetSnapshotData(), gistPageRecyclable(), heap_page_is_all_visible(), heap_prepare_freeze_tuple(), heap_prune_record_prunable(), heap_tuple_needs_freeze(), HeapTupleHeaderAdvanceLatestRemovedXid(), HeapTupleIsSurelyDead(), HeapTupleSatisfiesHistoricMVCC(), HeapTupleSatisfiesVacuum(), KnownAssignedXidsAdd(), KnownAssignedXidsGetAndSetXmin(), KnownAssignedXidsSearch(), lazy_scan_heap(), logical_rewrite_heap_tuple(), MaintainOldSnapshotTimeMapping(), multixact_redo(), OldSerXidGetMinConflictCommitSeqNo(), OldSerXidSetActiveSerXmin(), PhysicalReplicationSlotNewXmin(), PrescanPreparedTransactions(), ProcArrayApplyRecoveryInfo(), ProcArrayApplyXidAssignment(), ProcArrayEndTransactionInternal(), ProcArrayRemove(), ProcessStandbyHSFeedbackMessage(), RecordKnownAssignedTransactionIds(), relation_needs_vacanalyze(), ReorderBufferAbortOld(), ReplicationSlotsComputeRequiredXmin(), rewrite_heap_tuple(), SetCommitTsLimit(), SetNewSxactGlobalXmin(), SnapBuildCommitTxn(), SnapBuildProcessChange(), SnapBuildRestore(), SnapshotResetXmin(), StandbyReleaseOldLocks(), SubTransGetTopmostTransaction(), SubTransPagePrecedes(), TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdGetCommitTsData(), TransactionIdInRecentPast(), TransactionIdIsActive(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), TransactionIdLatest(), TransactionIdLimitedForOldSnapshots(), TransactionTreeSetCommitTsData(), tuple_all_visible(), txid_status(), vac_truncate_clog(), vac_update_datfrozenxid(), vac_update_relstats(), vacuum_set_xid_limits(), vacuumRedirectAndPlaceholder(), XidCacheRemoveRunningXids(), XidInMVCCSnapshot(), XidIsConcurrent(), xlog_redo(), XLogWalRcvSendHSFeedback(), and xmin_cmp().

301 {
302  /*
303  * If either ID is a permanent XID then we can just do unsigned
304  * comparison. If both are normal, do a modulo-2^32 comparison.
305  */
306  int32 diff;
307 
308  if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
309  return (id1 < id2);
310 
311  diff = (int32) (id1 - id2);
312  return (diff < 0);
313 }
signed int int32
Definition: c.h:346
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ TransactionIdPrecedesOrEquals()

bool TransactionIdPrecedesOrEquals ( TransactionId  id1,
TransactionId  id2 
)

Definition at line 319 of file transam.c.

References TransactionIdIsNormal.

Referenced by ClearOldPredicateLocks(), GetCurrentVirtualXIDs(), GetSnapshotData(), heap_vacuum_rel(), KnownAssignedXidsAdd(), LogicalIncreaseXminForSlot(), ProcArrayInstallImportedXmin(), ProcArrayInstallRestoredXmin(), SnapBuildFindSnapshot(), SnapBuildInitialSnapshot(), TransactionIdInRecentPast(), and TransactionIdIsInProgress().

320 {
321  int32 diff;
322 
323  if (!TransactionIdIsNormal(id1) || !TransactionIdIsNormal(id2))
324  return (id1 <= id2);
325 
326  diff = (int32) (id1 - id2);
327  return (diff <= 0);
328 }
signed int int32
Definition: c.h:346
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ TransactionStartedDuringRecovery()

bool TransactionStartedDuringRecovery ( void  )

Definition at line 953 of file xact.c.

References TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

954 {
956 }
static TransactionState CurrentTransactionState
Definition: xact.c:236
bool startedInRecovery
Definition: xact.c:191

Variable Documentation

◆ ShmemVariableCache