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 FirstBootstrapObjectId   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)
 
bool TransactionIdIsKnownCompleted (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)
 
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 294 of file transam.h.

Referenced by FullXidRelativeTo(), and GetNewObjectId().

◆ BootstrapTransactionId

#define BootstrapTransactionId   ((TransactionId) 1)

Definition at line 32 of file transam.h.

Referenced by GetNewTransactionId(), and TransactionLogFetch().

◆ EpochFromFullTransactionId

◆ FirstBootstrapObjectId

◆ FirstGenbkiObjectId

#define FirstGenbkiObjectId   10000

◆ FirstNormalFullTransactionId

#define FirstNormalFullTransactionId   FullTransactionIdFromEpochAndXid(0, FirstNormalTransactionId)

Definition at line 57 of file transam.h.

Referenced by FullTransactionIdAdvance(), and FullTransactionIdRetreat().

◆ FirstNormalObjectId

◆ FirstNormalTransactionId

◆ FrozenTransactionId

#define FrozenTransactionId   ((TransactionId) 2)

◆ FullTransactionIdEquals

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

Definition at line 50 of file transam.h.

Referenced by is_visible_fxid(), parse_snapshot(), pg_snapshot_recv(), xid8cmp(), xid8eq(), and xid8ne().

◆ FullTransactionIdFollows

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

Definition at line 53 of file transam.h.

Referenced by FullTransactionIdNewer(), xid8cmp(), and xid8gt().

◆ FullTransactionIdFollowsOrEquals

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

◆ FullTransactionIdIsNormal

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

Definition at line 58 of file transam.h.

Referenced by MaintainLatestCompletedXid(), and MaintainLatestCompletedXidRecovery().

◆ FullTransactionIdIsValid

◆ FullTransactionIdPrecedes

◆ FullTransactionIdPrecedesOrEquals

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

Definition at line 52 of file transam.h.

Referenced by xid8le().

◆ InvalidFullTransactionId

◆ InvalidTransactionId

#define InvalidTransactionId   ((TransactionId) 0)

Definition at line 31 of file transam.h.

