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  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 TransactionIdAdvance(dest)
 
#define TransactionIdRetreat(dest)
 
#define NormalTransactionIdPrecedes(id1, id2)
 
#define NormalTransactionIdFollows(id1, id2)
 
#define FirstBootstrapObjectId   10000
 
#define FirstNormalObjectId   16384
 

Typedefs

typedef struct VariableCacheData VariableCacheData
 
typedef VariableCacheDataVariableCache
 

Functions

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)
 
TransactionId GetNewTransactionId (bool isSubXact)
 
TransactionId ReadNewTransactionId (void)
 
void SetTransactionIdLimit (TransactionId oldest_datfrozenxid, Oid oldest_datoid)
 
void AdvanceOldestClogXid (TransactionId oldest_datfrozenxid)
 
bool ForceTransactionIdLimitUpdate (void)
 
Oid GetNewObjectId (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().

◆ FirstBootstrapObjectId

◆ FirstNormalObjectId

◆ FirstNormalTransactionId

◆ FrozenTransactionId

#define FrozenTransactionId   ((TransactionId) 2)

Definition at line 33 of file transam.h.

Referenced by fill_seq_with_data(), heap_execute_freeze_tuple(), and TransactionLogFetch().

◆ InvalidTransactionId

#define InvalidTransactionId   ((TransactionId) 0)

Definition at line 31 of file transam.h.

Referenced by _bt_check_unique(), AbortTransaction(), ActivateCommitTs(), AddNewRelationTuple(), AdvanceOldestCommitTsXid(), AlterSequence(), asyncQueueAddEntries(), asyncQueueReadAllNotifications(), BackendIdGetTransactionIds(), BackendXidGetPid(), BootStrapXLOG(), btree_xlog_delete_get_latestRemovedXid(), BuildCachedPlan(), CheckForSerializableConflictOut(), CleanupTransaction(), collect_corrupt_items(), CommitTransaction(), CommitTsShmemInit(), compute_new_xmax_infomask(), CreateCheckPoint(), CreateDecodingContext(), CreateInitDecodingContext(), CreateSharedProcArray(), DeactivateCommitTs(), DefineQueryRewrite(), do_analyze_rel(), ExpireAllKnownAssignedTransactionIds(), fill_seq_with_data(), FreezeMultiXactId(), funny_dup17(), GetOldestXmin(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetStableLatestTransactionId(), GuessControlValues(), hash_xlog_vacuum_get_latestRemovedXid(), heap_abort_speculative(), 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_xlog_delete(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuum(), ImportSnapshot(), index_drop(), index_set_state_flags(), IndexBuildHeapRangeScan(), InitAuxiliaryProcess(), InitPredicateLocks(), InitProcess(), KnownAssignedXidsGet(), KnownAssignedXidsGetOldestXmin(), lazy_cleanup_index(), lazy_scan_heap(), lazy_vacuum_rel(), 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(), PrepareTransaction(), ProcArrayApplyRecoveryInfo(), ProcArrayApplyXidAssignment(), ProcArrayClearTransaction(), ProcArrayEndTransaction(), ProcArrayEndTransactionInternal(), ProcessStandbyHSFeedbackMessage(), PushTransaction(), read_seq_tuple(), RecordTransactionAbort(), RecordTransactionCommit(), recoveryStopsAfter(), recoveryStopsBefore(), RegisterPredicateLockingXid(), reindex_index(), RelationSetNewRelfilenode(), ReleaseOneSerializableXact(), RemoveProcFromArray(), ReorderBufferAllocate(), ReorderBufferCommit(), ReorderBufferProcessXid(), ReorderBufferQueueMessage(), ReorderBufferReturnTXN(), ReplicationSlotCreate(), ReplicationSlotRelease(), ReplicationSlotsComputeRequiredXmin(), ResetSequence(), ResolveRecoveryConflictWithTablespace(), RestoreSlotFromDisk(), set_status_by_pages(), SetCommitTsLimit(), SetNewSxactGlobalXmin(), SimpleLruFlush(), SlruInternalWritePage(), SnapBuildFindSnapshot(), SnapMgrInit(), SnapshotResetXmin(), spgFormDeadTuple(), StartTransaction(), 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:671
signed int int32
Definition: c.h:284
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

Definition at line 67 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:671
signed int int32
Definition: c.h:284
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

Definition at line 62 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(), AbortSubTransaction(), AssignTransactionId(), bt_check_every_level(), check_exclusion_or_unique_constraint(), CheckCachedPlan(), CheckForSerializableConflictOut(), CheckPointPredicate(), CheckTableForSerializableConflictIn(), ClearOldPredicateLocks(), CommitSubTransaction(), ConditionalXactLockTableWait(), DecodeHeapOp(), DecodeXactOp(), DropAllPredicateLocksFromTable(), EstimateTransactionStateSpace(), EvalPlanQualFetch(), ExportSnapshot(), ForceTransactionIdLimitUpdate(), FreezeMultiXactId(), GetConflictingVirtualXIDs(), GetCurrentTransactionId(), GetCurrentVirtualXIDs(), GetMultiXactIdMembers(), GetOldestSafeDecodingTransactionId(), GetOldestXmin(), GetRunningTransactionData(), GetRunningTransactionLocks(), GetSerializableTransactionSnapshotInt(), GetSnapshotData(), GetStableLatestTransactionId(), GetTopTransactionId(), 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_prune_chain(), heap_prune_record_prunable(), heap_update(), heap_xlog_clean(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuum(), index_getnext_tid(), KnownAssignedXidExists(), KnownAssignedXidsGetAndSetXmin(), KnownAssignedXidsRemove(), KnownAssignedXidsRemovePreceding(), KnownAssignedXidsRemoveTree(), LogicalConfirmReceivedLocation(), MarkCurrentTransactionIdLoggedIfAny(), 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(), SerializeTransactionState(), SetHintBits(), SetNewSxactGlobalXmin(), SnapBuildAddCommittedTxn(), SnapBuildCommitTxn(), SnapBuildDistributeNewCatalogSnapshot(), SnapBuildInitialSnapshot(), SpeculativeInsertionWait(), spgFormDeadTuple(), spgRedoVacuumRedirect(), StandbyAcquireAccessExclusiveLock(), StandbyReleaseLocks(), StandbyReleaseOldLocks(), StandbyTransactionIdIsPrepared(), StartupXLOG(), SubTransGetTopmostTransaction(), SubTransSetParent(), SummarizeOldestCommittedSxact(), TransactionGroupUpdateXidStatus(), TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdGetCommitTsData(), TransactionIdInRecentPast(), TransactionIdIsActive(), TransactionIdIsCurrentTransactionId(), TransactionIdIsInProgress(), TransactionIdSetPageStatusInternal(), txid_status(), 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.

Typedef Documentation

◆ VariableCache

Definition at line 145 of file transam.h.

◆ VariableCacheData

Function Documentation

◆ AdvanceOldestClogXid()

void AdvanceOldestClogXid ( TransactionId  oldest_datfrozenxid)

Definition at line 271 of file varsup.c.

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

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

272 {
273  LWLockAcquire(CLogTruncationLock, LW_EXCLUSIVE);
275  oldest_datfrozenxid))
276  {
277  ShmemVariableCache->oldestClogXid = oldest_datfrozenxid;
278  }
279  LWLockRelease(CLogTruncationLock);
280 }
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
TransactionId oldestClogXid
Definition: transam.h:141
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:1117

◆ ForceTransactionIdLimitUpdate()

bool ForceTransactionIdLimitUpdate ( void  )

Definition at line 429 of file varsup.c.

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

Referenced by vac_update_datfrozenxid().

430 {
431  TransactionId nextXid;
432  TransactionId xidVacLimit;
433  TransactionId oldestXid;
434  Oid oldestXidDB;
435 
436  /* Locking is probably not really necessary, but let's be careful */
437  LWLockAcquire(XidGenLock, LW_SHARED);
438  nextXid = ShmemVariableCache->nextXid;
439  xidVacLimit = ShmemVariableCache->xidVacLimit;
440  oldestXid = ShmemVariableCache->oldestXid;
441  oldestXidDB = ShmemVariableCache->oldestXidDB;
442  LWLockRelease(XidGenLock);
443 
444  if (!TransactionIdIsNormal(oldestXid))
445  return true; /* shouldn't happen, but just in case */
446  if (!TransactionIdIsValid(xidVacLimit))
447  return true; /* this shouldn't happen anymore either */
448  if (TransactionIdFollowsOrEquals(nextXid, xidVacLimit))
449  return true; /* past VacLimit, don't delay updating */
451  return true; /* could happen, per comments above */
452  return false;
453 }
uint32 TransactionId
Definition: c.h:445
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId oldestXid
Definition: transam.h:119
unsigned int Oid
Definition: postgres_ext.h:31
TransactionId xidVacLimit
Definition: transam.h:120
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define SearchSysCacheExists1(cacheId, key1)
Definition: syscache.h:182
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
TransactionId nextXid
Definition: transam.h:117
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ GetNewObjectId()

Oid GetNewObjectId ( void  )

Definition at line 467 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 GetNewOid(), GetNewOidWithIndex(), and GetNewRelFileNode().

468 {
469  Oid result;
470 
471  /* safety check, we should never get this far in a HS standby */
472  if (RecoveryInProgress())
473  elog(ERROR, "cannot assign OIDs during recovery");
474 
475  LWLockAcquire(OidGenLock, LW_EXCLUSIVE);
476 
477  /*
478  * Check for wraparound of the OID counter. We *must* not return 0
479  * (InvalidOid); and as long as we have to check that, it seems a good
480  * idea to skip over everything below FirstNormalObjectId too. (This
481  * basically just avoids lots of collisions with bootstrap-assigned OIDs
482  * right after a wrap occurs, so as to avoid a possibly large number of
483  * iterations in GetNewOid.) Note we are relying on unsigned comparison.
484  *
485  * During initdb, we start the OID generator at FirstBootstrapObjectId, so
486  * we only wrap if before that point when in bootstrap or standalone mode.
487  * The first time through this routine after normal postmaster start, the
488  * counter will be forced up to FirstNormalObjectId. This mechanism
489  * leaves the OIDs between FirstBootstrapObjectId and FirstNormalObjectId
490  * available for automatic assignment during initdb, while ensuring they
491  * will never conflict with user-assigned OIDs.
492  */
494  {
496  {
497  /* wraparound, or first post-initdb assignment, in normal mode */
500  }
501  else
502  {
503  /* we may be bootstrapping, so don't enforce the full range */
505  {
506  /* wraparound in standalone mode (unlikely but possible) */
509  }
510  }
511  }
512 
513  /* If we run out of logged for use oids then we must log more */
514  if (ShmemVariableCache->oidCount == 0)
515  {
518  }
519 
520  result = ShmemVariableCache->nextOid;
521 
524 
525  LWLockRelease(OidGenLock);
526 
527  return result;
528 }
bool IsPostmasterEnvironment
Definition: globals.c:100
uint32 oidCount
Definition: transam.h:112
#define VAR_OID_PREFETCH
Definition: varsup.c:31
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:7929
#define FirstNormalObjectId
Definition: transam.h:94
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define ERROR
Definition: elog.h:43
void XLogPutNextOid(Oid nextOid)
Definition: xlog.c:9404
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define FirstBootstrapObjectId
Definition: transam.h:93
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
#define elog
Definition: elog.h:219

◆ GetNewTransactionId()

TransactionId GetNewTransactionId ( bool  isSubXact)

Definition at line 48 of file varsup.c.

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

Referenced by AssignTransactionId().

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

◆ ReadNewTransactionId()

TransactionId ReadNewTransactionId ( void  )

Definition at line 250 of file varsup.c.

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

Referenced by _bt_unlink_halfdead_page(), ActivateCommitTs(), AutoVacWorkerMain(), do_start_worker(), GetNextXidAndEpoch(), GetStableLatestTransactionId(), vac_truncate_clog(), vac_update_datfrozenxid(), vac_update_relstats(), and vacuum_set_xid_limits().

251 {
252  TransactionId xid;
253 
254  LWLockAcquire(XidGenLock, LW_SHARED);
256  LWLockRelease(XidGenLock);
257 
258  return xid;
259 }
uint32 TransactionId
Definition: c.h:445
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
TransactionId nextXid
Definition: transam.h:117
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117

◆ SetTransactionIdLimit()

void SetTransactionIdLimit ( TransactionId  oldest_datfrozenxid,
Oid  oldest_datoid 
)

Definition at line 288 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, VariableCacheData::xidStopLimit, VariableCacheData::xidVacLimit, VariableCacheData::xidWarnLimit, and VariableCacheData::xidWrapLimit.

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

289 {
290  TransactionId xidVacLimit;
291  TransactionId xidWarnLimit;
292  TransactionId xidStopLimit;
293  TransactionId xidWrapLimit;
294  TransactionId curXid;
295 
296  Assert(TransactionIdIsNormal(oldest_datfrozenxid));
297 
298  /*
299  * The place where we actually get into deep trouble is halfway around
300  * from the oldest potentially-existing XID. (This calculation is
301  * probably off by one or two counts, because the special XIDs reduce the
302  * size of the loop a little bit. But we throw in plenty of slop below,
303  * so it doesn't matter.)
304  */
305  xidWrapLimit = oldest_datfrozenxid + (MaxTransactionId >> 1);
306  if (xidWrapLimit < FirstNormalTransactionId)
307  xidWrapLimit += FirstNormalTransactionId;
308 
309  /*
310  * We'll refuse to continue assigning XIDs in interactive mode once we get
311  * within 1M transactions of data loss. This leaves lots of room for the
312  * DBA to fool around fixing things in a standalone backend, while not
313  * being significant compared to total XID space. (Note that since
314  * vacuuming requires one transaction per table cleaned, we had better be
315  * sure there's lots of XIDs left...)
316  */
317  xidStopLimit = xidWrapLimit - 1000000;
318  if (xidStopLimit < FirstNormalTransactionId)
319  xidStopLimit -= FirstNormalTransactionId;
320 
321  /*
322  * We'll start complaining loudly when we get within 10M transactions of
323  * the stop point. This is kind of arbitrary, but if you let your gas
324  * gauge get down to 1% of full, would you be looking for the next gas
325  * station? We need to be fairly liberal about this number because there
326  * are lots of scenarios where most transactions are done by automatic
327  * clients that won't pay attention to warnings. (No, we're not gonna make
328  * this configurable. If you know enough to configure it, you know enough
329  * to not get in this kind of trouble in the first place.)
330  */
331  xidWarnLimit = xidStopLimit - 10000000;
332  if (xidWarnLimit < FirstNormalTransactionId)
333  xidWarnLimit -= FirstNormalTransactionId;
334 
335  /*
336  * We'll start trying to force autovacuums when oldest_datfrozenxid gets
337  * to be more than autovacuum_freeze_max_age transactions old.
338  *
339  * Note: guc.c ensures that autovacuum_freeze_max_age is in a sane range,
340  * so that xidVacLimit will be well before xidWarnLimit.
341  *
342  * Note: autovacuum_freeze_max_age is a PGC_POSTMASTER parameter so that
343  * we don't have to worry about dealing with on-the-fly changes in its
344  * value. It doesn't look practical to update shared state from a GUC
345  * assign hook (too many processes would try to execute the hook,
346  * resulting in race conditions as well as crashes of those not connected
347  * to shared memory). Perhaps this can be improved someday. See also
348  * SetMultiXactIdLimit.
349  */
350  xidVacLimit = oldest_datfrozenxid + autovacuum_freeze_max_age;
351  if (xidVacLimit < FirstNormalTransactionId)
352  xidVacLimit += FirstNormalTransactionId;
353 
354  /* Grab lock for just long enough to set the new limit values */
355  LWLockAcquire(XidGenLock, LW_EXCLUSIVE);
356  ShmemVariableCache->oldestXid = oldest_datfrozenxid;
357  ShmemVariableCache->xidVacLimit = xidVacLimit;
358  ShmemVariableCache->xidWarnLimit = xidWarnLimit;
359  ShmemVariableCache->xidStopLimit = xidStopLimit;
360  ShmemVariableCache->xidWrapLimit = xidWrapLimit;
361  ShmemVariableCache->oldestXidDB = oldest_datoid;
362  curXid = ShmemVariableCache->nextXid;
363  LWLockRelease(XidGenLock);
364 
365  /* Log the info */
366  ereport(DEBUG1,
367  (errmsg("transaction ID wrap limit is %u, limited by database with OID %u",
368  xidWrapLimit, oldest_datoid)));
369 
370  /*
371  * If past the autovacuum force point, immediately signal an autovac
372  * request. The reason for this is that autovac only processes one
373  * database per invocation. Once it's finished cleaning up the oldest
374  * database, it'll call here, and we'll signal the postmaster to start
375  * another iteration immediately if there are still any old databases.
376  */
377  if (TransactionIdFollowsOrEquals(curXid, xidVacLimit) &&
380 
381  /* Give an immediate warning if past the wrap warn point */
382  if (TransactionIdFollowsOrEquals(curXid, xidWarnLimit) && !InRecovery)
383  {
384  char *oldest_datname;
385 
386  /*
387  * We can be called when not inside a transaction, for example during
388  * StartupXLOG(). In such a case we cannot do database access, so we
389  * must just report the oldest DB's OID.
390  *
391  * Note: it's also possible that get_database_name fails and returns
392  * NULL, for example because the database just got dropped. We'll
393  * still warn, even though the warning might now be unnecessary.
394  */
395  if (IsTransactionState())
396  oldest_datname = get_database_name(oldest_datoid);
397  else
398  oldest_datname = NULL;
399 
400  if (oldest_datname)
402  (errmsg("database \"%s\" must be vacuumed within %u transactions",
403  oldest_datname,
404  xidWrapLimit - curXid),
405  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
406  "You might also need to commit or roll back old prepared transactions.")));
407  else
409  (errmsg("database with OID %u must be vacuumed within %u transactions",
410  oldest_datoid,
411  xidWrapLimit - curXid),
412  errhint("To avoid a database shutdown, execute a database-wide VACUUM in that database.\n"
413  "You might also need to commit or roll back old prepared transactions.")));
414  }
415 }
#define DEBUG1
Definition: elog.h:25
int errhint(const char *fmt,...)
Definition: elog.c:987
uint32 TransactionId
Definition: c.h:445
bool InRecovery
Definition: xlog.c:194
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId oldestXid
Definition: transam.h:119
TransactionId xidVacLimit
Definition: transam.h:120
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define FirstNormalTransactionId
Definition: transam.h:34
int autovacuum_freeze_max_age
Definition: autovacuum.c:122
TransactionId nextXid
Definition: transam.h:117
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
TransactionId xidStopLimit
Definition: transam.h:122
bool IsUnderPostmaster
Definition: globals.c:101
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
#define MaxTransactionId
Definition: transam.h:35
#define Assert(condition)
Definition: c.h:670
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
bool IsTransactionState(void)
Definition: xact.c:351
TransactionId xidWarnLimit
Definition: transam.h:121
int errmsg(const char *fmt,...)
Definition: elog.c:797
TransactionId xidWrapLimit
Definition: transam.h:123
void SendPostmasterSignal(PMSignalReason reason)
Definition: pmsignal.c:113
#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:445
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:109
int XidStatus
Definition: clog.h:24
TransactionId TransactionXmin
Definition: snapmgr.c:164
#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
Definition: elog.h:219
#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(), compute_new_xmax_infomask(), FreezeMultiXactId(), 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:445
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:164
#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
Definition: elog.h:219
#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:445
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(), AdvanceOldestClogXid(), AdvanceOldestCommitTsXid(), check_exclusion_or_unique_constraint(), CheckForSerializableConflictOut(), CheckTargetForConflictsIn(), CLOGPagePrecedes(), collect_corrupt_items(), CommitTsPagePrecedes(), convert_xid(), copy_heap_data(), do_start_worker(), ExpireTreeKnownAssignedTransactionIds(), ExportSnapshot(), FreezeMultiXactId(), get_relation_info(), GetOldestActiveTransactionId(), GetOldestSafeDecodingTransactionId(), GetOldestXmin(), GetRunningTransactionData(), GetSnapshotData(), 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(), OldSerXidAdd(), OldSerXidGetMinConflictCommitSeqNo(), OldSerXidSetActiveSerXmin(), PhysicalReplicationSlotNewXmin(), PrescanPreparedTransactions(), ProcArrayApplyRecoveryInfo(), ProcArrayApplyXidAssignment(), ProcArrayEndTransactionInternal(), ProcArrayRemove(), ProcessStandbyHSFeedbackMessage(), RecordKnownAssignedTransactionIds(), relation_needs_vacanalyze(), ReorderBufferAbortOld(), ReplicationSlotsComputeRequiredXmin(), rewrite_heap_tuple(), SetCommitTsLimit(), SetNewSxactGlobalXmin(), SnapBuildCommitTxn(), SnapBuildProcessChange(), SnapBuildRestore(), SnapshotResetXmin(), 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:284
#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(), KnownAssignedXidsAdd(), lazy_vacuum_rel(), 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:284
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ TransactionStartedDuringRecovery()

bool TransactionStartedDuringRecovery ( void  )

Definition at line 864 of file xact.c.

References TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

865 {
867 }
static TransactionState CurrentTransactionState
Definition: xact.c:233
bool startedInRecovery
Definition: xact.c:189

Variable Documentation

◆ ShmemVariableCache