PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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)
 
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)
 

Variables

static TransactionId cachedFetchXid = InvalidTransactionId
 
static XidStatus cachedFetchXidStatus
 
static XLogRecPtr cachedCommitLSN
 

Function Documentation

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
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
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
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:391
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
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(), 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:391
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
XLogRecPtr TransactionIdGetCommitLSN ( TransactionId  xid)

Definition at line 402 of file transam.c.

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

Referenced by SetHintBits().

403 {
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
return result
Definition: formatting.c:1633
static XLogRecPtr cachedCommitLSN
Definition: transam.c:35
uint64 XLogRecPtr
Definition: xlogdefs.h:21
XidStatus TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
Definition: clog.c:635
static TransactionId cachedFetchXid
Definition: transam.c:33
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
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
TransactionId TransactionIdLatest ( TransactionId  mainxid,
int  nxids,
const TransactionId xids 
)

Definition at line 365 of file transam.c.

References result, and TransactionIdPrecedes().

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

367 {
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:391
return result
Definition: formatting.c:1633
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
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:246
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
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:246
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
static XidStatus TransactionLogFetch ( TransactionId  transactionId)
static

Definition at line 52 of file transam.c.

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

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 TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define TRANSACTION_STATUS_COMMITTED
Definition: clog.h:27
int XidStatus
Definition: clog.h:24
#define TRANSACTION_STATUS_ABORTED
Definition: clog.h:28
#define BootstrapTransactionId
Definition: transam.h:32
#define TRANSACTION_STATUS_SUB_COMMITTED
Definition: clog.h:29
static XLogRecPtr cachedCommitLSN
Definition: transam.c:35
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define FrozenTransactionId
Definition: transam.h:33
XidStatus TransactionIdGetStatus(TransactionId xid, XLogRecPtr *lsn)
Definition: clog.c:635
static XidStatus cachedFetchXidStatus
Definition: transam.c:34
static TransactionId cachedFetchXid
Definition: transam.c:33
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:26

Variable Documentation

XLogRecPtr cachedCommitLSN
static

Definition at line 35 of file transam.c.

Referenced by TransactionIdGetCommitLSN(), and TransactionLogFetch().

XidStatus cachedFetchXidStatus
static

Definition at line 34 of file transam.c.

Referenced by TransactionLogFetch().