Referenced by _bt_check_unique(), _bt_delitems_delete(), _bt_getroot(), _bt_initmetapage(), _bt_upgrademetapage(), _bt_xid_horizon(), AbortTransaction(), ActivateCommitTs(), AdvanceOldestCommitTsXid(), AlterSequence(), apply_returning_filter(), asyncQueueAddEntries(), asyncQueueReadAllNotifications(), BackendIdGetTransactionIds(), BackendXidGetPid(), BootStrapXLOG(), btvacuumscan(), BuildCachedPlan(), cleanup_subxact_info(), collect_corrupt_items(), CommitTransaction(), CommitTsShmemInit(), compute_new_xmax_infomask(), ComputeXidHorizons(), CreateCheckPoint(), createdb(), CreateDecodingContext(), CreateInitDecodingContext(), CreateSharedProcArray(), DeactivateCommitTs(), DecodeXLogRecord(), DefineIndex(), DefineQueryRewrite(), do_analyze_rel(), ExpireAllKnownAssignedTransactionIds(), fill_seq_with_data(), FreezeMultiXactId(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetStableLatestTransactionId(), gistprunepage(), GuessControlValues(), heap_abort_speculative(), heap_compute_xid_horizon_for_tuples(), heap_create(), heap_execute_freeze_tuple(), heap_force_common(), 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(), HeapCheckForSerializableConflictOut(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesNonVacuumable(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuum(), HeapTupleSatisfiesVacuumHorizon(), ImportSnapshot(), index_compute_xid_horizon_for_tuples(), index_create(), index_drop(), InitAuxiliaryProcess(), InitPredicateLocks(), InitProcess(), KnownAssignedXidsGet(), KnownAssignedXidsGetOldestXmin(), lazy_scan_heap(), logical_begin_heap_rewrite(), LogicalConfirmReceivedLocation(), main(), make_tuple_from_result_row(), MarkAsPreparingGuts(), maybe_send_schema(), message_cb_wrapper(), MinimumActiveBackends(), MultiXactIdGetUpdateXid(), pg_get_replication_slots(), pgoutput_change(), pgoutput_truncate(), PhysicalReplicationSlotNewXmin(), predicatelock_twophase_recover(), ProcArrayApplyRecoveryInfo(), ProcArrayApplyXidAssignment(), ProcArrayClearTransaction(), ProcArrayEndTransaction(), ProcArrayEndTransactionInternal(), ProcessStandbyHSFeedbackMessage(), read_seq_tuple(), RecordTransactionAbort(), RecordTransactionCommit(), recoveryStopsAfter(), recoveryStopsBefore(), RegisterPredicateLockingXid(), RelationSetNewRelfilenode(), ReleaseOneSerializableXact(), RemoveProcFromArray(), ReorderBufferAllocate(), ReorderBufferGetOldestXmin(), ReorderBufferProcessTXN(), ReorderBufferProcessXid(), ReorderBufferQueueMessage(), ReorderBufferReturnTXN(), ReplicationSlotCreate(), ReplicationSlotRelease(), ReplicationSlotsComputeRequiredXmin(), ResetLogicalStreamingState(), ResetSequence(), ResolveRecoveryConflictWithTablespace(), RestoreSlotFromDisk(), SerialInit(), SerialSetActiveSerXmin(), set_status_by_pages(), SetCommitTsLimit(), SetNewSxactGlobalXmin(), SetupCheckXidLive(), SimpleLruWriteAll(), SlruInternalWritePage(), SnapBuildFindSnapshot(), SnapBuildProcessRunningXacts(), SnapMgrInit(), SnapshotResetXmin(), spgFormDeadTuple(), stream_close_file(), stream_message_cb_wrapper(), SubTransGetParent(), SubTransSetParent(), swap_relation_files(), TwoPhaseGetGXact(), update_index_statistics(), UpdateXmaxHintBits(), vacuumRedirectAndPlaceholder(), WriteEmptyXLOG(), and XLogWalRcvSendHSFeedback().

◆ MaxTransactionId

#define MaxTransactionId   ((TransactionId) 0xFFFFFFFF)

Definition at line 35 of file transam.h.

Referenced by gistRedoPageReuse(), SetTransactionIdLimit(), and StartupSUBTRANS().

◆ NormalTransactionIdFollows

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

Definition at line 152 of file transam.h.

Referenced by SnapBuildCommitTxn().

◆ NormalTransactionIdPrecedes

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

Definition at line 147 of file transam.h.

Referenced by GetSnapshotData(), NormalTransactionIdOlder(), 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_unlink_halfdead_page(), _bt_vacuum_needs_cleanup(), AssignTransactionId(), bt_check_every_level(), btvacuumpage(), CachedPlanAllowsSimpleValidityCheck(), check_exclusion_or_unique_constraint(), CheckCachedPlan(), CheckForSerializableConflictOut(), CheckPointPredicate(), CheckTableForSerializableConflictIn(), ClearOldPredicateLocks(), ComputeXidHorizons(), ConditionalXactLockTableWait(), copy_table_data(), DecodeHeapOp(), DecodeXactOp(), DropAllPredicateLocksFromTable(), ExportSnapshot(), ForceTransactionIdLimitUpdate(), FreezeMultiXactId(), FullXidRelativeTo(), GetConflictingVirtualXIDs(), GetCurrentVirtualXIDs(), GetMultiXactIdMembers(), GetNewObjectId(), GetOldestSafeDecodingTransactionId(), GetRunningTransactionData(), GetRunningTransactionLocks(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetSnapshotDataReuse(), GetStableLatestTransactionId(), GinPageIsRecyclable(), GlobalVisTestShouldUpdate(), handle_streamed_transaction(), HandleConcurrentAbort(), heap_abort_speculative(), heap_get_latest_tid(), heap_get_root_tuples(), heap_getnext(), 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_prune_satisfies_vacuum(), heap_update(), heap_xlog_clean(), heapam_index_build_range_scan(), heapam_tuple_lock(), HeapCheckForSerializableConflictOut(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesNonVacuumable(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuum(), HeapTupleSatisfiesVacuumHorizon(), index_getnext_tid(), IsSubTransactionAssignmentPending(), KnownAssignedXidExists(), KnownAssignedXidsGetAndSetXmin(), KnownAssignedXidsRemove(), KnownAssignedXidsRemovePreceding(), KnownAssignedXidsRemoveTree(), LogicalConfirmReceivedLocation(), LogicalDecodingProcessRecord(), logicalrep_write_delete(), logicalrep_write_insert(), logicalrep_write_rel(), logicalrep_write_stream_abort(), logicalrep_write_stream_commit(), logicalrep_write_stream_start(), logicalrep_write_truncate(), logicalrep_write_typ(), logicalrep_write_update(), MultiXactIdCreate(), MultiXactIdExpand(), pg_stat_get_activity(), pg_xact_status(), predicatelock_twophase_recover(), PredicateLockPageSplit(), ProcArrayApplyRecoveryInfo(), ProcArrayEndTransaction(), ProcArrayEndTransactionInternal(), ProcArrayGroupClearXid(), ProcArrayRemove(), RecordKnownAssignedTransactionIds(), RecordTransactionAbort(), RecordTransactionCommit(), RegisterPredicateLockingXid(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), ReorderBufferTXNByXid(), ReplicationSlotRelease(), ReplicationSlotsComputeRequiredXmin(), ResolveRecoveryConflictWithSnapshot(), SerialAdd(), SerialGetMinConflictCommitSeqNo(), SerialSetActiveSerXmin(), SetHintBits(), SetNewSxactGlobalXmin(), SnapBuildAddCommittedTxn(), SnapBuildCommitTxn(), SnapBuildDistributeNewCatalogSnapshot(), SnapBuildInitialSnapshot(), SpeculativeInsertionWait(), spgFormDeadTuple(), spgRedoVacuumRedirect(), StandbyAcquireAccessExclusiveLock(), StandbyReleaseLocks(), StandbyReleaseOldLocks(), StandbyTransactionIdIsPrepared(), StartupXLOG(), stream_close_file(), stream_open_file(), stream_write_change(), SubTransGetTopmostTransaction(), SubTransSetParent(), subxact_info_add(), subxact_info_read(), subxact_info_write(), SummarizeOldestCommittedSxact(), swap_relation_files(), systable_beginscan(), systable_endscan(), table_index_fetch_tuple(), table_scan_bitmap_next_block(), table_scan_bitmap_next_tuple(), table_scan_getnextslot(), table_scan_sample_next_block(), table_scan_sample_next_tuple(), table_tuple_fetch_row_version(), table_tuple_get_latest_tid(), TransactionGroupUpdateXidStatus(), TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdGetCommitTsData(), TransactionIdInRecentPast(), TransactionIdIsActive(), TransactionIdIsInProgress(), TransactionIdLimitedForOldSnapshots(), TransactionIdOlder(), TransactionIdSetPageStatusInternal(), 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)

◆ XidFromFullTransactionId

Typedef Documentation

◆ FullTransactionId

◆ VariableCache

Definition at line 250 of file transam.h.

◆ VariableCacheData

Function Documentation

◆ AdvanceNextFullTransactionIdPastXid()

void AdvanceNextFullTransactionIdPastXid ( TransactionId  xid)

Definition at line 277 of file varsup.c.

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

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

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
285  * called from the startup process or single-process mode, meaning that no
286  * other 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 }
#define TransactionIdAdvance(dest)
Definition: transam.h:91
#define AmStartupProcess()
Definition: miscadmin.h:431
uint32 TransactionId
Definition: c.h:520
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
FullTransactionId nextXid
Definition: transam.h:213
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
bool IsUnderPostmaster
Definition: globals.c:109
VariableCache ShmemVariableCache
Definition: varsup.c:34
unsigned int uint32
Definition: c.h:374
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
#define Assert(condition)
Definition: c.h:745
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
static const unsigned __int64 epoch
Definition: gettimeofday.c:34
#define unlikely(x)
Definition: c.h:206

◆ AdvanceOldestClogXid()

void AdvanceOldestClogXid ( TransactionId  oldest_datfrozenxid)

Definition at line 328 of file varsup.c.

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

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

329 {
330  LWLockAcquire(XactTruncationLock, LW_EXCLUSIVE);
332  oldest_datfrozenxid))
333  {
334  ShmemVariableCache->oldestClogXid = oldest_datfrozenxid;
335  }
336  LWLockRelease(XactTruncationLock);
337 }
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
TransactionId oldestClogXid
Definition: transam.h:246
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:1208

◆ ForceTransactionIdLimitUpdate()

bool ForceTransactionIdLimitUpdate ( void  )

Definition at line 490 of file varsup.c.

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

Referenced by vac_update_datfrozenxid().

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 }
uint32 TransactionId
Definition: c.h:520
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId oldestXid
Definition: transam.h:215
unsigned int Oid
Definition: postgres_ext.h:31
FullTransactionId nextXid
Definition: transam.h:213
TransactionId xidVacLimit
Definition: transam.h:216
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:183
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ FullTransactionIdAdvance()

static void FullTransactionIdAdvance ( FullTransactionId dest)
inlinestatic

Definition at line 128 of file transam.h.

References FirstNormalFullTransactionId, FirstNormalTransactionId, FullTransactionIdPrecedes, FullTransactionId::value, and XidFromFullTransactionId.

Referenced by GetNewTransactionId().

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

◆ FullTransactionIdFromEpochAndXid()

static FullTransactionId FullTransactionIdFromEpochAndXid ( uint32  epoch,
TransactionId  xid 
)
inlinestatic

Definition at line 71 of file transam.h.

References FullTransactionId::value.

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

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

◆ FullTransactionIdFromU64()

static FullTransactionId FullTransactionIdFromU64 ( uint64  value)
inlinestatic

Definition at line 81 of file transam.h.

References FullTransactionId::value.

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

82 {
83  FullTransactionId result;
84 
85  result.value = value;
86 
87  return result;
88 }
static struct @142 value
uint64 value
Definition: transam.h:67

◆ FullTransactionIdNewer()

static FullTransactionId FullTransactionIdNewer ( FullTransactionId  a,
FullTransactionId  b 
)
inlinestatic

Definition at line 353 of file transam.h.

References FullTransactionIdFollows, and FullTransactionIdIsValid.

Referenced by GetSnapshotData(), and GlobalVisUpdateApply().

354 {
355  if (!FullTransactionIdIsValid(a))
356  return b;
357 
358  if (!FullTransactionIdIsValid(b))
359  return a;
360 
361  if (FullTransactionIdFollows(a, b))
362  return a;
363  return b;
364 }
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
#define FullTransactionIdFollows(a, b)
Definition: transam.h:53

◆ FullTransactionIdRetreat()

static void FullTransactionIdRetreat ( FullTransactionId dest)
inlinestatic

Definition at line 103 of file transam.h.

References FirstNormalFullTransactionId, FirstNormalTransactionId, FullTransactionIdPrecedes, FullTransactionId::value, and XidFromFullTransactionId.

Referenced by StartupXLOG().

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 }
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define FirstNormalTransactionId
Definition: transam.h:34
#define FirstNormalFullTransactionId
Definition: transam.h:57
uint64 value
Definition: transam.h:67
#define FullTransactionIdPrecedes(a, b)
Definition: transam.h:51

