PostgreSQL Source Code  git master
transam.c File Reference
#include "postgres.h"
#include "access/clog.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "utils/snapmgr.h"
Include dependency graph for transam.c:

Go to the source code of this file.

Functions

static XidStatus TransactionLogFetch (TransactionId transactionId)
 
bool TransactionIdDidCommit (TransactionId transactionId)
 
bool TransactionIdDidAbort (TransactionId transactionId)
 
void TransactionIdCommitTree (TransactionId xid, int nxids, TransactionId *xids)
 
void TransactionIdAsyncCommitTree (TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn)
 
void TransactionIdAbortTree (TransactionId xid, int nxids, TransactionId *xids)
 
bool TransactionIdPrecedes (TransactionId id1, TransactionId id2)
 
bool TransactionIdPrecedesOrEquals (TransactionId id1, TransactionId id2)
 
bool TransactionIdFollows (TransactionId id1, TransactionId id2)
 
bool TransactionIdFollowsOrEquals (TransactionId id1, TransactionId id2)
 
TransactionId TransactionIdLatest (TransactionId mainxid, int nxids, const TransactionId *xids)
 
XLogRecPtr TransactionIdGetCommitLSN (TransactionId xid)
 

Variables

static TransactionId cachedFetchXid = InvalidTransactionId
 
static XidStatus cachedFetchXidStatus
 
static XLogRecPtr cachedCommitLSN
 

Function Documentation

◆ TransactionIdAbortTree()

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

Definition at line 270 of file transam.c.

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

References InvalidXLogRecPtr, TRANSACTION_STATUS_ABORTED, and TransactionIdSetTreeStatus().

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

◆ TransactionIdAsyncCommitTree()

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

Definition at line 252 of file transam.c.

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

References TRANSACTION_STATUS_COMMITTED, and TransactionIdSetTreeStatus().

Referenced by RecordTransactionCommit(), and xact_redo_commit().

◆ TransactionIdCommitTree()

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

◆ TransactionIdDidAbort()

bool TransactionIdDidAbort ( TransactionId  transactionId)

Definition at line 188 of file transam.c.

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

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

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

◆ TransactionIdDidCommit()

bool TransactionIdDidCommit ( TransactionId  transactionId)

Definition at line 126 of file transam.c.

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

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

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

◆ TransactionIdFollows()

◆ TransactionIdFollowsOrEquals()

◆ TransactionIdGetCommitLSN()

XLogRecPtr TransactionIdGetCommitLSN ( TransactionId  xid)

Definition at line 382 of file transam.c.

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

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

Referenced by SetHintBits().

◆ TransactionIdLatest()

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

Definition at line 345 of file transam.c.

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

References TransactionIdPrecedes().

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

◆ TransactionIdPrecedes()

bool TransactionIdPrecedes ( TransactionId  id1,
TransactionId  id2 
)

Definition at line 280 of file transam.c.

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

References TransactionIdIsNormal.

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

◆ TransactionIdPrecedesOrEquals()

◆ TransactionLogFetch()

static XidStatus TransactionLogFetch ( TransactionId  transactionId)
static

Definition at line 52 of file transam.c.

53 {
54  XidStatus xidstatus;
55  XLogRecPtr xidlsn;
56 
57  /*
58  * Before going to the commit log manager, check our single item cache to
59  * see if we didn't just check the transaction status a moment ago.
60  */
61  if (TransactionIdEquals(transactionId, cachedFetchXid))
62  return cachedFetchXidStatus;
63 
64  /*
65  * Also, check to see if the transaction ID is a permanent one.
66  */
67  if (!TransactionIdIsNormal(transactionId))
68  {
69  if (TransactionIdEquals(transactionId, BootstrapTransactionId))
71  if (TransactionIdEquals(transactionId, FrozenTransactionId))
74  }
75 
76  /*
77  * Get the transaction status.
78  */
79  xidstatus = TransactionIdGetStatus(transactionId, &xidlsn);
80 
81  /*
82  * Cache it, but DO NOT cache status for unfinished or sub-committed
83  * transactions! We only cache status that is guaranteed not to change.
84  */
85  if (xidstatus != TRANSACTION_STATUS_IN_PROGRESS &&
87  {
88  cachedFetchXid = transactionId;
89  cachedFetchXidStatus = xidstatus;
90  cachedCommitLSN = xidlsn;
91  }
92 
93  return xidstatus;
94 }
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:27
static XidStatus cachedFetchXidStatus
Definition: transam.c:34
#define FrozenTransactionId
Definition: transam.h:33
#define BootstrapTransactionId
Definition: transam.h:32

References BootstrapTransactionId, cachedCommitLSN, cachedFetchXid, cachedFetchXidStatus, FrozenTransactionId, TRANSACTION_STATUS_ABORTED, TRANSACTION_STATUS_COMMITTED, TRANSACTION_STATUS_IN_PROGRESS, TRANSACTION_STATUS_SUB_COMMITTED, TransactionIdEquals, TransactionIdGetStatus(), and TransactionIdIsNormal.

Referenced by TransactionIdDidAbort(), and TransactionIdDidCommit().

Variable Documentation

◆ cachedCommitLSN

XLogRecPtr cachedCommitLSN
static

Definition at line 35 of file transam.c.

Referenced by TransactionIdGetCommitLSN(), and TransactionLogFetch().

◆ cachedFetchXid

TransactionId cachedFetchXid = InvalidTransactionId
static

Definition at line 33 of file transam.c.

Referenced by TransactionIdGetCommitLSN(), and TransactionLogFetch().

◆ cachedFetchXidStatus

XidStatus cachedFetchXidStatus
static

Definition at line 34 of file transam.c.

Referenced by TransactionLogFetch().