◆ GetNewObjectId()

Oid GetNewObjectId ( void  )

Definition at line 528 of file varsup.c.

References Assert, AssertTransactionIdInAllowableRange, elog, ERROR, FirstBootstrapObjectId, FirstNormalObjectId, IsPostmasterEnvironment, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::nextOid, VariableCacheData::nextXid, VariableCacheData::oidCount, VariableCacheData::oldestXid, pg_memory_barrier, RecoveryInProgress(), TransactionIdFollowsOrEquals(), TransactionIdIsNormal, TransactionIdIsValid, TransactionIdPrecedesOrEquals(), VAR_OID_PREFETCH, XidFromFullTransactionId, and XLogPutNextOid().

Referenced by GetNewOidWithIndex(), and GetNewRelFileNode().

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 FirstBootstrapObjectId, so
545  * we 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 FirstBootstrapObjectId 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 }
bool IsPostmasterEnvironment
Definition: globals.c:108
uint32 oidCount
Definition: transam.h:208
#define VAR_OID_PREFETCH
Definition: varsup.c:31
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:8074
#define FirstNormalObjectId
Definition: transam.h:190
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define ERROR
Definition: elog.h:43
void XLogPutNextOid(Oid nextOid)
Definition: xlog.c:9654
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define FirstBootstrapObjectId
Definition: transam.h:189
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
#define elog(elevel,...)
Definition: elog.h:214

◆ GetNewTransactionId()

FullTransactionId GetNewTransactionId ( bool  isSubXact)

Definition at line 50 of file varsup.c.

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(), 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().

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
183  * we have successfully completed ExtendCLOG() --- if that routine fails,
184  * we want the next incoming transaction to try it again. We cannot
185  * assign 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
196  * to 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 }
int errhint(const char *fmt,...)
Definition: elog.c:1071
uint32 TransactionId
Definition: c.h:520
XidCacheStatus * subxidStates
Definition: proc.h:315
PGPROC * MyProc
Definition: proc.c:67
void ExtendCLOG(TransactionId newestXact)
Definition: clog.c:839
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
int errcode(int sqlerrcode)
Definition: elog.c:610
PROC_HDR * ProcGlobal
Definition: proc.c:79
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:8074
FullTransactionId nextXid
Definition: transam.h:213
XidCacheStatus subxidStatus
Definition: proc.h:198
TransactionId xidVacLimit
Definition: transam.h:216
bool overflowed
Definition: proc.h:43
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
bool IsInParallelMode(void)
Definition: xact.c:1012
#define ERROR
Definition: elog.h:43
void ExtendSUBTRANS(TransactionId newestXact)
Definition: subtrans.c:307
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
#define BootstrapTransactionId
Definition: transam.h:32
TransactionId xidStopLimit
Definition: transam.h:218
bool IsUnderPostmaster
Definition: globals.c:109
VariableCache ShmemVariableCache
Definition: varsup.c:34
TransactionId * xids
Definition: proc.h:309
struct XidCache subxids
Definition: proc.h:200
#define WARNING
Definition: elog.h:40
#define PGPROC_MAX_CACHED_SUBXIDS
Definition: proc.h:36
#define ereport(elevel,...)
Definition: elog.h:144
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]
Definition: proc.h:48
#define Assert(condition)
Definition: c.h:745
void ExtendCommitTs(TransactionId newestXact)
Definition: commit_ts.c:828
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
uint8 count
Definition: proc.h:41
TransactionId xid
Definition: proc.h:124
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:393
TransactionId xidWarnLimit
Definition: transam.h:217
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
int pgxactoff
Definition: proc.h:139
TransactionId xidWrapLimit
Definition: transam.h:219
#define pg_write_barrier()
Definition: atomics.h:159
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:146
static void FullTransactionIdAdvance(FullTransactionId *dest)
Definition: transam.h:128

◆ NormalTransactionIdOlder()

static TransactionId NormalTransactionIdOlder ( TransactionId  a,
TransactionId  b 
)
inlinestatic

Definition at line 342 of file transam.h.

References Assert, NormalTransactionIdPrecedes, and TransactionIdIsNormal.

343 {
346  if (NormalTransactionIdPrecedes(a, b))
347  return a;
348  return b;
349 }
#define Assert(condition)
Definition: c.h:745
#define NormalTransactionIdPrecedes(id1, id2)
Definition: transam.h:147
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ ReadNewTransactionId()

static TransactionId ReadNewTransactionId ( void  )
inlinestatic

◆ ReadNextFullTransactionId()

FullTransactionId ReadNextFullTransactionId ( void  )

Definition at line 261 of file varsup.c.

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

Referenced by gistdeletepage(), gistRedoPageReuse(), pg_current_snapshot(), ReadNewTransactionId(), TransactionIdInRecentPast(), and XLogWalRcvSendHSFeedback().

262 {
263  FullTransactionId fullXid;
264 
265  LWLockAcquire(XidGenLock, LW_SHARED);
266  fullXid = ShmemVariableCache->nextXid;
267  LWLockRelease(XidGenLock);
268 
269  return fullXid;
270 }
FullTransactionId nextXid
Definition: transam.h:213
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208

◆ SetTransactionIdLimit()

void SetTransactionIdLimit ( TransactionId  oldest_datfrozenxid,
Oid  oldest_datoid 
)

Definition at line 345 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::nextXid, 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().

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("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 }
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:1071
uint32 TransactionId
Definition: c.h:520
bool InRecovery
Definition: xlog.c:205
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId oldestXid
Definition: transam.h:215
FullTransactionId nextXid
Definition: transam.h:213
TransactionId xidVacLimit
Definition: transam.h:216
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define FirstNormalTransactionId
Definition: transam.h:34
int autovacuum_freeze_max_age
Definition: autovacuum.c:124
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2155
TransactionId xidStopLimit
Definition: transam.h:218
bool IsUnderPostmaster
Definition: globals.c:109
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define WARNING
Definition: elog.h:40
#define MaxTransactionId
Definition: transam.h:35
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:745
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
bool IsTransactionState(void)
Definition: xact.c:371
TransactionId xidWarnLimit
Definition: transam.h:217
int errmsg(const char *fmt,...)
Definition: elog.c:824
TransactionId xidWrapLimit
Definition: transam.h:219
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:146
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ 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:164
#define TRANSACTION_STATUS_ABORTED
Definition: clog.h:29

◆ 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:28
void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
Definition: clog.c:164

◆ 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:28
void TransactionIdSetTreeStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
Definition: clog.c:164

◆ 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(), pg_xact_status(), ProcArrayApplyRecoveryInfo(), ProcessTwoPhaseBuffer(), StandbyAcquireAccessExclusiveLock(), test_lockmode_for_conflict(), TransactionIdDidAbort(), and TransactionIdIsInProgress().

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:520
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:109
int XidStatus
Definition: clog.h:25
TransactionId TransactionXmin
Definition: snapmgr.c:112
#define TRANSACTION_STATUS_ABORTED
Definition: clog.h:29
#define TRANSACTION_STATUS_SUB_COMMITTED
Definition: clog.h:30
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:214
#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(), HandleConcurrentAbort(), heap_prepare_freeze_tuple(), HeapTupleHeaderAdvanceLatestRemovedXid(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesHistoricMVCC(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuumHorizon(), MultiXactIdExpand(), pg_xact_status(), ProcArrayApplyRecoveryInfo(), ProcessTwoPhaseBuffer(), RecordTransactionAbort(), RecordTransactionAbortPrepared(), SetupCheckXidLive(), StandbyAcquireAccessExclusiveLock(), test_lockmode_for_conflict(), TransactionIdDidCommit(), 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:28
uint32 TransactionId
Definition: c.h:520
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:109
int XidStatus
Definition: clog.h:25
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
TransactionId TransactionXmin
Definition: snapmgr.c:112
#define TRANSACTION_STATUS_SUB_COMMITTED
Definition: clog.h:30
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define WARNING
Definition: elog.h:40
#define elog(elevel,...)
Definition: elog.h:214
#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:634
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:520
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300

◆ TransactionIdOlder()

static TransactionId TransactionIdOlder ( TransactionId  a,
TransactionId  b 
)
inlinestatic

Definition at line 327 of file transam.h.

References TransactionIdIsValid, and TransactionIdPrecedes().

Referenced by ComputeXidHorizons(), and GetSnapshotData().

328 {
329  if (!TransactionIdIsValid(a))
330  return b;
331 
332  if (!TransactionIdIsValid(b))
333  return a;
334 
335  if (TransactionIdPrecedes(a, b))
336  return a;
337  return b;
338 }
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ TransactionIdPrecedes()

bool TransactionIdPrecedes ( TransactionId  id1,
TransactionId  id2 
)

Definition at line 300 of file transam.c.

References TransactionIdIsNormal.

Referenced by _bt_unlink_halfdead_page(), AdvanceOldestClogXid(), AdvanceOldestCommitTsXid(), bt_check_every_level(), btvacuumpage(), check_exclusion_or_unique_constraint(), CheckTargetForConflictsIn(), CLOGPagePrecedes(), collect_corrupt_items(), CommitTsPagePrecedes(), copy_table_data(), do_start_worker(), ExportSnapshot(), FreezeMultiXactId(), get_relation_info(), GetOldestActiveTransactionId(), GetOldestSafeDecodingTransactionId(), GetRunningTransactionData(), heap_abort_speculative(), heap_page_is_all_visible(), heap_page_prune_opt(), heap_prepare_freeze_tuple(), heap_prune_record_prunable(), heap_prune_satisfies_vacuum(), heap_tuple_needs_freeze(), HeapCheckForSerializableConflictOut(), HeapTupleHeaderAdvanceLatestRemovedXid(), HeapTupleSatisfiesHistoricMVCC(), HeapTupleSatisfiesVacuum(), KnownAssignedXidsAdd(), KnownAssignedXidsGetAndSetXmin(), KnownAssignedXidsSearch(), lazy_scan_heap(), logical_rewrite_heap_tuple(), MaintainLatestCompletedXid(), MaintainLatestCompletedXidRecovery(), MaintainOldSnapshotTimeMapping(), multixact_redo(), pg_xact_status(), PhysicalReplicationSlotNewXmin(), PrescanPreparedTransactions(), ProcArrayApplyRecoveryInfo(), ProcArrayApplyXidAssignment(), ProcessStandbyHSFeedbackMessage(), RecordKnownAssignedTransactionIds(), relation_needs_vacanalyze(), ReorderBufferAbortOld(), ReplicationSlotsComputeRequiredXmin(), rewrite_heap_tuple(), SerialGetMinConflictCommitSeqNo(), SerialSetActiveSerXmin(), SetCommitTsLimit(), SetNewSxactGlobalXmin(), SnapBuildCommitTxn(), SnapBuildProcessChange(), SnapBuildRestore(), SnapshotResetXmin(), StandbyReleaseOldLocks(), SubTransGetTopmostTransaction(), SubTransPagePrecedes(), TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdGetCommitTsData(), TransactionIdInRecentPast(), TransactionIdIsActive(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), TransactionIdLatest(), TransactionIdLimitedForOldSnapshots(), TransactionIdOlder(), TransactionTreeSetCommitTsData(), tuple_all_visible(), vac_truncate_clog(), vac_update_datfrozenxid(), vac_update_relstats(), vacuum_set_xid_limits(), vacuumRedirectAndPlaceholder(), XidInMVCCSnapshot(), XidIsConcurrent(), xlog_redo(), 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:362
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ TransactionIdPrecedesOrEquals()

bool TransactionIdPrecedesOrEquals ( TransactionId  id1,
TransactionId  id2 
)

◆ TransactionIdRetreatedBy()

static TransactionId TransactionIdRetreatedBy ( TransactionId  xid,
uint32  amount 
)
inlinestatic

Definition at line 315 of file transam.h.

References FirstNormalTransactionId.

Referenced by ComputeXidHorizons(), and GetSnapshotData().

316 {
317  xid -= amount;
318 
319  while (xid < FirstNormalTransactionId)
320  xid--;
321 
322  return xid;
323 }
#define FirstNormalTransactionId
Definition: transam.h:34

◆ TransactionStartedDuringRecovery()

bool TransactionStartedDuringRecovery ( void  )

Definition at line 970 of file xact.c.

References TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

971 {
973 }
static TransactionState CurrentTransactionState
Definition: xact.c:250
bool startedInRecovery
Definition: xact.c:203

Variable Documentation

◆ ShmemVariableCache