PostgreSQL Source Code  git master
xact.c File Reference
#include "postgres.h"
#include <time.h>
#include <unistd.h>
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/parallel.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_enum.h"
#include "catalog/storage.h"
#include "commands/async.h"
#include "commands/tablecmds.h"
#include "commands/trigger.h"
#include "commands/waitlsn.h"
#include "common/pg_prng.h"
#include "executor/spi.h"
#include "libpq/be-fsstubs.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "replication/logical.h"
#include "replication/logicallauncher.h"
#include "replication/logicalworker.h"
#include "replication/origin.h"
#include "replication/snapbuild.h"
#include "replication/syncrep.h"
#include "storage/condition_variable.h"
#include "storage/fd.h"
#include "storage/lmgr.h"
#include "storage/md.h"
#include "storage/predicate.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/sinvaladt.h"
#include "storage/smgr.h"
#include "utils/builtins.h"
#include "utils/combocid.h"
#include "utils/guc.h"
#include "utils/inval.h"
#include "utils/memutils.h"
#include "utils/relmapper.h"
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
Include dependency graph for xact.c:

Go to the source code of this file.

Data Structures

struct  TransactionStateData
 
struct  SerializedTransactionState
 
struct  XactCallbackItem
 
struct  SubXactCallbackItem
 

Macros

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)
 

Typedefs

typedef enum TransState TransState
 
typedef enum TBlockState TBlockState
 
typedef struct TransactionStateData TransactionStateData
 
typedef TransactionStateDataTransactionState
 
typedef struct SerializedTransactionState SerializedTransactionState
 
typedef struct XactCallbackItem XactCallbackItem
 
typedef struct SubXactCallbackItem SubXactCallbackItem
 

Enumerations

enum  TransState {
  TRANS_DEFAULT , TRANS_START , TRANS_INPROGRESS , TRANS_COMMIT ,
  TRANS_ABORT , TRANS_PREPARE
}
 
enum  TBlockState {
  TBLOCK_DEFAULT , TBLOCK_STARTED , TBLOCK_BEGIN , TBLOCK_INPROGRESS ,
  TBLOCK_IMPLICIT_INPROGRESS , TBLOCK_PARALLEL_INPROGRESS , TBLOCK_END , TBLOCK_ABORT ,
  TBLOCK_ABORT_END , TBLOCK_ABORT_PENDING , TBLOCK_PREPARE , TBLOCK_SUBBEGIN ,
  TBLOCK_SUBINPROGRESS , TBLOCK_SUBRELEASE , TBLOCK_SUBCOMMIT , TBLOCK_SUBABORT ,
  TBLOCK_SUBABORT_END , TBLOCK_SUBABORT_PENDING , TBLOCK_SUBRESTART , TBLOCK_SUBABORT_RESTART
}
 

Functions

static void AssignTransactionId (TransactionState s)
 
static void AbortTransaction (void)
 
static void AtAbort_Memory (void)
 
static void AtCleanup_Memory (void)
 
static void AtAbort_ResourceOwner (void)
 
static void AtCCI_LocalCache (void)
 
static void AtCommit_Memory (void)
 
static void AtStart_Cache (void)
 
static void AtStart_Memory (void)
 
static void AtStart_ResourceOwner (void)
 
static void CallXactCallbacks (XactEvent event)
 
static void CallSubXactCallbacks (SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
 
static void CleanupTransaction (void)
 
static void CheckTransactionBlock (bool isTopLevel, bool throwError, const char *stmtType)
 
static void CommitTransaction (void)
 
static TransactionId RecordTransactionAbort (bool isSubXact)
 
static void StartTransaction (void)
 
static bool CommitTransactionCommandInternal (void)
 
static bool AbortCurrentTransactionInternal (void)
 
static void StartSubTransaction (void)
 
static void CommitSubTransaction (void)
 
static void AbortSubTransaction (void)
 
static void CleanupSubTransaction (void)
 
static void PushTransaction (void)
 
static void PopTransaction (void)
 
static void AtSubAbort_Memory (void)
 
static void AtSubCleanup_Memory (void)
 
static void AtSubAbort_ResourceOwner (void)
 
static void AtSubCommit_Memory (void)
 
static void AtSubStart_Memory (void)
 
static void AtSubStart_ResourceOwner (void)
 
static void ShowTransactionState (const char *str)
 
static void ShowTransactionStateRec (const char *str, TransactionState s)
 
static const char * BlockStateAsString (TBlockState blockState)
 
static const char * TransStateAsString (TransState state)
 
bool IsTransactionState (void)
 
bool IsAbortedTransactionBlockState (void)
 
TransactionId GetTopTransactionId (void)
 
TransactionId GetTopTransactionIdIfAny (void)
 
TransactionId GetCurrentTransactionId (void)
 
TransactionId GetCurrentTransactionIdIfAny (void)
 
FullTransactionId GetTopFullTransactionId (void)
 
FullTransactionId GetTopFullTransactionIdIfAny (void)
 
FullTransactionId GetCurrentFullTransactionId (void)
 
FullTransactionId GetCurrentFullTransactionIdIfAny (void)
 
void MarkCurrentTransactionIdLoggedIfAny (void)
 
bool IsSubxactTopXidLogPending (void)
 
void MarkSubxactTopXidLogged (void)
 
TransactionId GetStableLatestTransactionId (void)
 
SubTransactionId GetCurrentSubTransactionId (void)
 
bool SubTransactionIsActive (SubTransactionId subxid)
 
CommandId GetCurrentCommandId (bool used)
 
void SetParallelStartTimestamps (TimestampTz xact_ts, TimestampTz stmt_ts)
 
TimestampTz GetCurrentTransactionStartTimestamp (void)
 
TimestampTz GetCurrentStatementStartTimestamp (void)
 
TimestampTz GetCurrentTransactionStopTimestamp (void)
 
void SetCurrentStatementStartTimestamp (void)
 
int GetCurrentTransactionNestLevel (void)
 
bool TransactionIdIsCurrentTransactionId (TransactionId xid)
 
bool TransactionStartedDuringRecovery (void)
 
void EnterParallelMode (void)
 
void ExitParallelMode (void)
 
bool IsInParallelMode (void)
 
void CommandCounterIncrement (void)
 
void ForceSyncCommit (void)
 
static TransactionId RecordTransactionCommit (void)
 
static void AtSubCommit_childXids (void)
 
static void AtSubAbort_childXids (void)
 
static void PrepareTransaction (void)
 
void StartTransactionCommand (void)
 
void SaveTransactionCharacteristics (SavedTransactionCharacteristics *s)
 
void RestoreTransactionCharacteristics (const SavedTransactionCharacteristics *s)
 
void CommitTransactionCommand (void)
 
void AbortCurrentTransaction (void)
 
void PreventInTransactionBlock (bool isTopLevel, const char *stmtType)
 
void WarnNoTransactionBlock (bool isTopLevel, const char *stmtType)
 
void RequireTransactionBlock (bool isTopLevel, const char *stmtType)
 
bool IsInTransactionBlock (bool isTopLevel)
 
void RegisterXactCallback (XactCallback callback, void *arg)
 
void UnregisterXactCallback (XactCallback callback, void *arg)
 
void RegisterSubXactCallback (SubXactCallback callback, void *arg)
 
void UnregisterSubXactCallback (SubXactCallback callback, void *arg)
 
void BeginTransactionBlock (void)
 
bool PrepareTransactionBlock (const char *gid)
 
bool EndTransactionBlock (bool chain)
 
void UserAbortTransactionBlock (bool chain)
 
void BeginImplicitTransactionBlock (void)
 
void EndImplicitTransactionBlock (void)
 
void DefineSavepoint (const char *name)
 
void ReleaseSavepoint (const char *name)
 
void RollbackToSavepoint (const char *name)
 
void BeginInternalSubTransaction (const char *name)
 
void ReleaseCurrentSubTransaction (void)
 
void RollbackAndReleaseCurrentSubTransaction (void)
 
void AbortOutOfAnyTransaction (void)
 
bool IsTransactionBlock (void)
 
bool IsTransactionOrTransactionBlock (void)
 
char TransactionBlockStatusCode (void)
 
bool IsSubTransaction (void)
 
Size EstimateTransactionStateSpace (void)
 
void SerializeTransactionState (Size maxsize, char *start_address)
 
void StartParallelWorkerTransaction (char *tstatespace)
 
void EndParallelWorkerTransaction (void)
 
int xactGetCommittedChildren (TransactionId **ptr)
 
XLogRecPtr XactLogCommitRecord (TimestampTz commit_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInval, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
 
XLogRecPtr XactLogAbortRecord (TimestampTz abort_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
 
static void xact_redo_commit (xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
 
static void xact_redo_abort (xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
 
void xact_redo (XLogReaderState *record)
 

Variables

int DefaultXactIsoLevel = XACT_READ_COMMITTED
 
int XactIsoLevel = XACT_READ_COMMITTED
 
bool DefaultXactReadOnly = false
 
bool XactReadOnly
 
bool DefaultXactDeferrable = false
 
bool XactDeferrable
 
int synchronous_commit = SYNCHRONOUS_COMMIT_ON
 
TransactionId CheckXidAlive = InvalidTransactionId
 
bool bsysscan = false
 
static FullTransactionId XactTopFullTransactionId = {InvalidTransactionId}
 
static int nParallelCurrentXids = 0
 
static TransactionIdParallelCurrentXids
 
int MyXactFlags
 
static TransactionStateData TopTransactionStateData
 
static int nUnreportedXids
 
static TransactionId unreportedXids [PGPROC_MAX_CACHED_SUBXIDS]
 
static TransactionState CurrentTransactionState = &TopTransactionStateData
 
static SubTransactionId currentSubTransactionId
 
static CommandId currentCommandId
 
static bool currentCommandIdUsed
 
static TimestampTz xactStartTimestamp
 
static TimestampTz stmtStartTimestamp
 
static TimestampTz xactStopTimestamp
 
static char * prepareGID
 
static bool forceSyncCommit = false
 
bool xact_is_sampled = false
 
static MemoryContext TransactionAbortContext = NULL
 
static XactCallbackItemXact_callbacks = NULL
 
static SubXactCallbackItemSubXact_callbacks = NULL
 

Macro Definition Documentation

◆ SerializedTransactionStateHeaderSize

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)

Definition at line 238 of file xact.c.

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

typedef enum TBlockState TBlockState

◆ TransactionState

Definition at line 220 of file xact.c.

◆ TransactionStateData

◆ TransState

typedef enum TransState TransState

◆ XactCallbackItem

Enumeration Type Documentation

◆ TBlockState

Enumerator
TBLOCK_DEFAULT 
TBLOCK_STARTED 
TBLOCK_BEGIN 
TBLOCK_INPROGRESS 
TBLOCK_IMPLICIT_INPROGRESS 
TBLOCK_PARALLEL_INPROGRESS 
TBLOCK_END 
TBLOCK_ABORT 
TBLOCK_ABORT_END 
TBLOCK_ABORT_PENDING 
TBLOCK_PREPARE 
TBLOCK_SUBBEGIN 
TBLOCK_SUBINPROGRESS 
TBLOCK_SUBRELEASE 
TBLOCK_SUBCOMMIT 
TBLOCK_SUBABORT 
TBLOCK_SUBABORT_END 
TBLOCK_SUBABORT_PENDING 
TBLOCK_SUBRESTART 
TBLOCK_SUBABORT_RESTART 

Definition at line 156 of file xact.c.

157 {
158  /* not-in-transaction-block states */
159  TBLOCK_DEFAULT, /* idle */
160  TBLOCK_STARTED, /* running single-query transaction */
161 
162  /* transaction block states */
163  TBLOCK_BEGIN, /* starting transaction block */
164  TBLOCK_INPROGRESS, /* live transaction */
165  TBLOCK_IMPLICIT_INPROGRESS, /* live transaction after implicit BEGIN */
166  TBLOCK_PARALLEL_INPROGRESS, /* live transaction inside parallel worker */
167  TBLOCK_END, /* COMMIT received */
168  TBLOCK_ABORT, /* failed xact, awaiting ROLLBACK */
169  TBLOCK_ABORT_END, /* failed xact, ROLLBACK received */
170  TBLOCK_ABORT_PENDING, /* live xact, ROLLBACK received */
171  TBLOCK_PREPARE, /* live xact, PREPARE received */
172 
173  /* subtransaction states */
174  TBLOCK_SUBBEGIN, /* starting a subtransaction */
175  TBLOCK_SUBINPROGRESS, /* live subtransaction */
176  TBLOCK_SUBRELEASE, /* RELEASE received */
177  TBLOCK_SUBCOMMIT, /* COMMIT received while TBLOCK_SUBINPROGRESS */
178  TBLOCK_SUBABORT, /* failed subxact, awaiting ROLLBACK */
179  TBLOCK_SUBABORT_END, /* failed subxact, ROLLBACK received */
180  TBLOCK_SUBABORT_PENDING, /* live subxact, ROLLBACK received */
181  TBLOCK_SUBRESTART, /* live subxact, ROLLBACK TO received */
182  TBLOCK_SUBABORT_RESTART, /* failed subxact, ROLLBACK TO received */
183 } TBlockState;
TBlockState
Definition: xact.c:157
@ TBLOCK_DEFAULT
Definition: xact.c:159
@ TBLOCK_SUBABORT_END
Definition: xact.c:179
@ TBLOCK_STARTED
Definition: xact.c:160
@ TBLOCK_SUBCOMMIT
Definition: xact.c:177
@ TBLOCK_IMPLICIT_INPROGRESS
Definition: xact.c:165
@ TBLOCK_ABORT_END
Definition: xact.c:169
@ TBLOCK_PREPARE
Definition: xact.c:171
@ TBLOCK_ABORT_PENDING
Definition: xact.c:170
@ TBLOCK_ABORT
Definition: xact.c:168
@ TBLOCK_SUBRELEASE
Definition: xact.c:176
@ TBLOCK_SUBBEGIN
Definition: xact.c:174
@ TBLOCK_SUBABORT
Definition: xact.c:178
@ TBLOCK_SUBRESTART
Definition: xact.c:181
@ TBLOCK_INPROGRESS
Definition: xact.c:164
@ TBLOCK_END
Definition: xact.c:167
@ TBLOCK_PARALLEL_INPROGRESS
Definition: xact.c:166
@ TBLOCK_SUBABORT_RESTART
Definition: xact.c:182
@ TBLOCK_SUBABORT_PENDING
Definition: xact.c:180
@ TBLOCK_BEGIN
Definition: xact.c:163
@ TBLOCK_SUBINPROGRESS
Definition: xact.c:175

◆ TransState

enum TransState
Enumerator
TRANS_DEFAULT 
TRANS_START 
TRANS_INPROGRESS 
TRANS_COMMIT 
TRANS_ABORT 
TRANS_PREPARE 

Definition at line 140 of file xact.c.

141 {
142  TRANS_DEFAULT, /* idle */
143  TRANS_START, /* transaction starting */
144  TRANS_INPROGRESS, /* inside a valid transaction */
145  TRANS_COMMIT, /* commit in progress */
146  TRANS_ABORT, /* abort in progress */
147  TRANS_PREPARE, /* prepare in progress */
148 } TransState;
TransState
Definition: xact.c:141
@ TRANS_INPROGRESS
Definition: xact.c:144
@ TRANS_START
Definition: xact.c:143
@ TRANS_COMMIT
Definition: xact.c:145
@ TRANS_ABORT
Definition: xact.c:146
@ TRANS_DEFAULT
Definition: xact.c:142
@ TRANS_PREPARE
Definition: xact.c:147

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3431 of file xact.c.

3432 {
3433  /*
3434  * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3435  * done.
3436  */
3438  {
3439  }
3440 }
static bool AbortCurrentTransactionInternal(void)
Definition: xact.c:3449

References AbortCurrentTransactionInternal().

Referenced by _SPI_commit(), _SPI_rollback(), pa_stream_abort(), PostgresMain(), ReorderBufferImmediateInvalidation(), ReorderBufferProcessTXN(), and SnapBuildClearExportedSnapshot().

◆ AbortCurrentTransactionInternal()

static bool AbortCurrentTransactionInternal ( void  )
static

Definition at line 3449 of file xact.c.

3450 {
3452 
3453  switch (s->blockState)
3454  {
3455  case TBLOCK_DEFAULT:
3456  if (s->state == TRANS_DEFAULT)
3457  {
3458  /* we are idle, so nothing to do */
3459  }
3460  else
3461  {
3462  /*
3463  * We can get here after an error during transaction start
3464  * (state will be TRANS_START). Need to clean up the
3465  * incompletely started transaction. First, adjust the
3466  * low-level state to suppress warning message from
3467  * AbortTransaction.
3468  */
3469  if (s->state == TRANS_START)
3470  s->state = TRANS_INPROGRESS;
3471  AbortTransaction();
3473  }
3474  break;
3475 
3476  /*
3477  * If we aren't in a transaction block, we just do the basic abort
3478  * & cleanup transaction. For this purpose, we treat an implicit
3479  * transaction block as if it were a simple statement.
3480  */
3481  case TBLOCK_STARTED:
3483  AbortTransaction();
3486  break;
3487 
3488  /*
3489  * If we are in TBLOCK_BEGIN it means something screwed up right
3490  * after reading "BEGIN TRANSACTION". We assume that the user
3491  * will interpret the error as meaning the BEGIN failed to get him
3492  * into a transaction block, so we should abort and return to idle
3493  * state.
3494  */
3495  case TBLOCK_BEGIN:
3496  AbortTransaction();
3499  break;
3500 
3501  /*
3502  * We are somewhere in a transaction block and we've gotten a
3503  * failure, so we abort the transaction and set up the persistent
3504  * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3505  */
3506  case TBLOCK_INPROGRESS:
3508  AbortTransaction();
3509  s->blockState = TBLOCK_ABORT;
3510  /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3511  break;
3512 
3513  /*
3514  * Here, we failed while trying to COMMIT. Clean up the
3515  * transaction and return to idle state (we do not want to stay in
3516  * the transaction).
3517  */
3518  case TBLOCK_END:
3519  AbortTransaction();
3522  break;
3523 
3524  /*
3525  * Here, we are already in an aborted transaction state and are
3526  * waiting for a ROLLBACK, but for some reason we failed again! So
3527  * we just remain in the abort state.
3528  */
3529  case TBLOCK_ABORT:
3530  case TBLOCK_SUBABORT:
3531  break;
3532 
3533  /*
3534  * We are in a failed transaction and we got the ROLLBACK command.
3535  * We have already aborted, we just need to cleanup and go to idle
3536  * state.
3537  */
3538  case TBLOCK_ABORT_END:
3541  break;
3542 
3543  /*
3544  * We are in a live transaction and we got a ROLLBACK command.
3545  * Abort, cleanup, go to idle state.
3546  */
3547  case TBLOCK_ABORT_PENDING:
3548  AbortTransaction();
3551  break;
3552 
3553  /*
3554  * Here, we failed while trying to PREPARE. Clean up the
3555  * transaction and return to idle state (we do not want to stay in
3556  * the transaction).
3557  */
3558  case TBLOCK_PREPARE:
3559  AbortTransaction();
3562  break;
3563 
3564  /*
3565  * We got an error inside a subtransaction. Abort just the
3566  * subtransaction, and go to the persistent SUBABORT state until
3567  * we get ROLLBACK.
3568  */
3569  case TBLOCK_SUBINPROGRESS:
3572  break;
3573 
3574  /*
3575  * If we failed while trying to create a subtransaction, clean up
3576  * the broken subtransaction and abort the parent. The same
3577  * applies if we get a failure while ending a subtransaction. As
3578  * we need to abort the parent, return false to request the caller
3579  * to do the next iteration.
3580  */
3581  case TBLOCK_SUBBEGIN:
3582  case TBLOCK_SUBRELEASE:
3583  case TBLOCK_SUBCOMMIT:
3585  case TBLOCK_SUBRESTART:
3588  return false;
3589 
3590  /*
3591  * Same as above, except the Abort() was already done.
3592  */
3593  case TBLOCK_SUBABORT_END:
3596  return false;
3597  }
3598 
3599  /* Done, no more iterations required */
3600  return true;
3601 }
TransState state
Definition: xact.c:198
TBlockState blockState
Definition: xact.c:199
static void CleanupSubTransaction(void)
Definition: xact.c:5370
static void CleanupTransaction(void)
Definition: xact.c:2989
static void AbortSubTransaction(void)
Definition: xact.c:5211
static void AbortTransaction(void)
Definition: xact.c:2788
static TransactionState CurrentTransactionState
Definition: xact.c:259

References AbortSubTransaction(), AbortTransaction(), TransactionStateData::blockState, CleanupSubTransaction(), CleanupTransaction(), CurrentTransactionState, TransactionStateData::state, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, TRANS_DEFAULT, TRANS_INPROGRESS, and TRANS_START.

Referenced by AbortCurrentTransaction().

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4855 of file xact.c.

4856 {
4858 
4859  /* Ensure we're not running in a doomed memory context */
4860  AtAbort_Memory();
4861 
4862  /*
4863  * Get out of any transaction or nested transaction
4864  */
4865  do
4866  {
4867  switch (s->blockState)
4868  {
4869  case TBLOCK_DEFAULT:
4870  if (s->state == TRANS_DEFAULT)
4871  {
4872  /* Not in a transaction, do nothing */
4873  }
4874  else
4875  {
4876  /*
4877  * We can get here after an error during transaction start
4878  * (state will be TRANS_START). Need to clean up the
4879  * incompletely started transaction. First, adjust the
4880  * low-level state to suppress warning message from
4881  * AbortTransaction.
4882  */
4883  if (s->state == TRANS_START)
4884  s->state = TRANS_INPROGRESS;
4885  AbortTransaction();
4887  }
4888  break;
4889  case TBLOCK_STARTED:
4890  case TBLOCK_BEGIN:
4891  case TBLOCK_INPROGRESS:
4894  case TBLOCK_END:
4895  case TBLOCK_ABORT_PENDING:
4896  case TBLOCK_PREPARE:
4897  /* In a transaction, so clean up */
4898  AbortTransaction();
4901  break;
4902  case TBLOCK_ABORT:
4903  case TBLOCK_ABORT_END:
4904 
4905  /*
4906  * AbortTransaction is already done, still need Cleanup.
4907  * However, if we failed partway through running ROLLBACK,
4908  * there will be an active portal running that command, which
4909  * we need to shut down before doing CleanupTransaction.
4910  */
4911  AtAbort_Portals();
4914  break;
4915 
4916  /*
4917  * In a subtransaction, so clean it up and abort parent too
4918  */
4919  case TBLOCK_SUBBEGIN:
4920  case TBLOCK_SUBINPROGRESS:
4921  case TBLOCK_SUBRELEASE:
4922  case TBLOCK_SUBCOMMIT:
4924  case TBLOCK_SUBRESTART:
4927  s = CurrentTransactionState; /* changed by pop */
4928  break;
4929 
4930  case TBLOCK_SUBABORT:
4931  case TBLOCK_SUBABORT_END:
4933  /* As above, but AbortSubTransaction already done */
4934  if (s->curTransactionOwner)
4935  {
4936  /* As in TBLOCK_ABORT, might have a live portal to zap */
4941  }
4943  s = CurrentTransactionState; /* changed by pop */
4944  break;
4945  }
4946  } while (s->blockState != TBLOCK_DEFAULT);
4947 
4948  /* Should be out of all subxacts now */
4949  Assert(s->parent == NULL);
4950 
4951  /*
4952  * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4953  * whether there were any transactions to close or not. (Callers that
4954  * don't intend to exit soon should switch to some other context to avoid
4955  * long-term memory leaks.)
4956  */
4958 }
#define Assert(condition)
Definition: c.h:849
MemoryContext TopMemoryContext
Definition: mcxt.c:149
void AtAbort_Portals(void)
Definition: portalmem.c:781
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:979
MemoryContextSwitchTo(old_ctx)
SubTransactionId subTransactionId
Definition: xact.c:195
struct TransactionStateData * parent
Definition: xact.c:217
ResourceOwner curTransactionOwner
Definition: xact.c:203
static void AtAbort_Memory(void)
Definition: xact.c:1873

References AbortSubTransaction(), AbortTransaction(), Assert, AtAbort_Memory(), AtAbort_Portals(), AtSubAbort_Portals(), TransactionStateData::blockState, CleanupSubTransaction(), CleanupTransaction(), CurrentTransactionState, TransactionStateData::curTransactionOwner, MemoryContextSwitchTo(), TransactionStateData::parent, TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, TopMemoryContext, TRANS_DEFAULT, TRANS_INPROGRESS, and TRANS_START.

Referenced by DisableSubscriptionAndExit(), do_autovacuum(), perform_work_item(), RemoveTempRelationsCallback(), ShutdownPostgres(), start_apply(), and start_table_sync().

◆ AbortSubTransaction()

static void AbortSubTransaction ( void  )
static

Definition at line 5211 of file xact.c.

5212 {
5214 
5215  /* Prevent cancel/die interrupt while cleaning up */
5216  HOLD_INTERRUPTS();
5217 
5218  /* Make sure we have a valid memory context and resource owner */
5221 
5222  /*
5223  * Release any LW locks we might be holding as quickly as possible.
5224  * (Regular locks, however, must be held till we finish aborting.)
5225  * Releasing LW locks is critical since we might try to grab them again
5226  * while cleaning up!
5227  *
5228  * FIXME This may be incorrect --- Are there some locks we should keep?
5229  * Buffer locks, for example? I don't think so but I'm not sure.
5230  */
5231  LWLockReleaseAll();
5232 
5235  UnlockBuffers();
5236 
5237  /* Reset WAL record construction state */
5239 
5240  /* Cancel condition variable sleep */
5242 
5243  /*
5244  * Also clean up any open wait for lock, since the lock manager will choke
5245  * if we try to wait for another lock before doing this.
5246  */
5247  LockErrorCleanup();
5248 
5249  /*
5250  * If any timeout events are still active, make sure the timeout interrupt
5251  * is scheduled. This covers possible loss of a timeout interrupt due to
5252  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5253  * We delay this till after LockErrorCleanup so that we don't uselessly
5254  * reschedule lock or deadlock check timeouts.
5255  */
5257 
5258  /*
5259  * Re-enable signals, in case we got here by longjmp'ing out of a signal
5260  * handler. We do this fairly early in the sequence so that the timeout
5261  * infrastructure will be functional if needed while aborting.
5262  */
5263  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5264 
5265  /*
5266  * check the current transaction state
5267  */
5268  ShowTransactionState("AbortSubTransaction");
5269 
5270  if (s->state != TRANS_INPROGRESS)
5271  elog(WARNING, "AbortSubTransaction while in %s state",
5273 
5274  s->state = TRANS_ABORT;
5275 
5276  /*
5277  * Reset user ID which might have been changed transiently. (See notes in
5278  * AbortTransaction.)
5279  */
5281 
5282  /* Forget about any active REINDEX. */
5284 
5285  /* Reset logical streaming state. */
5287 
5288  /*
5289  * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5290  * exports are not supported in subtransactions.
5291  */
5292 
5293  /*
5294  * If this subxact has started any unfinished parallel operation, clean up
5295  * its workers and exit parallel mode. Don't warn about leaked resources.
5296  */
5298  s->parallelModeLevel = 0;
5299 
5300  /*
5301  * We can skip all this stuff if the subxact failed before creating a
5302  * ResourceOwner...
5303  */
5304  if (s->curTransactionOwner)
5305  {
5306  AfterTriggerEndSubXact(false);
5312  s->parent->subTransactionId);
5314 
5315  /* Advertise the fact that we aborted in pg_xact. */
5316  (void) RecordTransactionAbort(true);
5317 
5318  /* Post-abort cleanup */
5321 
5323  s->parent->subTransactionId);
5324 
5327  false, false);
5328 
5330  s->parent->subTransactionId);
5331  AtEOSubXact_Inval(false);
5334  false, false);
5337  false, false);
5338  AtSubAbort_smgr();
5339 
5340  AtEOXact_GUC(false, s->gucNestLevel);
5341  AtEOSubXact_SPI(false, s->subTransactionId);
5343  s->parent->subTransactionId);
5345  s->parent->subTransactionId);
5347  s->parent->subTransactionId);
5349  AtEOSubXact_PgStat(false, s->nestingLevel);
5351  }
5352 
5353  /*
5354  * Restore the upper transaction's read-only state, too. This should be
5355  * redundant with GUC's cleanup but we may as well do it for consistency
5356  * with the commit case.
5357  */
5359 
5361 }
void AtSubAbort_Notify(void)
Definition: async.c:1761
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition: parallel.c:1233
sigset_t UnBlockSig
Definition: pqsignal.c:22
void pgstat_progress_end_command(void)
void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: be-fsstubs.c:648
void UnlockBuffers(void)
Definition: bufmgr.c:5130
bool ConditionVariableCancelSleep(void)
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1938
#define WARNING
Definition: elog.h:36
#define elog(elevel,...)
Definition: elog.h:225
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:3155
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2261
void ResetReindexState(int nestLevel)
Definition: index.c:4164
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1082
void ResetLogicalStreamingState(void)
Definition: logical.c:1922
void LWLockReleaseAll(void)
Definition: lwlock.c:1876
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:135
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:133
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:642
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: namespace.c:4558
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:113
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3387
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:648
@ RESOURCE_RELEASE_LOCKS
Definition: resowner.h:55
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:54
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56
void AtSubAbort_Snapshot(int level)
Definition: snapmgr.c:959
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition: spi.c:482
void LockErrorCleanup(void)
Definition: proc.c:777
void AtSubAbort_smgr(void)
Definition: storage.c:934
int parallelModeLevel
Definition: xact.c:213
FullTransactionId fullTransactionId
Definition: xact.c:194
bool prevXactReadOnly
Definition: xact.c:210
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:17804
void reschedule_timeouts(void)
Definition: timeout.c:540
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5355
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3891
static void AtSubAbort_Memory(void)
Definition: xact.c:1893
static const char * TransStateAsString(TransState state)
Definition: xact.c:5747
bool XactReadOnly
Definition: xact.c:81
static void AtSubAbort_childXids(void)
Definition: xact.c:1931
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1918
static void ShowTransactionState(const char *str)
Definition: xact.c:5635
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1743
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:144
void XLogResetInsertion(void)
Definition: xloginsert.c:222

References AfterTriggerEndSubXact(), AtEOSubXact_Files(), AtEOSubXact_HashTables(), AtEOSubXact_Inval(), AtEOSubXact_LargeObject(), AtEOSubXact_Namespace(), AtEOSubXact_on_commit_actions(), AtEOSubXact_Parallel(), AtEOSubXact_PgStat(), AtEOSubXact_RelationCache(), AtEOSubXact_SPI(), AtEOXact_GUC(), AtSubAbort_childXids(), AtSubAbort_Memory(), AtSubAbort_Notify(), AtSubAbort_Portals(), AtSubAbort_ResourceOwner(), AtSubAbort_smgr(), AtSubAbort_Snapshot(), CallSubXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, TransactionStateData::curTransactionOwner, elog, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, LockErrorCleanup(), LWLockReleaseAll(), TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pgstat_progress_end_command(), pgstat_report_wait_end(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, TransactionStateData::prevXactReadOnly, RecordTransactionAbort(), reschedule_timeouts(), ResetLogicalStreamingState(), ResetReindexState(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), RESUME_INTERRUPTS, SetUserIdAndSecContext(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_ABORT_SUB, TRANS_ABORT, TRANS_INPROGRESS, TransStateAsString(), UnBlockSig, UnlockBuffers(), WARNING, XactReadOnly, and XLogResetInsertion().

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), CommitTransactionCommandInternal(), and RollbackAndReleaseCurrentSubTransaction().

◆ AbortTransaction()

static void AbortTransaction ( void  )
static

Definition at line 2788 of file xact.c.

2789 {
2791  TransactionId latestXid;
2792  bool is_parallel_worker;
2793 
2794  /* Prevent cancel/die interrupt while cleaning up */
2795  HOLD_INTERRUPTS();
2796 
2797  /* Disable transaction timeout */
2798  if (TransactionTimeout > 0)
2800 
2801  /* Make sure we have a valid memory context and resource owner */
2802  AtAbort_Memory();
2804 
2805  /*
2806  * Release any LW locks we might be holding as quickly as possible.
2807  * (Regular locks, however, must be held till we finish aborting.)
2808  * Releasing LW locks is critical since we might try to grab them again
2809  * while cleaning up!
2810  */
2811  LWLockReleaseAll();
2812 
2813  /*
2814  * Cleanup waiting for LSN if any.
2815  */
2816  WaitLSNCleanup();
2817 
2818  /* Clear wait information and command progress indicator */
2821 
2822  /* Clean up buffer context locks, too */
2823  UnlockBuffers();
2824 
2825  /* Reset WAL record construction state */
2827 
2828  /* Cancel condition variable sleep */
2830 
2831  /*
2832  * Also clean up any open wait for lock, since the lock manager will choke
2833  * if we try to wait for another lock before doing this.
2834  */
2835  LockErrorCleanup();
2836 
2837  /*
2838  * If any timeout events are still active, make sure the timeout interrupt
2839  * is scheduled. This covers possible loss of a timeout interrupt due to
2840  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2841  * We delay this till after LockErrorCleanup so that we don't uselessly
2842  * reschedule lock or deadlock check timeouts.
2843  */
2845 
2846  /*
2847  * Re-enable signals, in case we got here by longjmp'ing out of a signal
2848  * handler. We do this fairly early in the sequence so that the timeout
2849  * infrastructure will be functional if needed while aborting.
2850  */
2851  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2852 
2853  /*
2854  * check the current transaction state
2855  */
2856  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2857  if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2858  elog(WARNING, "AbortTransaction while in %s state",
2860  Assert(s->parent == NULL);
2861 
2862  /*
2863  * set the current transaction state information appropriately during the
2864  * abort processing
2865  */
2866  s->state = TRANS_ABORT;
2867 
2868  /*
2869  * Reset user ID which might have been changed transiently. We need this
2870  * to clean up in case control escaped out of a SECURITY DEFINER function
2871  * or other local change of CurrentUserId; therefore, the prior value of
2872  * SecurityRestrictionContext also needs to be restored.
2873  *
2874  * (Note: it is not necessary to restore session authorization or role
2875  * settings here because those can only be changed via GUC, and GUC will
2876  * take care of rolling them back if need be.)
2877  */
2879 
2880  /* Forget about any active REINDEX. */
2882 
2883  /* Reset logical streaming state. */
2885 
2886  /* Reset snapshot export state. */
2888 
2889  /*
2890  * If this xact has started any unfinished parallel operation, clean up
2891  * its workers and exit parallel mode. Don't warn about leaked resources.
2892  */
2893  AtEOXact_Parallel(false);
2894  s->parallelModeLevel = 0;
2895  s->parallelChildXact = false; /* should be false already */
2896 
2897  /*
2898  * do abort processing
2899  */
2900  AfterTriggerEndXact(false); /* 'false' means it's abort */
2901  AtAbort_Portals();
2902  smgrDoPendingSyncs(false, is_parallel_worker);
2903  AtEOXact_LargeObject(false);
2904  AtAbort_Notify();
2905  AtEOXact_RelationMap(false, is_parallel_worker);
2906  AtAbort_Twophase();
2907 
2908  /*
2909  * Advertise the fact that we aborted in pg_xact (assuming that we got as
2910  * far as assigning an XID to advertise). But if we're inside a parallel
2911  * worker, skip this; the user backend must be the one to write the abort
2912  * record.
2913  */
2914  if (!is_parallel_worker)
2915  latestXid = RecordTransactionAbort(false);
2916  else
2917  {
2918  latestXid = InvalidTransactionId;
2919 
2920  /*
2921  * Since the parallel leader won't get our value of XactLastRecEnd in
2922  * this case, we nudge WAL-writer ourselves in this case. See related
2923  * comments in RecordTransactionAbort for why this matters.
2924  */
2926  }
2927 
2928  TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2929 
2930  /*
2931  * Let others know about no transaction in progress by me. Note that this
2932  * must be done _before_ releasing locks we hold and _after_
2933  * RecordTransactionAbort.
2934  */
2935  ProcArrayEndTransaction(MyProc, latestXid);
2936 
2937  /*
2938  * Post-abort cleanup. See notes in CommitTransaction() concerning
2939  * ordering. We can skip all of it if the transaction failed before
2940  * creating a resource owner.
2941  */
2942  if (TopTransactionResourceOwner != NULL)
2943  {
2944  if (is_parallel_worker)
2946  else
2948 
2951  false, true);
2952  AtEOXact_Buffers(false);
2953  AtEOXact_RelationCache(false);
2954  AtEOXact_Inval(false);
2958  false, true);
2961  false, true);
2962  smgrDoPendingDeletes(false);
2963 
2964  AtEOXact_GUC(false, 1);
2965  AtEOXact_SPI(false);
2966  AtEOXact_Enum();
2968  AtEOXact_Namespace(false, is_parallel_worker);
2969  AtEOXact_SMgr();
2970  AtEOXact_Files(false);
2972  AtEOXact_HashTables(false);
2973  AtEOXact_PgStat(false, is_parallel_worker);
2974  AtEOXact_ApplyLauncher(false);
2977  }
2978 
2979  /*
2980  * State remains TRANS_ABORT until CleanupTransaction().
2981  */
2983 }
void AtAbort_Notify(void)
Definition: async.c:1671
void AtEOXact_Parallel(bool isCommit)
Definition: parallel.c:1254
void AtEOXact_LogicalRepWorkers(bool isCommit)
Definition: worker.c:5113
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition: be-fsstubs.c:602
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:3559
uint32 TransactionId
Definition: c.h:643
void AtEOXact_ComboCid(void)
Definition: combocid.c:182
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1912
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3188
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1025
void AtEOXact_ApplyLauncher(bool isCommit)
Definition: launcher.c:1092
void AtEOXact_MultiXact(void)
Definition: multixact.c:1808
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition: namespace.c:4512
void AtEOXact_Enum(void)
Definition: pg_enum.c:726
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition: pgstat_xact.c:40
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:667
void AtEOXact_RelationCache(bool isCommit)
Definition: relcache.c:3235
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition: relmapper.c:541
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:167
void AtEOXact_SMgr(void)
Definition: smgr.c:829
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:627
void AtEOXact_SPI(bool isCommit)
Definition: spi.c:428
PGPROC * MyProc
Definition: proc.c:67
int TransactionTimeout
Definition: proc.c:62
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:700
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:632
LocalTransactionId lxid
Definition: proc.h:200
struct PGPROC::@119 vxid
bool parallelChildXact
Definition: xact.c:214
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:17772
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:685
@ TRANSACTION_TIMEOUT
Definition: timeout.h:34
#define InvalidTransactionId
Definition: transam.h:31
void AfterTriggerEndXact(bool isCommit)
Definition: trigger.c:5259
void AtAbort_Twophase(void)
Definition: twophase.c:304
void WaitLSNCleanup(void)
Definition: waitlsn.c:204
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1905
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3831
@ XACT_EVENT_ABORT
Definition: xact.h:130
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:131
XLogRecPtr XactLastRecEnd
Definition: xlog.c:253
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2630

References AfterTriggerEndXact(), Assert, AtAbort_Memory(), AtAbort_Notify(), AtAbort_Portals(), AtAbort_ResourceOwner(), AtAbort_Twophase(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_Inval(), AtEOXact_LargeObject(), AtEOXact_LogicalRepWorkers(), AtEOXact_MultiXact(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_Parallel(), AtEOXact_PgStat(), AtEOXact_RelationCache(), AtEOXact_RelationMap(), AtEOXact_SMgr(), AtEOXact_SPI(), TransactionStateData::blockState, CallXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, disable_timeout(), elog, HOLD_INTERRUPTS, InvalidTransactionId, LockErrorCleanup(), LWLockReleaseAll(), PGPROC::lxid, MyProc, TransactionStateData::nestingLevel, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pgstat_progress_end_command(), pgstat_report_wait_end(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, ProcArrayEndTransaction(), RecordTransactionAbort(), reschedule_timeouts(), ResetLogicalStreamingState(), ResetReindexState(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), RESUME_INTERRUPTS, SetUserIdAndSecContext(), smgrDoPendingDeletes(), smgrDoPendingSyncs(), SnapBuildResetExportedSnapshotState(), TransactionStateData::state, TBLOCK_PARALLEL_INPROGRESS, TopTransactionResourceOwner, TRANS_ABORT, TRANS_INPROGRESS, TRANS_PREPARE, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), UnBlockSig, UnlockBuffers(), PGPROC::vxid, WaitLSNCleanup(), WARNING, XACT_EVENT_ABORT, XACT_EVENT_PARALLEL_ABORT, XactLastRecEnd, XLogResetInsertion(), and XLogSetAsyncXactLSN().

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), and CommitTransactionCommandInternal().

◆ AssignTransactionId()

static void AssignTransactionId ( TransactionState  s)
static

Definition at line 634 of file xact.c.

635 {
636  bool isSubXact = (s->parent != NULL);
637  ResourceOwner currentOwner;
638  bool log_unknown_top = false;
639 
640  /* Assert that caller didn't screw up */
643 
644  /*
645  * Workers synchronize transaction state at the beginning of each parallel
646  * operation, so we can't account for new XIDs at this point.
647  */
649  ereport(ERROR,
650  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
651  errmsg("cannot assign transaction IDs during a parallel operation")));
652 
653  /*
654  * Ensure parent(s) have XIDs, so that a child always has an XID later
655  * than its parent. Mustn't recurse here, or we might get a stack
656  * overflow if we're at the bottom of a huge stack of subtransactions none
657  * of which have XIDs yet.
658  */
659  if (isSubXact && !FullTransactionIdIsValid(s->parent->fullTransactionId))
660  {
661  TransactionState p = s->parent;
662  TransactionState *parents;
663  size_t parentOffset = 0;
664 
665  parents = palloc(sizeof(TransactionState) * s->nestingLevel);
666  while (p != NULL && !FullTransactionIdIsValid(p->fullTransactionId))
667  {
668  parents[parentOffset++] = p;
669  p = p->parent;
670  }
671 
672  /*
673  * This is technically a recursive call, but the recursion will never
674  * be more than one layer deep.
675  */
676  while (parentOffset != 0)
677  AssignTransactionId(parents[--parentOffset]);
678 
679  pfree(parents);
680  }
681 
682  /*
683  * When wal_level=logical, guarantee that a subtransaction's xid can only
684  * be seen in the WAL stream if its toplevel xid has been logged before.
685  * If necessary we log an xact_assignment record with fewer than
686  * PGPROC_MAX_CACHED_SUBXIDS. Note that it is fine if didLogXid isn't set
687  * for a transaction even though it appears in a WAL record, we just might
688  * superfluously log something. That can happen when an xid is included
689  * somewhere inside a wal record, but not in XLogRecord->xl_xid, like in
690  * xl_standby_locks.
691  */
692  if (isSubXact && XLogLogicalInfoActive() &&
694  log_unknown_top = true;
695 
696  /*
697  * Generate a new FullTransactionId and record its xid in PGPROC and
698  * pg_subtrans.
699  *
700  * NB: we must make the subtrans entry BEFORE the Xid appears anywhere in
701  * shared storage other than PGPROC; because if there's no room for it in
702  * PGPROC, the subtrans entry is needed to ensure that other backends see
703  * the Xid as "running". See GetNewTransactionId.
704  */
705  s->fullTransactionId = GetNewTransactionId(isSubXact);
706  if (!isSubXact)
708 
709  if (isSubXact)
712 
713  /*
714  * If it's a top-level transaction, the predicate locking system needs to
715  * be told about it too.
716  */
717  if (!isSubXact)
719 
720  /*
721  * Acquire lock on the transaction XID. (We assume this cannot block.) We
722  * have to ensure that the lock is assigned to the transaction's own
723  * ResourceOwner.
724  */
725  currentOwner = CurrentResourceOwner;
727 
729 
730  CurrentResourceOwner = currentOwner;
731 
732  /*
733  * Every PGPROC_MAX_CACHED_SUBXIDS assigned transaction ids within each
734  * top-level transaction we issue a WAL record for the assignment. We
735  * include the top-level xid and all the subxids that have not yet been
736  * reported using XLOG_XACT_ASSIGNMENT records.
737  *
738  * This is required to limit the amount of shared memory required in a hot
739  * standby server to keep track of in-progress XIDs. See notes for
740  * RecordKnownAssignedTransactionIds().
741  *
742  * We don't keep track of the immediate parent of each subxid, only the
743  * top-level transaction that each subxact belongs to. This is correct in
744  * recovery only because aborted subtransactions are separately WAL
745  * logged.
746  *
747  * This is correct even for the case where several levels above us didn't
748  * have an xid assigned as we recursed up to them beforehand.
749  */
750  if (isSubXact && XLogStandbyInfoActive())
751  {
753  nUnreportedXids++;
754 
755  /*
756  * ensure this test matches similar one in
757  * RecoverPreparedTransactions()
758  */
760  log_unknown_top)
761  {
762  xl_xact_assignment xlrec;
763 
764  /*
765  * xtop is always set by now because we recurse up transaction
766  * stack to the highest unassigned xid and then come back down
767  */
768  xlrec.xtop = GetTopTransactionId();
770  xlrec.nsubxacts = nUnreportedXids;
771 
772  XLogBeginInsert();
773  XLogRegisterData((char *) &xlrec, MinSizeOfXactAssignment);
775  nUnreportedXids * sizeof(TransactionId));
776 
777  (void) XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT);
778 
779  nUnreportedXids = 0;
780  /* mark top, not current xact as having been logged */
782  }
783  }
784 }
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
#define IsParallelWorker()
Definition: parallel.h:60
void XactLockTableInsert(TransactionId xid)
Definition: lmgr.c:616
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc(Size size)
Definition: mcxt.c:1317
void RegisterPredicateLockingXid(TransactionId xid)
Definition: predicate.c:1949
#define PGPROC_MAX_CACHED_SUBXIDS
Definition: proc.h:39
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
TransactionId xtop
Definition: xact.h:220
void SubTransSetParent(TransactionId xid, TransactionId parent)
Definition: subtrans.c:85
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define TransactionIdIsValid(xid)
Definition: transam.h:41
FullTransactionId GetNewTransactionId(bool isSubXact)
Definition: varsup.c:77
TransactionId GetTopTransactionId(void)
Definition: xact.c:425
static TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
Definition: xact.c:257
static int nUnreportedXids
Definition: xact.c:256
static void AssignTransactionId(TransactionState s)
Definition: xact.c:634
static TransactionStateData TopTransactionStateData
Definition: xact.c:246
static FullTransactionId XactTopFullTransactionId
Definition: xact.c:124
bool IsInParallelMode(void)
Definition: xact.c:1088
#define MinSizeOfXactAssignment
Definition: xact.h:225
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:174
#define XLogLogicalInfoActive()
Definition: xlog.h:126
#define XLogStandbyInfoActive()
Definition: xlog.h:123
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogRegisterData(const char *data, uint32 len)
Definition: xloginsert.c:364
void XLogBeginInsert(void)
Definition: xloginsert.c:149

References Assert, CurrentResourceOwner, TransactionStateData::curTransactionOwner, TransactionStateData::didLogXid, ereport, errcode(), errmsg(), ERROR, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetNewTransactionId(), GetTopTransactionId(), IsInParallelMode(), IsParallelWorker, MinSizeOfXactAssignment, TransactionStateData::nestingLevel, xl_xact_assignment::nsubxacts, nUnreportedXids, palloc(), TransactionStateData::parent, pfree(), PGPROC_MAX_CACHED_SUBXIDS, RegisterPredicateLockingXid(), TransactionStateData::state, SubTransSetParent(), TopTransactionStateData, TRANS_INPROGRESS, TransactionIdIsValid, unreportedXids, XactLockTableInsert(), XactTopFullTransactionId, XidFromFullTransactionId, XLOG_XACT_ASSIGNMENT, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogStandbyInfoActive, and xl_xact_assignment::xtop.

Referenced by GetCurrentFullTransactionId(), GetCurrentTransactionId(), GetTopFullTransactionId(), and GetTopTransactionId().

◆ AtAbort_Memory()

static void AtAbort_Memory ( void  )
static

Definition at line 1873 of file xact.c.

1874 {
1875  /*
1876  * Switch into TransactionAbortContext, which should have some free space
1877  * even if nothing else does. We'll work in this context until we've
1878  * finished cleaning up.
1879  *
1880  * It is barely possible to get here when we've not been able to create
1881  * TransactionAbortContext yet; if so use TopMemoryContext.
1882  */
1883  if (TransactionAbortContext != NULL)
1885  else
1887 }
static MemoryContext TransactionAbortContext
Definition: xact.c:302

References MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1905 of file xact.c.

1906 {
1907  /*
1908  * Make sure we have a valid ResourceOwner, if possible (else it will be
1909  * NULL, which is OK)
1910  */
1912 }

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1568 of file xact.c.

1569 {
1570  /*
1571  * Make any pending relation map changes visible. We must do this before
1572  * processing local sinval messages, so that the map changes will get
1573  * reflected into the relcache when relcache invals are processed.
1574  */
1576 
1577  /*
1578  * Make catalog changes visible to me for the next command.
1579  */
1581 }
void CommandEndInvalidationMessages(void)
Definition: inval.c:1170
void AtCCI_RelationMap(void)
Definition: relmapper.c:504

References AtCCI_RelationMap(), and CommandEndInvalidationMessages().

Referenced by CommandCounterIncrement().

◆ AtCleanup_Memory()

static void AtCleanup_Memory ( void  )
static

Definition at line 1963 of file xact.c.

1964 {
1966 
1967  /* Should be at top level */
1968  Assert(s->parent == NULL);
1969 
1970  /*
1971  * Return to the memory context that was current before we started the
1972  * transaction. (In principle, this could not be any of the contexts we
1973  * are about to delete. If it somehow is, assertions in mcxt.c will
1974  * complain.)
1975  */
1977 
1978  /*
1979  * Clear the special abort context for next time.
1980  */
1981  if (TransactionAbortContext != NULL)
1983 
1984  /*
1985  * Release all transaction-local memory, the same as in AtCommit_Memory,
1986  * except we must cope with the possibility that we didn't get as far as
1987  * creating TopTransactionContext.
1988  */
1989  if (TopTransactionContext != NULL)
1991 
1992  /*
1993  * Clear these pointers as a pro-forma matter. (Notionally, while
1994  * TopTransactionContext still exists, it's currently not associated with
1995  * this TransactionState struct.)
1996  */
1997  CurTransactionContext = NULL;
1998  s->curTransactionContext = NULL;
1999 }
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
MemoryContext TopTransactionContext
Definition: mcxt.c:154
MemoryContext CurTransactionContext
Definition: mcxt.c:155
MemoryContext priorContext
Definition: xact.c:204
MemoryContext curTransactionContext
Definition: xact.c:202

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::parent, TransactionStateData::priorContext, TopTransactionContext, and TransactionAbortContext.

Referenced by CleanupTransaction().

◆ AtCommit_Memory()

static void AtCommit_Memory ( void  )
static

Definition at line 1587 of file xact.c.

1588 {
1590 
1591  /*
1592  * Return to the memory context that was current before we started the
1593  * transaction. (In principle, this could not be any of the contexts we
1594  * are about to delete. If it somehow is, assertions in mcxt.c will
1595  * complain.)
1596  */
1598 
1599  /*
1600  * Release all transaction-local memory. TopTransactionContext survives
1601  * but becomes empty; any sub-contexts go away.
1602  */
1603  Assert(TopTransactionContext != NULL);
1605 
1606  /*
1607  * Clear these pointers as a pro-forma matter. (Notionally, while
1608  * TopTransactionContext still exists, it's currently not associated with
1609  * this TransactionState struct.)
1610  */
1611  CurTransactionContext = NULL;
1612  s->curTransactionContext = NULL;
1613 }

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::priorContext, and TopTransactionContext.

Referenced by CommitTransaction(), and PrepareTransaction().

◆ AtStart_Cache()

static void AtStart_Cache ( void  )
static

Definition at line 1166 of file xact.c.

1167 {
1169 }
void AcceptInvalidationMessages(void)
Definition: inval.c:806

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1175 of file xact.c.

1176 {
1178 
1179  /*
1180  * Remember the memory context that was active prior to transaction start.
1181  */
1183 
1184  /*
1185  * If this is the first time through, create a private context for
1186  * AbortTransaction to work in. By reserving some space now, we can
1187  * insulate AbortTransaction from out-of-memory scenarios. Like
1188  * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1189  * size, so that space will be reserved immediately.
1190  */
1191  if (TransactionAbortContext == NULL)
1194  "TransactionAbortContext",
1195  32 * 1024,
1196  32 * 1024,
1197  32 * 1024);
1198 
1199  /*
1200  * Likewise, if this is the first time through, create a top-level context
1201  * for transaction-local data. This context will be reset at transaction
1202  * end, and then re-used in later transactions.
1203  */
1204  if (TopTransactionContext == NULL)
1207  "TopTransactionContext",
1209 
1210  /*
1211  * In a top-level transaction, CurTransactionContext is the same as
1212  * TopTransactionContext.
1213  */
1216 
1217  /* Make the CurTransactionContext active. */
1219 }
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, CurrentMemoryContext, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, MemoryContextSwitchTo(), TransactionStateData::priorContext, TopMemoryContext, TopTransactionContext, and TransactionAbortContext.

Referenced by StartTransaction().

◆ AtStart_ResourceOwner()

static void AtStart_ResourceOwner ( void  )
static

Definition at line 1225 of file xact.c.

1226 {
1228 
1229  /*
1230  * We shouldn't have a transaction resource owner already.
1231  */
1233 
1234  /*
1235  * Create a toplevel resource owner for the transaction.
1236  */
1237  s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1238 
1242 }
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:413
ResourceOwner CurTransactionResourceOwner
Definition: resowner.c:166

References Assert, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, ResourceOwnerCreate(), and TopTransactionResourceOwner.

Referenced by StartTransaction().

◆ AtSubAbort_childXids()

static void AtSubAbort_childXids ( void  )
static

Definition at line 1931 of file xact.c.

1932 {
1934 
1935  /*
1936  * We keep the child-XID arrays in TopTransactionContext (see
1937  * AtSubCommit_childXids). This means we'd better free the array
1938  * explicitly at abort to avoid leakage.
1939  */
1940  if (s->childXids != NULL)
1941  pfree(s->childXids);
1942  s->childXids = NULL;
1943  s->nChildXids = 0;
1944  s->maxChildXids = 0;
1945 
1946  /*
1947  * We could prune the unreportedXids array here. But we don't bother. That
1948  * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1949  * would likely introduce more CPU time into the more common paths, so we
1950  * choose not to do that.
1951  */
1952 }
TransactionId * childXids
Definition: xact.c:205

References TransactionStateData::childXids, CurrentTransactionState, TransactionStateData::maxChildXids, TransactionStateData::nChildXids, and pfree().

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

Definition at line 1893 of file xact.c.

1894 {
1896 
1898 }

References Assert, MemoryContextSwitchTo(), and TransactionAbortContext.

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1918 of file xact.c.

1919 {
1921 
1922  /* Make sure we have a valid ResourceOwner */
1924 }

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 2011 of file xact.c.

2012 {
2014 
2015  Assert(s->parent != NULL);
2016 
2017  /*
2018  * Return to the memory context that was current before we started the
2019  * subtransaction. (In principle, this could not be any of the contexts
2020  * we are about to delete. If it somehow is, assertions in mcxt.c will
2021  * complain.)
2022  */
2024 
2025  /* Update CurTransactionContext (might not be same as priorContext) */
2027 
2028  /*
2029  * Clear the special abort context for next time.
2030  */
2031  if (TransactionAbortContext != NULL)
2033 
2034  /*
2035  * Delete the subxact local memory contexts. Its CurTransactionContext can
2036  * go too (note this also kills CurTransactionContexts from any children
2037  * of the subxact).
2038  */
2039  if (s->curTransactionContext)
2041  s->curTransactionContext = NULL;
2042 }
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:454

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, MemoryContextDelete(), MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::parent, TransactionStateData::priorContext, and TransactionAbortContext.

Referenced by CleanupSubTransaction().

◆ AtSubCommit_childXids()

static void AtSubCommit_childXids ( void  )
static

Definition at line 1653 of file xact.c.

1654 {
1656  int new_nChildXids;
1657 
1658  Assert(s->parent != NULL);
1659 
1660  /*
1661  * The parent childXids array will need to hold my XID and all my
1662  * childXids, in addition to the XIDs already there.
1663  */
1664  new_nChildXids = s->parent->nChildXids + s->nChildXids + 1;
1665 
1666  /* Allocate or enlarge the parent array if necessary */
1667  if (s->parent->maxChildXids < new_nChildXids)
1668  {
1669  int new_maxChildXids;
1670  TransactionId *new_childXids;
1671 
1672  /*
1673  * Make it 2x what's needed right now, to avoid having to enlarge it
1674  * repeatedly. But we can't go above MaxAllocSize. (The latter limit
1675  * is what ensures that we don't need to worry about integer overflow
1676  * here or in the calculation of new_nChildXids.)
1677  */
1678  new_maxChildXids = Min(new_nChildXids * 2,
1679  (int) (MaxAllocSize / sizeof(TransactionId)));
1680 
1681  if (new_maxChildXids < new_nChildXids)
1682  ereport(ERROR,
1683  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1684  errmsg("maximum number of committed subtransactions (%d) exceeded",
1685  (int) (MaxAllocSize / sizeof(TransactionId)))));
1686 
1687  /*
1688  * We keep the child-XID arrays in TopTransactionContext; this avoids
1689  * setting up child-transaction contexts for what might be just a few
1690  * bytes of grandchild XIDs.
1691  */
1692  if (s->parent->childXids == NULL)
1693  new_childXids =
1695  new_maxChildXids * sizeof(TransactionId));
1696  else
1697  new_childXids = repalloc(s->parent->childXids,
1698  new_maxChildXids * sizeof(TransactionId));
1699 
1700  s->parent->childXids = new_childXids;
1701  s->parent->maxChildXids = new_maxChildXids;
1702  }
1703 
1704  /*
1705  * Copy all my XIDs to parent's array.
1706  *
1707  * Note: We rely on the fact that the XID of a child always follows that
1708  * of its parent. By copying the XID of this subtransaction before the
1709  * XIDs of its children, we ensure that the array stays ordered. Likewise,
1710  * all XIDs already in the array belong to subtransactions started and
1711  * subcommitted before us, so their XIDs must precede ours.
1712  */
1714 
1715  if (s->nChildXids > 0)
1716  memcpy(&s->parent->childXids[s->parent->nChildXids + 1],
1717  s->childXids,
1718  s->nChildXids * sizeof(TransactionId));
1719 
1720  s->parent->nChildXids = new_nChildXids;
1721 
1722  /* Release child's array to avoid leakage */
1723  if (s->childXids != NULL)
1724  pfree(s->childXids);
1725  /* We must reset these to avoid double-free if fail later in commit */
1726  s->childXids = NULL;
1727  s->nChildXids = 0;
1728  s->maxChildXids = 0;
1729 }
#define Min(x, y)
Definition: c.h:995
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:1541
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1181
#define MaxAllocSize
Definition: memutils.h:40

References Assert, TransactionStateData::childXids, CurrentTransactionState, ereport, errcode(), errmsg(), ERROR, TransactionStateData::fullTransactionId, MaxAllocSize, TransactionStateData::maxChildXids, MemoryContextAlloc(), Min, TransactionStateData::nChildXids, TransactionStateData::parent, pfree(), repalloc(), TopTransactionContext, and XidFromFullTransactionId.

Referenced by CommitSubTransaction().

◆ AtSubCommit_Memory()

static void AtSubCommit_Memory ( void  )
static

Definition at line 1624 of file xact.c.

1625 {
1627 
1628  Assert(s->parent != NULL);
1629 
1630  /* Return to parent transaction level's memory context. */
1633 
1634  /*
1635  * Ordinarily we cannot throw away the child's CurTransactionContext,
1636  * since the data it contains will be needed at upper commit. However, if
1637  * there isn't actually anything in it, we can throw it away. This avoids
1638  * a small memory leak in the common case of "trivial" subxacts.
1639  */
1641  {
1643  s->curTransactionContext = NULL;
1644  }
1645 }
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:743

References Assert, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, MemoryContextDelete(), MemoryContextIsEmpty(), MemoryContextSwitchTo(), and TransactionStateData::parent.

Referenced by CommitSubTransaction().

◆ AtSubStart_Memory()

static void AtSubStart_Memory ( void  )
static

Definition at line 1253 of file xact.c.

1254 {
1256 
1257  Assert(CurTransactionContext != NULL);
1258 
1259  /*
1260  * Remember the context that was active prior to subtransaction start.
1261  */
1263 
1264  /*
1265  * Create a CurTransactionContext, which will be used to hold data that
1266  * survives subtransaction commit but disappears on subtransaction abort.
1267  * We make it a child of the immediate parent's CurTransactionContext.
1268  */
1270  "CurTransactionContext",
1273 
1274  /* Make the CurTransactionContext active. */
1276 }

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, CurrentMemoryContext, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, MemoryContextSwitchTo(), and TransactionStateData::priorContext.

Referenced by StartSubTransaction().

◆ AtSubStart_ResourceOwner()

static void AtSubStart_ResourceOwner ( void  )
static

Definition at line 1282 of file xact.c.

1283 {
1285 
1286  Assert(s->parent != NULL);
1287 
1288  /*
1289  * Create a resource owner for the subtransaction. We make it a child of
1290  * the immediate parent's resource owner.
1291  */
1292  s->curTransactionOwner =
1294  "SubTransaction");
1295 
1298 }

References Assert, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, TransactionStateData::parent, and ResourceOwnerCreate().

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4319 of file xact.c.

4320 {
4322 
4323  /*
4324  * If we are in STARTED state (that is, no transaction block is open),
4325  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4326  * block.
4327  *
4328  * For caller convenience, we consider all other transaction states as
4329  * legal here; otherwise the caller would need its own state check, which
4330  * seems rather pointless.
4331  */
4332  if (s->blockState == TBLOCK_STARTED)
4334 }

References TransactionStateData::blockState, CurrentTransactionState, TBLOCK_IMPLICIT_INPROGRESS, and TBLOCK_STARTED.

Referenced by exec_simple_query().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4687 of file xact.c.

4688 {
4690  bool save_ExitOnAnyError = ExitOnAnyError;
4691 
4692  /*
4693  * Errors within this function are improbable, but if one does happen we
4694  * force a FATAL exit. Callers generally aren't prepared to handle losing
4695  * control, and moreover our transaction state is probably corrupted if we
4696  * fail partway through; so an ordinary ERROR longjmp isn't okay.
4697  */
4698  ExitOnAnyError = true;
4699 
4700  /*
4701  * We do not check for parallel mode here. It's permissible to start and
4702  * end "internal" subtransactions while in parallel mode, so long as no
4703  * new XIDs or command IDs are assigned. Enforcement of that occurs in
4704  * AssignTransactionId() and CommandCounterIncrement().
4705  */
4706 
4707  switch (s->blockState)
4708  {
4709  case TBLOCK_STARTED:
4710  case TBLOCK_INPROGRESS:
4713  case TBLOCK_END:
4714  case TBLOCK_PREPARE:
4715  case TBLOCK_SUBINPROGRESS:
4716  /* Normal subtransaction start */
4717  PushTransaction();
4718  s = CurrentTransactionState; /* changed by push */
4719 
4720  /*
4721  * Savepoint names, like the TransactionState block itself, live
4722  * in TopTransactionContext.
4723  */
4724  if (name)
4726  break;
4727 
4728  /* These cases are invalid. */
4729  case TBLOCK_DEFAULT:
4730  case TBLOCK_BEGIN:
4731  case TBLOCK_SUBBEGIN:
4732  case TBLOCK_SUBRELEASE:
4733  case TBLOCK_SUBCOMMIT:
4734  case TBLOCK_ABORT:
4735  case TBLOCK_SUBABORT:
4736  case TBLOCK_ABORT_END:
4737  case TBLOCK_SUBABORT_END:
4738  case TBLOCK_ABORT_PENDING:
4740  case TBLOCK_SUBRESTART:
4742  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4744  break;
4745  }
4746 
4749 
4750  ExitOnAnyError = save_ExitOnAnyError;
4751 }
#define FATAL
Definition: elog.h:41
bool ExitOnAnyError
Definition: globals.c:122
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1683
const char * name
static void PushTransaction(void)
Definition: xact.c:5403
void StartTransactionCommand(void)
Definition: xact.c:3039
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5694
void CommitTransactionCommand(void)
Definition: xact.c:3137

References TransactionStateData::blockState, BlockStateAsString(), CommitTransactionCommand(), CurrentTransactionState, elog, ExitOnAnyError, FATAL, MemoryContextStrdup(), TransactionStateData::name, name, PushTransaction(), StartTransactionCommand(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and TopTransactionContext.

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_returnnext(), pltcl_subtrans_begin(), pltcl_subtransaction(), PLy_spi_subtransaction_begin(), PLy_subtransaction_enter(), ReorderBufferImmediateInvalidation(), and ReorderBufferProcessTXN().

◆ BeginTransactionBlock()

void BeginTransactionBlock ( void  )

Definition at line 3917 of file xact.c.

3918 {
3920 
3921  switch (s->blockState)
3922  {
3923  /*
3924  * We are not inside a transaction block, so allow one to begin.
3925  */
3926  case TBLOCK_STARTED:
3927  s->blockState = TBLOCK_BEGIN;
3928  break;
3929 
3930  /*
3931  * BEGIN converts an implicit transaction block to a regular one.
3932  * (Note that we allow this even if we've already done some
3933  * commands, which is a bit odd but matches historical practice.)
3934  */
3936  s->blockState = TBLOCK_BEGIN;
3937  break;
3938 
3939  /*
3940  * Already a transaction block in progress.
3941  */
3942  case TBLOCK_INPROGRESS:
3944  case TBLOCK_SUBINPROGRESS:
3945  case TBLOCK_ABORT:
3946  case TBLOCK_SUBABORT:
3947  ereport(WARNING,
3948  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3949  errmsg("there is already a transaction in progress")));
3950  break;
3951 
3952  /* These cases are invalid. */
3953  case TBLOCK_DEFAULT:
3954  case TBLOCK_BEGIN:
3955  case TBLOCK_SUBBEGIN:
3956  case TBLOCK_END:
3957  case TBLOCK_SUBRELEASE:
3958  case TBLOCK_SUBCOMMIT:
3959  case TBLOCK_ABORT_END:
3960  case TBLOCK_SUBABORT_END:
3961  case TBLOCK_ABORT_PENDING:
3963  case TBLOCK_SUBRESTART:
3965  case TBLOCK_PREPARE:
3966  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3968  break;
3969  }
3970 }

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), FATAL, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and WARNING.

Referenced by apply_handle_prepare_internal(), pa_start_subtrans(), and standard_ProcessUtility().

◆ BlockStateAsString()

static const char * BlockStateAsString ( TBlockState  blockState)
static

Definition at line 5694 of file xact.c.

5695 {
5696  switch (blockState)
5697  {
5698  case TBLOCK_DEFAULT:
5699  return "DEFAULT";
5700  case TBLOCK_STARTED:
5701  return "STARTED";
5702  case TBLOCK_BEGIN:
5703  return "BEGIN";
5704  case TBLOCK_INPROGRESS:
5705  return "INPROGRESS";
5707  return "IMPLICIT_INPROGRESS";
5709  return "PARALLEL_INPROGRESS";
5710  case TBLOCK_END:
5711  return "END";
5712  case TBLOCK_ABORT:
5713  return "ABORT";
5714  case TBLOCK_ABORT_END:
5715  return "ABORT_END";
5716  case TBLOCK_ABORT_PENDING:
5717  return "ABORT_PENDING";
5718  case TBLOCK_PREPARE:
5719  return "PREPARE";
5720  case TBLOCK_SUBBEGIN:
5721  return "SUBBEGIN";
5722  case TBLOCK_SUBINPROGRESS:
5723  return "SUBINPROGRESS";
5724  case TBLOCK_SUBRELEASE:
5725  return "SUBRELEASE";
5726  case TBLOCK_SUBCOMMIT:
5727  return "SUBCOMMIT";
5728  case TBLOCK_SUBABORT:
5729  return "SUBABORT";
5730  case TBLOCK_SUBABORT_END:
5731  return "SUBABORT_END";
5733  return "SUBABORT_PENDING";
5734  case TBLOCK_SUBRESTART:
5735  return "SUBRESTART";
5737  return "SUBABORT_RESTART";
5738  }
5739  return "UNRECOGNIZED";
5740 }

References TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by BeginInternalSubTransaction(), BeginTransactionBlock(), CommitTransactionCommandInternal(), DefineSavepoint(), EndTransactionBlock(), ReleaseCurrentSubTransaction(), ReleaseSavepoint(), RollbackAndReleaseCurrentSubTransaction(), RollbackToSavepoint(), ShowTransactionStateRec(), StartTransactionCommand(), TransactionBlockStatusCode(), and UserAbortTransactionBlock().

◆ CallSubXactCallbacks()

static void CallSubXactCallbacks ( SubXactEvent  event,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)
static

Definition at line 3891 of file xact.c.

3894 {
3895  SubXactCallbackItem *item;
3897 
3898  for (item = SubXact_callbacks; item; item = next)
3899  {
3900  /* allow callbacks to unregister themselves when called */
3901  next = item->next;
3902  item->callback(event, mySubid, parentSubid, item->arg);
3903  }
3904 }
static int32 next
Definition: blutils.c:222
struct SubXactCallbackItem * next
Definition: xact.c:321
SubXactCallback callback
Definition: xact.c:322
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:326

References SubXactCallbackItem::arg, SubXactCallbackItem::callback, next, SubXactCallbackItem::next, and SubXact_callbacks.

Referenced by AbortSubTransaction(), CommitSubTransaction(), and StartSubTransaction().

◆ CallXactCallbacks()

static void CallXactCallbacks ( XactEvent  event)
static

Definition at line 3831 of file xact.c.

3832 {
3833  XactCallbackItem *item;
3835 
3836  for (item = Xact_callbacks; item; item = next)
3837  {
3838  /* allow callbacks to unregister themselves when called */
3839  next = item->next;
3840  item->callback(event, item->arg);
3841  }
3842 }
struct XactCallbackItem * next
Definition: xact.c:309
void * arg
Definition: xact.c:311
XactCallback callback
Definition: xact.c:310
static XactCallbackItem * Xact_callbacks
Definition: xact.c:314

References XactCallbackItem::arg, XactCallbackItem::callback, next, XactCallbackItem::next, and Xact_callbacks.

Referenced by AbortTransaction(), CommitTransaction(), and PrepareTransaction().

◆ CheckTransactionBlock()

static void CheckTransactionBlock ( bool  isTopLevel,
bool  throwError,
const char *  stmtType 
)
static

Definition at line 3715 of file xact.c.

3716 {
3717  /*
3718  * xact block already started?
3719  */
3720  if (IsTransactionBlock())
3721  return;
3722 
3723  /*
3724  * subtransaction?
3725  */
3726  if (IsSubTransaction())
3727  return;
3728 
3729  /*
3730  * inside a function call?
3731  */
3732  if (!isTopLevel)
3733  return;
3734 
3735  ereport(throwError ? ERROR : WARNING,
3736  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3737  /* translator: %s represents an SQL statement name */
3738  errmsg("%s can only be used in transaction blocks",
3739  stmtType)));
3740 }
bool IsSubTransaction(void)
Definition: xact.c:5037
bool IsTransactionBlock(void)
Definition: xact.c:4964

References ereport, errcode(), errmsg(), ERROR, IsSubTransaction(), IsTransactionBlock(), and WARNING.

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5370 of file xact.c.

5371 {
5373 
5374  ShowTransactionState("CleanupSubTransaction");
5375 
5376  if (s->state != TRANS_ABORT)
5377  elog(WARNING, "CleanupSubTransaction while in %s state",
5379 
5381 
5384  if (s->curTransactionOwner)
5386  s->curTransactionOwner = NULL;
5387 
5389 
5390  s->state = TRANS_DEFAULT;
5391 
5392  PopTransaction();
5393 }
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1092
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:854
static void AtSubCleanup_Memory(void)
Definition: xact.c:2011
static void PopTransaction(void)
Definition: xact.c:5465

References AtSubCleanup_Memory(), AtSubCleanup_Portals(), CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, TransactionStateData::parent, PopTransaction(), ResourceOwnerDelete(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, TRANS_ABORT, TRANS_DEFAULT, TransStateAsString(), and WARNING.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), CommitTransactionCommandInternal(), and RollbackAndReleaseCurrentSubTransaction().

◆ CleanupTransaction()

static void CleanupTransaction ( void  )
static

Definition at line 2989 of file xact.c.

2990 {
2992 
2993  /*
2994  * State should still be TRANS_ABORT from AbortTransaction().
2995  */
2996  if (s->state != TRANS_ABORT)
2997  elog(FATAL, "CleanupTransaction: unexpected state %s",
2999 
3000  /*
3001  * do abort cleanup processing
3002  */
3003  AtCleanup_Portals(); /* now safe to release portal memory */
3004  AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3005 
3006  CurrentResourceOwner = NULL; /* and resource owner */
3009  s->curTransactionOwner = NULL;
3012 
3013  AtCleanup_Memory(); /* and transaction memory */
3014 
3017  s->nestingLevel = 0;
3018  s->gucNestLevel = 0;
3019  s->childXids = NULL;
3020  s->nChildXids = 0;
3021  s->maxChildXids = 0;
3022  s->parallelModeLevel = 0;
3023  s->parallelChildXact = false;
3024 
3027 
3028  /*
3029  * done with abort processing, set current transaction state back to
3030  * default
3031  */
3032  s->state = TRANS_DEFAULT;
3033 }
#define InvalidSubTransactionId
Definition: c.h:649
void AtCleanup_Portals(void)
Definition: portalmem.c:858
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:995
#define InvalidFullTransactionId
Definition: transam.h:56
static void AtCleanup_Memory(void)
Definition: xact.c:1963
static int nParallelCurrentXids
Definition: xact.c:125

References AtCleanup_Memory(), AtCleanup_Portals(), AtEOXact_Snapshot(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, FATAL, TransactionStateData::fullTransactionId, TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, TransactionStateData::maxChildXids, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, ResourceOwnerDelete(), TransactionStateData::state, TransactionStateData::subTransactionId, TopTransactionResourceOwner, TRANS_ABORT, TRANS_DEFAULT, TransStateAsString(), and XactTopFullTransactionId.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), and CommitTransactionCommandInternal().

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 1099 of file xact.c.

1100 {
1101  /*
1102  * If the current value of the command counter hasn't been "used" to mark
1103  * tuples, we need not increment it, since there's no need to distinguish
1104  * a read-only command from others. This helps postpone command counter
1105  * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1106  */
1108  {
1109  /*
1110  * Workers synchronize transaction state at the beginning of each
1111  * parallel operation, so we can't account for new commands after that
1112  * point.
1113  */
1115  ereport(ERROR,
1116  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
1117  errmsg("cannot start commands during a parallel operation")));
1118 
1119  currentCommandId += 1;
1121  {
1122  currentCommandId -= 1;
1123  ereport(ERROR,
1124  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1125  errmsg("cannot have more than 2^32-2 commands in a transaction")));
1126  }
1127  currentCommandIdUsed = false;
1128 
1129  /* Propagate new command ID into static snapshots */
1131 
1132  /*
1133  * Make any catalog changes done by the just-completed command visible
1134  * in the local syscache. We obviously don't need to do this after a
1135  * read-only command. (But see hacks in inval.c to make real sure we
1136  * don't think a command that queued inval messages was read-only.)
1137  */
1138  AtCCI_LocalCache();
1139  }
1140 }
#define InvalidCommandId
Definition: c.h:660
void SnapshotSetCommandId(CommandId curcid)
Definition: snapmgr.c:456
static bool currentCommandIdUsed
Definition: xact.c:267
static CommandId currentCommandId
Definition: xact.c:266
static void AtCCI_LocalCache(void)
Definition: xact.c:1568

References AtCCI_LocalCache(), currentCommandId, currentCommandIdUsed, ereport, errcode(), errmsg(), ERROR, InvalidCommandId, IsInParallelMode(), IsParallelWorker, and SnapshotSetCommandId().

Referenced by _SPI_execute_plan(), acquire_inherited_sample_rows(), addFkConstraint(), AddRoleMems(), AlterPublicationOptions(), AlterRole(), ATAddCheckConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecCmd(), ATExecDropColumn(), ATExecDropConstraint(), ATExecDropExpression(), ATExecDropIdentity(), ATExecSetAccessMethodNoStorage(), ATExecSetCompression(), ATExecSetExpression(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), ATParseTransformCmd(), ATRewriteTables(), AttachPartitionEnsureIndexes(), btadjustmembers(), CommitSubTransaction(), CommitTransactionCommandInternal(), copy_table_data(), create_ctas_internal(), create_toast_table(), CreateFKCheckTrigger(), createForeignKeyActionTriggers(), CreateForeignTable(), CreatePublication(), CreateRole(), CreateSchemaCommand(), CreateTriggerFiringOn(), DefineCollation(), DefineDomain(), DefineIndex(), DefineRelation(), DefineVirtualRelation(), deleteOneObject(), DetachPartitionFinalize(), do_analyze_rel(), DropClonedTriggersFromPartition(), DropRole(), end_replication_step(), EventTriggerDDLCommandEnd(), EventTriggerDDLCommandStart(), EventTriggerInvoke(), EventTriggerSQLDrop(), EventTriggerTableRewrite(), exec_eval_simple_expr(), exec_execute_message(), exec_parse_message(), exec_simple_query(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), execute_sql_string(), ExplainOnePlan(), finish_heap_swap(), fmgr_sql(), hashadjustmembers(), ImportForeignSchema(), index_build(), index_create(), IndexSetParentIndex(), InitTempTableNamespace(), inv_create(), inv_drop(), inv_truncate(), inv_write(), LogicalRepSyncTableStart(), make_new_heap(), makeConfigurationDependencies(), moveArrayTypeName(), objectNamesToOids(), OperatorShellMake(), OperatorUpd(), pg_import_system_collations(), PortalRunMulti(), ProcedureCreate(), process_syncing_tables_for_apply(), ProcessUtilitySlow(), recordExtensionInitPrivWorker(), reindex_index(), reindex_relation(), ReindexRelationConcurrently(), RelationSetNewRelfilenumber(), RemoveRoleFromInitPriv(), RemoveRoleFromObjectPolicy(), RenumberEnumType(), ReplaceRoleInInitPriv(), replorigin_create(), replorigin_drop_by_name(), ri_PerformCheck(), SetDatabaseHasLoginEventTriggers(), SetDefaultACL(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), standard_ProcessUtility(), StoreConstraints(), StorePartitionBound(), tryAttachPartitionForeignKey(), vacuum(), and validatePartitionedIndex().

◆ CommitSubTransaction()

static void CommitSubTransaction ( void  )
static

Definition at line 5097 of file xact.c.

5098 {
5100 
5101  ShowTransactionState("CommitSubTransaction");
5102 
5103  if (s->state != TRANS_INPROGRESS)
5104  elog(WARNING, "CommitSubTransaction while in %s state",
5106 
5107  /* Pre-commit processing goes here */
5108 
5110  s->parent->subTransactionId);
5111 
5112  /*
5113  * If this subxact has started any unfinished parallel operation, clean up
5114  * its workers and exit parallel mode. Warn about leaked resources.
5115  */
5117  if (s->parallelModeLevel != 0)
5118  {
5119  elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5120  s->parallelModeLevel);
5121  s->parallelModeLevel = 0;
5122  }
5123 
5124  /* Do the actual "commit", such as it is */
5125  s->state = TRANS_COMMIT;
5126 
5127  /* Must CCI to ensure commands of subtransaction are seen as done */
5129 
5130  /*
5131  * Prior to 8.4 we marked subcommit in clog at this point. We now only
5132  * perform that step, if required, as part of the atomic update of the
5133  * whole transaction tree at top level commit or abort.
5134  */
5135 
5136  /* Post-commit cleanup */
5139  AfterTriggerEndSubXact(true);
5142  s->parent->nestingLevel,
5145  s->parent->subTransactionId);
5147 
5149  s->parent->subTransactionId);
5150 
5153  true, false);
5155  s->parent->subTransactionId);
5156  AtEOSubXact_Inval(true);
5157  AtSubCommit_smgr();
5158 
5159  /*
5160  * The only lock we actually release here is the subtransaction XID lock.
5161  */
5165 
5166  /*
5167  * Other locks should get transferred to their parent resource owner.
5168  */
5171  true, false);
5174  true, false);
5175 
5176  AtEOXact_GUC(true, s->gucNestLevel);
5179  s->parent->subTransactionId);
5181  s->parent->subTransactionId);
5183  s->parent->subTransactionId);
5185  AtEOSubXact_PgStat(true, s->nestingLevel);
5187 
5188  /*
5189  * We need to restore the upper transaction's read-only state, in case the
5190  * upper is read-write while the child is read-only; GUC will incorrectly
5191  * think it should leave the child state in place.
5192  */
5194 
5198  s->curTransactionOwner = NULL;
5199 
5201 
5202  s->state = TRANS_DEFAULT;
5203 
5204  PopTransaction();
5205 }
void AtSubCommit_Notify(void)
Definition: async.c:1691
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:633
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition: portalmem.c:943
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:938
void AtSubCommit_smgr(void)
Definition: storage.c:914
static void AtSubCommit_Memory(void)
Definition: xact.c:1624
static void AtSubCommit_childXids(void)
Definition: xact.c:1653
void CommandCounterIncrement(void)
Definition: xact.c:1099
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition: xact.h:145
@ SUBXACT_EVENT_COMMIT_SUB
Definition: xact.h:143

References AfterTriggerEndSubXact(), AtEOSubXact_Files(), AtEOSubXact_HashTables(), AtEOSubXact_Inval(), AtEOSubXact_LargeObject(), AtEOSubXact_Namespace(), AtEOSubXact_on_commit_actions(), AtEOSubXact_Parallel(), AtEOSubXact_PgStat(), AtEOSubXact_RelationCache(), AtEOSubXact_SPI(), AtEOXact_GUC(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubCommit_Notify(), AtSubCommit_Portals(), AtSubCommit_smgr(), AtSubCommit_Snapshot(), CallSubXactCallbacks(), CommandCounterIncrement(), CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, PopTransaction(), TransactionStateData::prevXactReadOnly, RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_COMMIT_SUB, SUBXACT_EVENT_PRE_COMMIT_SUB, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TransStateAsString(), WARNING, XactLockTableDelete(), XactReadOnly, and XidFromFullTransactionId.

Referenced by CommitTransactionCommandInternal(), and ReleaseCurrentSubTransaction().

◆ CommitTransaction()

static void CommitTransaction ( void  )
static

Definition at line 2217 of file xact.c.

2218 {
2220  TransactionId latestXid;
2221  bool is_parallel_worker;
2222 
2223  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2224 
2225  /* Enforce parallel mode restrictions during parallel worker commit. */
2226  if (is_parallel_worker)
2228 
2229  ShowTransactionState("CommitTransaction");
2230 
2231  /*
2232  * check the current transaction state
2233  */
2234  if (s->state != TRANS_INPROGRESS)
2235  elog(WARNING, "CommitTransaction while in %s state",
2237  Assert(s->parent == NULL);
2238 
2239  /*
2240  * Do pre-commit processing that involves calling user-defined code, such
2241  * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2242  * action that would run here, because that would bypass the sandbox.
2243  * Since closing cursors could queue trigger actions, triggers could open
2244  * cursors, etc, we have to keep looping until there's nothing left to do.
2245  */
2246  for (;;)
2247  {
2248  /*
2249  * Fire all currently pending deferred triggers.
2250  */
2252 
2253  /*
2254  * Close open portals (converting holdable ones into static portals).
2255  * If there weren't any, we are done ... otherwise loop back to check
2256  * if they queued deferred triggers. Lather, rinse, repeat.
2257  */
2258  if (!PreCommit_Portals(false))
2259  break;
2260  }
2261 
2262  /*
2263  * The remaining actions cannot call any user-defined code, so it's safe
2264  * to start shutting down within-transaction services. But note that most
2265  * of this stuff could still throw an error, which would switch us into
2266  * the transaction-abort path.
2267  */
2268 
2271 
2272  /*
2273  * If this xact has started any unfinished parallel operation, clean up
2274  * its workers, warning about leaked resources. (But we don't actually
2275  * reset parallelModeLevel till entering TRANS_COMMIT, a bit below. This
2276  * keeps parallel mode restrictions active as long as possible in a
2277  * parallel worker.)
2278  */
2279  AtEOXact_Parallel(true);
2280  if (is_parallel_worker)
2281  {
2282  if (s->parallelModeLevel != 1)
2283  elog(WARNING, "parallelModeLevel is %d not 1 at end of parallel worker transaction",
2284  s->parallelModeLevel);
2285  }
2286  else
2287  {
2288  if (s->parallelModeLevel != 0)
2289  elog(WARNING, "parallelModeLevel is %d not 0 at end of transaction",
2290  s->parallelModeLevel);
2291  }
2292 
2293  /* Shut down the deferred-trigger manager */
2294  AfterTriggerEndXact(true);
2295 
2296  /*
2297  * Let ON COMMIT management do its thing (must happen after closing
2298  * cursors, to avoid dangling-reference problems)
2299  */
2301 
2302  /*
2303  * Synchronize files that are created and not WAL-logged during this
2304  * transaction. This must happen before AtEOXact_RelationMap(), so that we
2305  * don't see committed-but-broken files after a crash.
2306  */
2307  smgrDoPendingSyncs(true, is_parallel_worker);
2308 
2309  /* close large objects before lower-level cleanup */
2310  AtEOXact_LargeObject(true);
2311 
2312  /*
2313  * Insert notifications sent by NOTIFY commands into the queue. This
2314  * should be late in the pre-commit sequence to minimize time spent
2315  * holding the notify-insertion lock. However, this could result in
2316  * creating a snapshot, so we must do it before serializable cleanup.
2317  */
2318  PreCommit_Notify();
2319 
2320  /*
2321  * Mark serializable transaction as complete for predicate locking
2322  * purposes. This should be done as late as we can put it and still allow
2323  * errors to be raised for failure patterns found at commit. This is not
2324  * appropriate in a parallel worker however, because we aren't committing
2325  * the leader's transaction and its serializable state will live on.
2326  */
2327  if (!is_parallel_worker)
2329 
2330  /* Prevent cancel/die interrupt while cleaning up */
2331  HOLD_INTERRUPTS();
2332 
2333  /* Commit updates to the relation map --- do this as late as possible */
2334  AtEOXact_RelationMap(true, is_parallel_worker);
2335 
2336  /*
2337  * set the current transaction state information appropriately during
2338  * commit processing
2339  */
2340  s->state = TRANS_COMMIT;
2341  s->parallelModeLevel = 0;
2342  s->parallelChildXact = false; /* should be false already */
2343 
2344  /* Disable transaction timeout */
2345  if (TransactionTimeout > 0)
2347 
2348  if (!is_parallel_worker)
2349  {
2350  /*
2351  * We need to mark our XIDs as committed in pg_xact. This is where we
2352  * durably commit.
2353  */
2354  latestXid = RecordTransactionCommit();
2355  }
2356  else
2357  {
2358  /*
2359  * We must not mark our XID committed; the parallel leader is
2360  * responsible for that.
2361  */
2362  latestXid = InvalidTransactionId;
2363 
2364  /*
2365  * Make sure the leader will know about any WAL we wrote before it
2366  * commits.
2367  */
2369  }
2370 
2371  TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->vxid.lxid);
2372 
2373  /*
2374  * Let others know about no transaction in progress by me. Note that this
2375  * must be done _before_ releasing locks we hold and _after_
2376  * RecordTransactionCommit.
2377  */
2378  ProcArrayEndTransaction(MyProc, latestXid);
2379 
2380  /*
2381  * This is all post-commit cleanup. Note that if an error is raised here,
2382  * it's too late to abort the transaction. This should be just
2383  * noncritical resource releasing.
2384  *
2385  * The ordering of operations is not entirely random. The idea is:
2386  * release resources visible to other backends (eg, files, buffer pins);
2387  * then release locks; then release backend-local resources. We want to
2388  * release locks at the point where any backend waiting for us will see
2389  * our transaction as being fully cleaned up.
2390  *
2391  * Resources that can be associated with individual queries are handled by
2392  * the ResourceOwner mechanism. The other calls here are for backend-wide
2393  * state.
2394  */
2395 
2396  CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_COMMIT
2397  : XACT_EVENT_COMMIT);
2398 
2399  CurrentResourceOwner = NULL;
2402  true, true);
2403 
2404  /* Check we've released all buffer pins */
2405  AtEOXact_Buffers(true);
2406 
2407  /* Clean up the relation cache */
2408  AtEOXact_RelationCache(true);
2409 
2410  /*
2411  * Make catalog changes visible to all backends. This has to happen after
2412  * relcache references are dropped (see comments for
2413  * AtEOXact_RelationCache), but before locks are released (if anyone is
2414  * waiting for lock on a relation we've modified, we want them to know
2415  * about the catalog change before they start using the relation).
2416  */
2417  AtEOXact_Inval(true);
2418 
2420 
2423  true, true);
2426  true, true);
2427 
2428  /*
2429  * Likewise, dropping of files deleted during the transaction is best done
2430  * after releasing relcache and buffer pins. (This is not strictly
2431  * necessary during commit, since such pins should have been released
2432  * already, but this ordering is definitely critical during abort.) Since
2433  * this may take many seconds, also delay until after releasing locks.
2434  * Other backends will observe the attendant catalog changes and not
2435  * attempt to access affected files.
2436  */
2437  smgrDoPendingDeletes(true);
2438 
2439  /*
2440  * Send out notification signals to other backends (and do other
2441  * post-commit NOTIFY cleanup). This must not happen until after our
2442  * transaction is fully done from the viewpoint of other backends.
2443  */
2444  AtCommit_Notify();
2445 
2446  /*
2447  * Everything after this should be purely internal-to-this-backend
2448  * cleanup.
2449  */
2450  AtEOXact_GUC(true, 1);
2451  AtEOXact_SPI(true);
2452  AtEOXact_Enum();
2454  AtEOXact_Namespace(true, is_parallel_worker);
2455  AtEOXact_SMgr();
2456  AtEOXact_Files(true);
2458  AtEOXact_HashTables(true);
2459  AtEOXact_PgStat(true, is_parallel_worker);
2460  AtEOXact_Snapshot(true, false);
2461  AtEOXact_ApplyLauncher(true);
2464 
2466  s->curTransactionOwner = NULL;
2469 
2470  AtCommit_Memory();
2471 
2474  s->nestingLevel = 0;
2475  s->gucNestLevel = 0;
2476  s->childXids = NULL;
2477  s->nChildXids = 0;
2478  s->maxChildXids = 0;
2479 
2482 
2483  /*
2484  * done with commit processing, set current transaction state back to
2485  * default
2486  */
2487  s->state = TRANS_DEFAULT;
2488 
2490 }
void AtCommit_Notify(void)
Definition: async.c:968
void PreCommit_Notify(void)
Definition: async.c:861
void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
Definition: parallel.c:1550
bool PreCommit_Portals(bool isPrepare)
Definition: portalmem.c:677
void PreCommit_CheckForSerializationFailure(void)
Definition: predicate.c:4693
void PreCommit_on_commit_actions(void)
Definition: tablecmds.c:17665
void AfterTriggerFireDeferred(void)
Definition: trigger.c:5203
void EnterParallelMode(void)
Definition: xact.c:1050
static TransactionId RecordTransactionCommit(void)
Definition: xact.c:1314
static void AtCommit_Memory(void)
Definition: xact.c:1587
@ XACT_EVENT_COMMIT
Definition: xact.h:128
@ XACT_EVENT_PARALLEL_PRE_COMMIT
Definition: xact.h:134
@ XACT_EVENT_PARALLEL_COMMIT
Definition: xact.h:129
@ XACT_EVENT_PRE_COMMIT
Definition: xact.h:133

References AfterTriggerEndXact(), AfterTriggerFireDeferred(), Assert, AtCommit_Memory(), AtCommit_Notify(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_Inval(), AtEOXact_LargeObject(), AtEOXact_LogicalRepWorkers(), AtEOXact_MultiXact(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_Parallel(), AtEOXact_PgStat(), AtEOXact_RelationCache(), AtEOXact_RelationMap(), AtEOXact_SMgr(), AtEOXact_Snapshot(), AtEOXact_SPI(), TransactionStateData::blockState, CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, disable_timeout(), elog, EnterParallelMode(), TransactionStateData::fullTransactionId, TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, InvalidFullTransactionId, InvalidSubTransactionId, InvalidTransactionId, PGPROC::lxid, TransactionStateData::maxChildXids, MyProc, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, ParallelWorkerReportLastRecEnd(), TransactionStateData::parent, pgstat_report_xact_timestamp(), PreCommit_CheckForSerializationFailure(), PreCommit_Notify(), PreCommit_on_commit_actions(), PreCommit_Portals(), ProcArrayEndTransaction(), RecordTransactionCommit(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), RESUME_INTERRUPTS, ShowTransactionState(), smgrDoPendingDeletes(), smgrDoPendingSyncs(), TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_PARALLEL_INPROGRESS, TopTransactionResourceOwner, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), PGPROC::vxid, WARNING, XACT_EVENT_COMMIT, XACT_EVENT_PARALLEL_COMMIT, XACT_EVENT_PARALLEL_PRE_COMMIT, XACT_EVENT_PRE_COMMIT, XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommandInternal(), EndParallelWorkerTransaction(), EndRestoreLOs(), restore_toc_entries_prefork(), restore_toc_entry(), and RestoreArchive().

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 3137 of file xact.c.

3138 {
3139  /*
3140  * Repeatedly call CommitTransactionCommandInternal() until all the work
3141  * is done.
3142  */
3144  {
3145  }
3146 }
static bool CommitTransactionCommandInternal(void)
Definition: xact.c:3155

References CommitTransactionCommandInternal().

Referenced by _SPI_commit(), AllTablesyncsReady(), apply_handle_commit_internal(), apply_handle_commit_prepared(), apply_handle_prepare(), apply_handle_prepare_internal(), apply_handle_rollback_prepared(), apply_handle_stream_prepare(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), BeginInternalSubTransaction(), BootstrapModeMain(), clear_subscription_skip_lsn(), cluster_multiple_rels(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), finish_xact_command(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), pa_stream_abort(), ParallelApplyWorkerMain(), ParallelWorkerMain(), pg_attribute_noreturn(), process_syncing_tables_for_apply(), process_syncing_tables_for_sync(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), run_apply_worker(), shell_check_detail(), stream_abort_internal(), stream_stop_internal(), synchronize_slots(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ CommitTransactionCommandInternal()

static bool CommitTransactionCommandInternal ( void  )
static

Definition at line 3155 of file xact.c.

3156 {
3159 
3160  /* Must save in case we need to restore below */
3162 
3163  switch (s->blockState)
3164  {
3165  /*
3166  * These shouldn't happen. TBLOCK_DEFAULT means the previous
3167  * StartTransactionCommand didn't set the STARTED state
3168  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3169  * by EndParallelWorkerTransaction(), not this function.
3170  */
3171  case TBLOCK_DEFAULT:
3173  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3175  break;
3176 
3177  /*
3178  * If we aren't in a transaction block, just do our usual
3179  * transaction commit, and return to the idle state.
3180  */
3181  case TBLOCK_STARTED:
3184  break;
3185 
3186  /*
3187  * We are completing a "BEGIN TRANSACTION" command, so we change
3188  * to the "transaction block in progress" state and return. (We
3189  * assume the BEGIN did nothing to the database, so we need no
3190  * CommandCounterIncrement.)
3191  */
3192  case TBLOCK_BEGIN:
3194  break;
3195 
3196  /*
3197  * This is the case when we have finished executing a command
3198  * someplace within a transaction block. We increment the command
3199  * counter and return.
3200  */
3201  case TBLOCK_INPROGRESS:
3203  case TBLOCK_SUBINPROGRESS:
3205  break;
3206 
3207  /*
3208  * We are completing a "COMMIT" command. Do it and return to the
3209  * idle state.
3210  */
3211  case TBLOCK_END:
3214  if (s->chain)
3215  {
3216  StartTransaction();
3218  s->chain = false;
3220  }
3221  break;
3222 
3223  /*
3224  * Here we are in the middle of a transaction block but one of the
3225  * commands caused an abort so we do nothing but remain in the
3226  * abort state. Eventually we will get a ROLLBACK command.
3227  */
3228  case TBLOCK_ABORT:
3229  case TBLOCK_SUBABORT:
3230  break;
3231 
3232  /*
3233  * Here we were in an aborted transaction block and we just got
3234  * the ROLLBACK command from the user, so clean up the
3235  * already-aborted transaction and return to the idle state.
3236  */
3237  case TBLOCK_ABORT_END:
3240  if (s->chain)
3241  {
3242  StartTransaction();
3244  s->chain = false;
3246  }
3247  break;
3248 
3249  /*
3250  * Here we were in a perfectly good transaction block but the user
3251  * told us to ROLLBACK anyway. We have to abort the transaction
3252  * and then clean up.
3253  */
3254  case TBLOCK_ABORT_PENDING:
3255  AbortTransaction();
3258  if (s->chain)
3259  {
3260  StartTransaction();
3262  s->chain = false;
3264  }
3265  break;
3266 
3267  /*
3268  * We are completing a "PREPARE TRANSACTION" command. Do it and
3269  * return to the idle state.
3270  */
3271  case TBLOCK_PREPARE:
3274  break;
3275 
3276  /*
3277  * The user issued a SAVEPOINT inside a transaction block. Start a
3278  * subtransaction. (DefineSavepoint already did PushTransaction,
3279  * so as to have someplace to put the SUBBEGIN state.)
3280  */
3281  case TBLOCK_SUBBEGIN:
3284  break;
3285 
3286  /*
3287  * The user issued a RELEASE command, so we end the current
3288  * subtransaction and return to the parent transaction. The parent
3289  * might be ended too, so repeat till we find an INPROGRESS
3290  * transaction or subtransaction.
3291  */
3292  case TBLOCK_SUBRELEASE:
3293  do
3294  {
3296  s = CurrentTransactionState; /* changed by pop */
3297  } while (s->blockState == TBLOCK_SUBRELEASE);
3298 
3301  break;
3302 
3303  /*
3304  * The user issued a COMMIT, so we end the current subtransaction
3305  * hierarchy and perform final commit. We do this by rolling up
3306  * any subtransactions into their parent, which leads to O(N^2)
3307  * operations with respect to resource owners - this isn't that
3308  * bad until we approach a thousands of savepoints but is
3309  * necessary for correctness should after triggers create new
3310  * resource owners.
3311  */
3312  case TBLOCK_SUBCOMMIT:
3313  do
3314  {
3316  s = CurrentTransactionState; /* changed by pop */
3317  } while (s->blockState == TBLOCK_SUBCOMMIT);
3318  /* If we had a COMMIT command, finish off the main xact too */
3319  if (s->blockState == TBLOCK_END)
3320  {
3321  Assert(s->parent == NULL);
3324  if (s->chain)
3325  {
3326  StartTransaction();
3328  s->chain = false;
3330  }
3331  }
3332  else if (s->blockState == TBLOCK_PREPARE)
3333  {
3334  Assert(s->parent == NULL);
3337  }
3338  else
3339  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3341  break;
3342 
3343  /*
3344  * The current already-failed subtransaction is ending due to a
3345  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3346  * examine the parent (which could be in any of several states).
3347  * As we need to examine the parent, return false to request the
3348  * caller to do the next iteration.
3349  */
3350  case TBLOCK_SUBABORT_END:
3352  return false;
3353 
3354  /*
3355  * As above, but it's not dead yet, so abort first.
3356  */
3360  return false;
3361 
3362  /*
3363  * The current subtransaction is the target of a ROLLBACK TO
3364  * command. Abort and pop it, then start a new subtransaction
3365  * with the same name.
3366  */
3367  case TBLOCK_SUBRESTART:
3368  {
3369  char *name;
3370  int savepointLevel;
3371 
3372  /* save name and keep Cleanup from freeing it */
3373  name = s->name;
3374  s->name = NULL;
3375  savepointLevel = s->savepointLevel;
3376 
3379 
3380  DefineSavepoint(NULL);
3381  s = CurrentTransactionState; /* changed by push */
3382  s->name = name;
3383  s->savepointLevel = savepointLevel;
3384 
3385  /* This is the same as TBLOCK_SUBBEGIN case */
3389  }
3390  break;
3391 
3392  /*
3393  * Same as above, but the subtransaction had already failed, so we
3394  * don't need AbortSubTransaction.
3395  */
3397  {
3398  char *name;
3399  int savepointLevel;
3400 
3401  /* save name and keep Cleanup from freeing it */
3402  name = s->name;
3403  s->name = NULL;
3404  savepointLevel = s->savepointLevel;
3405 
3407 
3408  DefineSavepoint(NULL);
3409  s = CurrentTransactionState; /* changed by push */
3410  s->name = name;
3411  s->savepointLevel = savepointLevel;
3412 
3413  /* This is the same as TBLOCK_SUBBEGIN case */
3417  }
3418  break;
3419  }
3420 
3421  /* Done, no more iterations required */
3422  return true;
3423 }
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3116
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3124
static void StartTransaction(void)
Definition: xact.c:2053
void DefineSavepoint(const char *name)
Definition: xact.c:4366
static void CommitSubTransaction(void)
Definition: xact.c:5097
static void CommitTransaction(void)
Definition: xact.c:2217
static void PrepareTransaction(void)
Definition: xact.c:2499
static void StartSubTransaction(void)
Definition: xact.c:5060

References AbortSubTransaction(), AbortTransaction(), Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CleanupSubTransaction(), CleanupTransaction(), CommandCounterIncrement(), CommitSubTransaction(), CommitTransaction(), CurrentTransactionState, DefineSavepoint(), elog, ERROR, FATAL, TransactionStateData::name, name, TransactionStateData::parent, PrepareTransaction(), RestoreTransactionCharacteristics(), TransactionStateData::savepointLevel, SaveTransactionCharacteristics(), StartSubTransaction(), StartTransaction(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by CommitTransactionCommand().

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

Definition at line 4366 of file xact.c.

4367 {
4369 
4370  /*
4371  * Workers synchronize transaction state at the beginning of each parallel
4372  * operation, so we can't account for new subtransactions after that
4373  * point. (Note that this check will certainly error out if s->blockState
4374  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4375  * below.)
4376  */
4378  ereport(ERROR,
4379  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4380  errmsg("cannot define savepoints during a parallel operation")));
4381 
4382  switch (s->blockState)
4383  {
4384  case TBLOCK_INPROGRESS:
4385  case TBLOCK_SUBINPROGRESS:
4386  /* Normal subtransaction start */
4387  PushTransaction();
4388  s = CurrentTransactionState; /* changed by push */
4389 
4390  /*
4391  * Savepoint names, like the TransactionState block itself, live
4392  * in TopTransactionContext.
4393  */
4394  if (name)
4396  break;
4397 
4398  /*
4399  * We disallow savepoint commands in implicit transaction blocks.
4400  * There would be no great difficulty in allowing them so far as
4401  * this module is concerned, but a savepoint seems inconsistent
4402  * with exec_simple_query's behavior of abandoning the whole query
4403  * string upon error. Also, the point of an implicit transaction
4404  * block (as opposed to a regular one) is to automatically close
4405  * after an error, so it's hard to see how a savepoint would fit
4406  * into that.
4407  *
4408  * The error messages for this are phrased as if there were no
4409  * active transaction block at all, which is historical but
4410  * perhaps could be improved.
4411  */
4413  ereport(ERROR,
4414  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4415  /* translator: %s represents an SQL statement name */
4416  errmsg("%s can only be used in transaction blocks",
4417  "SAVEPOINT")));
4418  break;
4419 
4420  /* These cases are invalid. */
4421  case TBLOCK_DEFAULT:
4422  case TBLOCK_STARTED:
4423  case TBLOCK_BEGIN:
4425  case TBLOCK_SUBBEGIN:
4426  case TBLOCK_END:
4427  case TBLOCK_SUBRELEASE:
4428  case TBLOCK_SUBCOMMIT:
4429  case TBLOCK_ABORT:
4430  case TBLOCK_SUBABORT:
4431  case TBLOCK_ABORT_END:
4432  case TBLOCK_SUBABORT_END:
4433  case TBLOCK_ABORT_PENDING:
4435  case TBLOCK_SUBRESTART:
4437  case TBLOCK_PREPARE:
4438  elog(FATAL, "DefineSavepoint: unexpected state %s",
4440  break;
4441  }
4442 }

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), IsParallelWorker, MemoryContextStrdup(), TransactionStateData::name, name, PushTransaction(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and TopTransactionContext.

Referenced by CommitTransactionCommandInternal(), pa_start_subtrans(), and standard_ProcessUtility().

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 4344 of file xact.c.

4345 {
4347 
4348  /*
4349  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4350  * allowing CommitTransactionCommand to commit whatever happened during
4351  * the implicit transaction block as though it were a single statement.
4352  *
4353  * For caller convenience, we consider all other transaction states as
4354  * legal here; otherwise the caller would need its own state check, which
4355  * seems rather pointless.
4356  */
4359 }

References TransactionStateData::blockState, CurrentTransactionState, TBLOCK_IMPLICIT_INPROGRESS, and TBLOCK_STARTED.

Referenced by exec_simple_query().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 4037 of file xact.c.

4038 {
4040  bool result = false;
4041 
4042  switch (s->blockState)
4043  {
4044  /*
4045  * We are in a transaction block, so tell CommitTransactionCommand
4046  * to COMMIT.
4047  */
4048  case TBLOCK_INPROGRESS:
4049  s->blockState = TBLOCK_END;
4050  result = true;
4051  break;
4052 
4053  /*
4054  * We are in an implicit transaction block. If AND CHAIN was
4055  * specified, error. Otherwise commit, but issue a warning
4056  * because there was no explicit BEGIN before this.
4057  */
4059  if (chain)
4060  ereport(ERROR,
4061  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4062  /* translator: %s represents an SQL statement name */
4063  errmsg("%s can only be used in transaction blocks",
4064  "COMMIT AND CHAIN")));
4065  else
4066  ereport(WARNING,
4067  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4068  errmsg("there is no transaction in progress")));
4069  s->blockState = TBLOCK_END;
4070  result = true;
4071  break;
4072 
4073  /*
4074  * We are in a failed transaction block. Tell
4075  * CommitTransactionCommand it's time to exit the block.
4076  */
4077  case TBLOCK_ABORT:
4079  break;
4080 
4081  /*
4082  * We are in a live subtransaction block. Set up to subcommit all
4083  * open subtransactions and then commit the main transaction.
4084  */
4085  case TBLOCK_SUBINPROGRESS:
4086  while (s->parent != NULL)
4087  {
4088  if (s->blockState == TBLOCK_SUBINPROGRESS)
4090  else
4091  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4093  s = s->parent;
4094  }
4095  if (s->blockState == TBLOCK_INPROGRESS)
4096  s->blockState = TBLOCK_END;
4097  else
4098  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4100  result = true;
4101  break;
4102 
4103  /*
4104  * Here we are inside an aborted subtransaction. Treat the COMMIT
4105  * as ROLLBACK: set up to abort everything and exit the main
4106  * transaction.
4107  */
4108  case TBLOCK_SUBABORT:
4109  while (s->parent != NULL)
4110  {
4111  if (s->blockState == TBLOCK_SUBINPROGRESS)
4113  else if (s->blockState == TBLOCK_SUBABORT)
4115  else
4116  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4118  s = s->parent;
4119  }
4120  if (s->blockState == TBLOCK_INPROGRESS)
4122  else if (s->blockState == TBLOCK_ABORT)
4124  else
4125  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4127  break;
4128 
4129  /*
4130  * The user issued COMMIT when not inside a transaction. For
4131  * COMMIT without CHAIN, issue a WARNING, staying in
4132  * TBLOCK_STARTED state. The upcoming call to
4133  * CommitTransactionCommand() will then close the transaction and
4134  * put us back into the default state. For COMMIT AND CHAIN,
4135  * error.
4136  */
4137  case TBLOCK_STARTED:
4138  if (chain)
4139  ereport(ERROR,
4140  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4141  /* translator: %s represents an SQL statement name */
4142  errmsg("%s can only be used in transaction blocks",
4143  "COMMIT AND CHAIN")));
4144  else
4145  ereport(WARNING,
4146  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4147  errmsg("there is no transaction in progress")));
4148  result = true;
4149  break;
4150 
4151  /*
4152  * The user issued a COMMIT that somehow ran inside a parallel
4153  * worker. We can't cope with that.
4154  */
4156  ereport(FATAL,
4157  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4158  errmsg("cannot commit during a parallel operation")));
4159  break;
4160 
4161  /* These cases are invalid. */
4162  case TBLOCK_DEFAULT:
4163  case TBLOCK_BEGIN:
4164  case TBLOCK_SUBBEGIN:
4165  case TBLOCK_END:
4166  case TBLOCK_SUBRELEASE:
4167  case TBLOCK_SUBCOMMIT:
4168  case TBLOCK_ABORT_END:
4169  case TBLOCK_SUBABORT_END:
4170  case TBLOCK_ABORT_PENDING:
4172  case TBLOCK_SUBRESTART:
4174  case TBLOCK_PREPARE:
4175  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4177  break;
4178  }
4179 
4181  s->blockState == TBLOCK_END ||
4182  s->blockState == TBLOCK_ABORT_END ||
4184 
4185  s->chain = chain;
4186 
4187  return result;
4188 }

References Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, TransactionStateData::parent, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and WARNING.

Referenced by apply_handle_commit_internal(), pa_stream_abort(), PrepareTransactionBlock(), and standard_ProcessUtility().

◆ EnterParallelMode()

void EnterParallelMode ( void  )

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 5499 of file xact.c.

5500 {
5501  TransactionState s;
5502  Size nxids = 0;
5504 
5505  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5506  {
5508  nxids = add_size(nxids, 1);
5509  nxids = add_size(nxids, s->nChildXids);
5510  }
5511 
5512  return add_size(size, mul_size(sizeof(TransactionId), nxids));
5513 }
size_t Size
Definition: c.h:596
Size add_size(Size s1, Size s2)
Definition: shmem.c:493
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
static pg_noinline void Size size
Definition: slab.c:607
#define SerializedTransactionStateHeaderSize
Definition: xact.c:238

References add_size(), CurrentTransactionState, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, mul_size(), TransactionStateData::nChildXids, TransactionStateData::parent, SerializedTransactionStateHeaderSize, and size.

Referenced by InitializeParallelDSM().

◆ ExitParallelMode()

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 1151 of file xact.c.

1152 {
1153  forceSyncCommit = true;
1154 }
static bool forceSyncCommit
Definition: xact.c:292

References forceSyncCommit.

Referenced by createdb(), CreateTableSpace(), dropdb(), DropTableSpace(), and movedb().

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 828 of file xact.c.

829 {
830  /* this is global to a transaction, not subtransaction-local */
831  if (used)
832  {
833  /*
834  * Forbid setting currentCommandIdUsed in a parallel worker, because
835  * we have no provision for communicating this back to the leader. We
836  * could relax this restriction when currentCommandIdUsed was already
837  * true at the start of the parallel operation.
838  */
839  if (IsParallelWorker())
840  ereport(ERROR,
841  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
842  errmsg("cannot modify data in a parallel worker")));
843 
844  currentCommandIdUsed = true;
845  }
846  return currentCommandId;
847 }

References currentCommandId, currentCommandIdUsed, ereport, errcode(), errmsg(), ERROR, and IsParallelWorker.

Referenced by ATRewriteTable(), CatalogTuplesMultiInsertWithInfo(), CopyFrom(), create_edata_for_relation(), create_estate_for_relation(), FindConflictTuple(), GetSnapshotData(), GetSnapshotDataReuse(), heap_inplace_lock(), intorel_startup(), pgrowlocks(), RegisterRelcacheInvalidation(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), simple_heap_delete(), simple_heap_insert(), simple_heap_update(), simple_table_tuple_delete(), simple_table_tuple_insert(), simple_table_tuple_update(), standard_ExecutorStart(), toast_save_datum(), transientrel_startup(), and UpdateActiveSnapshotCommandId().

◆ GetCurrentFullTransactionId()

FullTransactionId GetCurrentFullTransactionId ( void  )

◆ GetCurrentFullTransactionIdIfAny()

FullTransactionId GetCurrentFullTransactionIdIfAny ( void  )

Definition at line 529 of file xact.c.

530 {
532 }

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 878 of file xact.c.

879 {
880  return stmtStartTimestamp;
881 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:280

References stmtStartTimestamp.

Referenced by check_log_duration(), CreatePortal(), InitializeParallelDSM(), pgstat_report_activity(), statement_timestamp(), and StorePreparedStatement().

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

TimestampTz GetCurrentTransactionStartTimestamp ( void  )

Definition at line 869 of file xact.c.

870 {
871  return xactStartTimestamp;
872 }
static TimestampTz xactStartTimestamp
Definition: xact.c:279

References xactStartTimestamp.

Referenced by GetCurrentTimeUsec(), GetSQLCurrentTimestamp(), GetSQLLocalTimestamp(), InitializeParallelDSM(), now(), pg_timezone_abbrevs(), and timetz_zone().

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 890 of file xact.c.

891 {
893 
894  /* should only be called after commit / abort processing */
895  Assert(s->state == TRANS_DEFAULT ||
896  s->state == TRANS_COMMIT ||
897  s->state == TRANS_ABORT ||
898  s->state == TRANS_PREPARE);
899 
900  if (xactStopTimestamp == 0)
902 
903  return xactStopTimestamp;
904 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1644
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:185
static TimestampTz xactStopTimestamp
Definition: xact.c:281

References Assert, CurrentTransactionState, GetCurrentTimestamp(), PG_USED_FOR_ASSERTS_ONLY, TRANS_ABORT, TRANS_COMMIT, TRANS_DEFAULT, TRANS_PREPARE, and xactStopTimestamp.

Referenced by pgstat_relation_flush_cb(), pgstat_report_stat(), RecordTransactionAbort(), and RecordTransactionCommit().

◆ GetStableLatestTransactionId()

TransactionId GetStableLatestTransactionId ( void  )

Definition at line 606 of file xact.c.

607 {
609  static TransactionId stablexid = InvalidTransactionId;
610 
611  if (lxid != MyProc->vxid.lxid)
612  {
613  lxid = MyProc->vxid.lxid;
614  stablexid = GetTopTransactionIdIfAny();
615  if (!TransactionIdIsValid(stablexid))
616  stablexid = ReadNextTransactionId();
617  }
618 
619  Assert(TransactionIdIsValid(stablexid));
620 
621  return stablexid;
622 }
uint32 LocalTransactionId
Definition: c.h:645
#define InvalidLocalTransactionId
Definition: lock.h:65
static TransactionId ReadNextTransactionId(void)
Definition: transam.h:315
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:440

References Assert, GetTopTransactionIdIfAny(), InvalidLocalTransactionId, InvalidTransactionId, PGPROC::lxid, MyProc, ReadNextTransactionId(), TransactionIdIsValid, and PGPROC::vxid.

Referenced by xid_age().

◆ GetTopFullTransactionId()

◆ GetTopFullTransactionIdIfAny()

FullTransactionId GetTopFullTransactionIdIfAny ( void  )

Definition at line 498 of file xact.c.

499 {
501 }

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3759 of file xact.c.

3760 {
3761  /*
3762  * Return true on same conditions that would make
3763  * PreventInTransactionBlock error out
3764  */
3765  if (IsTransactionBlock())
3766  return true;
3767 
3768  if (IsSubTransaction())
3769  return true;
3770 
3772  return true;
3773 
3774  if (!isTopLevel)
3775  return true;
3776 
3779  return true;
3780 
3781  return false;
3782 }
int MyXactFlags
Definition: xact.c:135
#define XACT_FLAGS_PIPELINING
Definition: xact.h:121

References TransactionStateData::blockState, CurrentTransactionState, IsSubTransaction(), IsTransactionBlock(), MyXactFlags, TBLOCK_DEFAULT, TBLOCK_STARTED, and XACT_FLAGS_PIPELINING.

Referenced by vacuum().

◆ IsSubTransaction()

◆ IsSubxactTopXidLogPending()

bool IsSubxactTopXidLogPending ( void  )

Definition at line 558 of file xact.c.

559 {
560  /* check whether it is already logged */
562  return false;
563 
564  /* wal_level has to be logical */
565  if (!XLogLogicalInfoActive())
566  return false;
567 
568  /* we need to be in a transaction state */
569  if (!IsTransactionState())
570  return false;
571 
572  /* it has to be a subtransaction */
573  if (!IsSubTransaction())
574  return false;
575 
576  /* the subtransaction has to have a XID assigned */
578  return false;
579 
580  return true;
581 }
bool IsTransactionState(void)
Definition: xact.c:386
TransactionId GetCurrentTransactionIdIfAny(void)
Definition: xact.c:470

References CurrentTransactionState, GetCurrentTransactionIdIfAny(), IsSubTransaction(), IsTransactionState(), TransactionStateData::topXidLogged, TransactionIdIsValid, and XLogLogicalInfoActive.

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 386 of file xact.c.

387 {
389 
390  /*
391  * TRANS_DEFAULT and TRANS_ABORT are obviously unsafe states. However, we
392  * also reject the startup/shutdown states TRANS_START, TRANS_COMMIT,
393  * TRANS_PREPARE since it might be too soon or too late within those
394  * transition states to do anything interesting. Hence, the only "valid"
395  * state is TRANS_INPROGRESS.
396  */
397  return (s->state == TRANS_INPROGRESS);
398 }

References CurrentTransactionState, TransactionStateData::state, and TRANS_INPROGRESS.

Referenced by apply_handle_commit_internal(), apply_handle_origin(), assign_transaction_timeout(), begin_replication_step(), check_client_encoding(), check_default_table_access_method(), check_default_tablespace(), check_default_text_search_config(), check_role(), check_session_authorization(), check_temp_tablespaces(), check_transaction_isolation(), check_transaction_read_only(), clear_subscription_skip_lsn(), CreateInitDecodingContext(), ensure_last_message(), FetchTableStates(), InitializeClientEncoding(), IsSubxactTopXidLogPending(), LogicalRepApplyLoop(), LogLogicalMessage(), maybe_reread_subscription(), pa_send_data(), pa_start_subtrans(), pg_attribute_noreturn(), pg_do_encoding_conversion(), PrepareClientEncoding(), PrepareTempTablespaces(), process_syncing_tables_for_apply(), process_syncing_tables_for_sync(), RelationClearRelation(), RelationFlushRelation(), RelationIdGetRelation(), RelationInitPhysicalAddr(), RelationReloadNailed(), replorigin_create(), replorigin_drop_by_name(), SearchCatCacheInternal(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SnapBuildClearExportedSnapshot(), SocketBackend(), stream_stop_internal(), synchronize_slots(), and validate_remote_info().

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

◆ MarkSubxactTopXidLogged()

void MarkSubxactTopXidLogged ( void  )

Definition at line 590 of file xact.c.

591 {
593 
595 }
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:558

References Assert, CurrentTransactionState, IsSubxactTopXidLogPending(), and TransactionStateData::topXidLogged.

Referenced by XLogInsertRecord().

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5465 of file xact.c.

5466 {
5468 
5469  if (s->state != TRANS_DEFAULT)
5470  elog(WARNING, "PopTransaction while in %s state",
5472 
5473  if (s->parent == NULL)
5474  elog(FATAL, "PopTransaction with no parent");
5475 
5477 
5478  /* Let's just make sure CurTransactionContext is good */
5481 
5482  /* Ditto for ResourceOwner links */
5485 
5486  /* Free the old child structure */
5487  if (s->name)
5488  pfree(s->name);
5489  pfree(s);
5490 }

References CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, FATAL, MemoryContextSwitchTo(), TransactionStateData::name, TransactionStateData::parent, pfree(), TransactionStateData::state, TRANS_DEFAULT, TransStateAsString(), and WARNING.

Referenced by CleanupSubTransaction(), and CommitSubTransaction().

◆ PrepareTransaction()

static void PrepareTransaction ( void  )
static

Definition at line 2499 of file xact.c.

2500 {
2503  GlobalTransaction gxact;
2504  TimestampTz prepared_at;
2505 
2507 
2508  ShowTransactionState("PrepareTransaction");
2509 
2510  /*
2511  * check the current transaction state
2512  */
2513  if (s->state != TRANS_INPROGRESS)
2514  elog(WARNING, "PrepareTransaction while in %s state",
2516  Assert(s->parent == NULL);
2517 
2518  /*
2519  * Do pre-commit processing that involves calling user-defined code, such
2520  * as triggers. Since closing cursors could queue trigger actions,
2521  * triggers could open cursors, etc, we have to keep looping until there's
2522  * nothing left to do.
2523  */
2524  for (;;)
2525  {
2526  /*
2527  * Fire all currently pending deferred triggers.
2528  */
2530 
2531  /*
2532  * Close open portals (converting holdable ones into static portals).
2533  * If there weren't any, we are done ... otherwise loop back to check
2534  * if they queued deferred triggers. Lather, rinse, repeat.
2535  */
2536  if (!PreCommit_Portals(true))
2537  break;
2538  }
2539 
2541 
2542  /*
2543  * The remaining actions cannot call any user-defined code, so it's safe
2544  * to start shutting down within-transaction services. But note that most
2545  * of this stuff could still throw an error, which would switch us into
2546  * the transaction-abort path.
2547  */
2548 
2549  /* Shut down the deferred-trigger manager */
2550  AfterTriggerEndXact(true);
2551 
2552  /*
2553  * Let ON COMMIT management do its thing (must happen after closing
2554  * cursors, to avoid dangling-reference problems)
2555  */
2557 
2558  /*
2559  * Synchronize files that are created and not WAL-logged during this
2560  * transaction. This must happen before EndPrepare(), so that we don't see
2561  * committed-but-broken files after a crash and COMMIT PREPARED.
2562  */
2563  smgrDoPendingSyncs(true, false);
2564 
2565  /* close large objects before lower-level cleanup */
2566  AtEOXact_LargeObject(true);
2567 
2568  /* NOTIFY requires no work at this point */
2569 
2570  /*
2571  * Mark serializable transaction as complete for predicate locking
2572  * purposes. This should be done as late as we can put it and still allow
2573  * errors to be raised for failure patterns found at commit.
2574  */
2576 
2577  /*
2578  * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2579  * this transaction. Having the prepared xact hold locks on another
2580  * backend's temp table seems a bad idea --- for instance it would prevent
2581  * the backend from exiting. There are other problems too, such as how to
2582  * clean up the source backend's local buffers and ON COMMIT state if the
2583  * prepared xact includes a DROP of a temp table.
2584  *
2585  * Other objects types, like functions, operators or extensions, share the
2586  * same restriction as they should not be created, locked or dropped as
2587  * this can mess up with this session or even a follow-up session trying
2588  * to use the same temporary namespace.
2589  *
2590  * We must check this after executing any ON COMMIT actions, because they
2591  * might still access a temp relation.
2592  *
2593  * XXX In principle this could be relaxed to allow some useful special
2594  * cases, such as a temp table created and dropped all within the
2595  * transaction. That seems to require much more bookkeeping though.
2596  */
2598  ereport(ERROR,
2599  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2600  errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2601 
2602  /*
2603  * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2604  * supported if we added cleanup logic to twophase.c, but for now it
2605  * doesn't seem worth the trouble.
2606  */
2608  ereport(ERROR,
2609  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2610  errmsg("cannot PREPARE a transaction that has exported snapshots")));
2611 
2612  /* Prevent cancel/die interrupt while cleaning up */
2613  HOLD_INTERRUPTS();
2614 
2615  /*
2616  * set the current transaction state information appropriately during
2617  * prepare processing
2618  */
2619  s->state = TRANS_PREPARE;
2620 
2621  /* Disable transaction timeout */
2622  if (TransactionTimeout > 0)
2624 
2625  prepared_at = GetCurrentTimestamp();
2626 
2627  /*
2628  * Reserve the GID for this transaction. This could fail if the requested
2629  * GID is invalid or already in use.
2630  */
2631  gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2632  GetUserId(), MyDatabaseId);
2633  prepareGID = NULL;
2634 
2635  /*
2636  * Collect data for the 2PC state file. Note that in general, no actual
2637  * state change should happen in the called modules during this step,
2638  * since it's still possible to fail before commit, and in that case we
2639  * want transaction abort to be able to clean up. (In particular, the
2640  * AtPrepare routines may error out if they find cases they cannot
2641  * handle.) State cleanup should happen in the PostPrepare routines
2642  * below. However, some modules can go ahead and clear state here because
2643  * they wouldn't do anything with it during abort anyway.
2644  *
2645  * Note: because the 2PC state file records will be replayed in the same
2646  * order they are made, the order of these calls has to match the order in
2647  * which we want things to happen during COMMIT PREPARED or ROLLBACK
2648  * PREPARED; in particular, pay attention to whether things should happen
2649  * before or after releasing the transaction's locks.
2650  */
2651  StartPrepare(gxact);
2652 
2653  AtPrepare_Notify();
2654  AtPrepare_Locks();
2656  AtPrepare_PgStat();
2659 
2660  /*
2661  * Here is where we really truly prepare.
2662  *
2663  * We have to record transaction prepares even if we didn't make any
2664  * updates, because the transaction manager might get confused if we lose
2665  * a global transaction.
2666  */
2667  EndPrepare(gxact);
2668 
2669  /*
2670  * Now we clean up backend-internal state and release internal resources.
2671  */
2672 
2673  /* Reset XactLastRecEnd until the next transaction writes something */
2674  XactLastRecEnd = 0;
2675 
2676  /*
2677  * Transfer our locks to a dummy PGPROC. This has to be done before
2678  * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2679  * conclude "xact already committed or aborted" for our locks.
2680  */
2681  PostPrepare_Locks(xid);
2682 
2683  /*
2684  * Let others know about no transaction in progress by me. This has to be
2685  * done *after* the prepared transaction has been marked valid, else
2686  * someone may think it is unlocked and recyclable.
2687  */
2689 
2690  /*
2691  * In normal commit-processing, this is all non-critical post-transaction
2692  * cleanup. When the transaction is prepared, however, it's important
2693  * that the locks and other per-backend resources are transferred to the
2694  * prepared transaction's PGPROC entry. Note that if an error is raised
2695  * here, it's too late to abort the transaction. XXX: This probably should
2696  * be in a critical section, to force a PANIC if any of this fails, but
2697  * that cure could be worse than the disease.
2698  */
2699 
2701 
2704  true, true);
2705 
2706  /* Check we've released all buffer pins */
2707  AtEOXact_Buffers(true);
2708 
2709  /* Clean up the relation cache */
2710  AtEOXact_RelationCache(true);
2711 
2712  /* notify doesn't need a postprepare call */
2713 
2715 
2717 
2718  PostPrepare_smgr();
2719 
2720  PostPrepare_MultiXact(xid);
2721 
2723 
2726  true, true);
2729  true, true);
2730 
2731  /*
2732  * Allow another backend to finish the transaction. After
2733  * PostPrepare_Twophase(), the transaction is completely detached from our
2734  * backend. The rest is just non-critical cleanup of backend-local state.
2735  */
2737 
2738  /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2739  AtEOXact_GUC(true, 1);
2740  AtEOXact_SPI(true);
2741  AtEOXact_Enum();
2743  AtEOXact_Namespace(true, false);
2744  AtEOXact_SMgr();
2745  AtEOXact_Files(true);
2747  AtEOXact_HashTables(true);
2748  /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2749  AtEOXact_Snapshot(true, true);
2750  /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2751  AtEOXact_ApplyLauncher(false);
2754 
2755  CurrentResourceOwner = NULL;
2757  s->curTransactionOwner = NULL;
2760 
2761  AtCommit_Memory();
2762 
2765  s->nestingLevel = 0;
2766  s->gucNestLevel = 0;
2767  s->childXids = NULL;
2768  s->nChildXids = 0;
2769  s->maxChildXids = 0;
2770 
2773 
2774  /*
2775  * done with 1st phase commit processing, set current transaction state
2776  * back to default
2777  */
2778  s->state = TRANS_DEFAULT;
2779 
2781 }
void AtPrepare_Notify(void)
Definition: async.c:836
int64 TimestampTz
Definition: timestamp.h:39
Oid MyDatabaseId
Definition: globals.c:93
void PostPrepare_Inval(void)
Definition: inval.c:863
void AtPrepare_Locks(void)
Definition: lock.c:3386
void PostPrepare_Locks(TransactionId xid)
Definition: lock.c:3482
Oid GetUserId(void)
Definition: miscinit.c:514
void AtPrepare_MultiXact(void)
Definition: multixact.c:1836
void PostPrepare_MultiXact(TransactionId xid)
Definition: multixact.c:1850
void AtPrepare_PgStat(void)
Definition: pgstat_xact.c:191
void PostPrepare_PgStat(void)
Definition: pgstat_xact.c:211
void AtPrepare_PredicateLocks(void)
Definition: predicate.c:4780
void PostPrepare_PredicateLocks(TransactionId xid)
Definition: predicate.c:4849
void ProcArrayClearTransaction(PGPROC *proc)
Definition: procarray.c:907
void AtPrepare_RelationMap(void)
Definition: relmapper.c:588
bool XactHasExportedSnapshots(void)
Definition: snapmgr.c:1554
void PostPrepare_smgr(void)
Definition: storage.c:893
void EndPrepare(GlobalTransaction gxact)
Definition: twophase.c:1158
void StartPrepare(GlobalTransaction gxact)
Definition: twophase.c:1065
void PostPrepare_Twophase(void)
Definition: twophase.c:344
GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition: twophase.c:359
static char * prepareGID
Definition: xact.c:287
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:453
@ XACT_EVENT_PRE_PREPARE
Definition: xact.h:135
@ XACT_EVENT_PREPARE
Definition: xact.h:132
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:102

References AfterTriggerEndXact(), AfterTriggerFireDeferred(), Assert, AtCommit_Memory(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_LargeObject(), AtEOXact_LogicalRepWorkers(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_RelationCache(), AtEOXact_SMgr(), AtEOXact_Snapshot(), AtEOXact_SPI(), AtPrepare_Locks(), AtPrepare_MultiXact(), AtPrepare_Notify(), AtPrepare_PgStat(), AtPrepare_PredicateLocks(), AtPrepare_RelationMap(), CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, disable_timeout(), elog, EndPrepare(), ereport, errcode(), errmsg(), ERROR, TransactionStateData::fullTransactionId, GetCurrentTimestamp(), GetCurrentTransactionId(), GetUserId(), TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, InvalidFullTransactionId, InvalidSubTransactionId, IsInParallelMode(), MarkAsPreparing(), TransactionStateData::maxChildXids, MyDatabaseId, MyProc, MyXactFlags, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parent, pgstat_report_xact_timestamp(), PostPrepare_Inval(), PostPrepare_Locks(), PostPrepare_MultiXact(), PostPrepare_PgStat(), PostPrepare_PredicateLocks(), PostPrepare_smgr(), PostPrepare_Twophase(), PreCommit_CheckForSerializationFailure(), PreCommit_on_commit_actions(), PreCommit_Portals(), prepareGID, ProcArrayClearTransaction(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), RESUME_INTERRUPTS, ShowTransactionState(), smgrDoPendingSyncs(), StartPrepare(), TransactionStateData::state, TransactionStateData::subTransactionId, TopTransactionResourceOwner, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_PREPARE, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), WARNING, XACT_EVENT_PRE_PREPARE, XACT_EVENT_PREPARE, XACT_FLAGS_ACCESSEDTEMPNAMESPACE, XactHasExportedSnapshots(), XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommandInternal().

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char *  gid)

Definition at line 3985 of file xact.c.

3986 {
3987  TransactionState s;
3988  bool result;
3989 
3990  /* Set up to commit the current transaction */
3991  result = EndTransactionBlock(false);
3992 
3993  /* If successful, change outer tblock state to PREPARE */
3994  if (result)
3995  {
3997 
3998  while (s->parent != NULL)
3999  s = s->parent;
4000 
4001  if (s->blockState == TBLOCK_END)
4002  {
4003  /* Save GID where PrepareTransaction can find it again */
4005 
4007  }
4008  else
4009  {
4010  /*
4011  * ignore case where we are not in a transaction;
4012  * EndTransactionBlock already issued a warning.
4013  */
4016  /* Don't send back a PREPARE result tag... */
4017  result = false;
4018  }
4019  }
4020 
4021  return result;
4022 }
bool EndTransactionBlock(bool chain)
Definition: xact.c:4037

References Assert, TransactionStateData::blockState, CurrentTransactionState, EndTransactionBlock(), MemoryContextStrdup(), TransactionStateData::parent, prepareGID, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, and TopTransactionContext.

Referenced by apply_handle_prepare_internal(), and standard_ProcessUtility().

◆ PreventInTransactionBlock()

void PreventInTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3628 of file xact.c.

3629 {
3630  /*
3631  * xact block already started?
3632  */
3633  if (IsTransactionBlock())
3634  ereport(ERROR,
3635  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3636  /* translator: %s represents an SQL statement name */
3637  errmsg("%s cannot run inside a transaction block",
3638  stmtType)));
3639 
3640  /*
3641  * subtransaction?
3642  */
3643  if (IsSubTransaction())
3644  ereport(ERROR,
3645  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3646  /* translator: %s represents an SQL statement name */
3647  errmsg("%s cannot run inside a subtransaction",
3648  stmtType)));
3649 
3650  /*
3651  * inside a pipeline that has started an implicit transaction?
3652  */
3654  ereport(ERROR,
3655  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3656  /* translator: %s represents an SQL statement name */
3657  errmsg("%s cannot be executed within a pipeline",
3658  stmtType)));
3659 
3660  /*
3661  * inside a function call?
3662  */
3663  if (!isTopLevel)
3664  ereport(ERROR,
3665  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3666  /* translator: %s represents an SQL statement name */
3667  errmsg("%s cannot be executed from a function", stmtType)));
3668 
3669  /* If we got past IsTransactionBlock test, should be in default state */
3672  elog(FATAL, "cannot prevent transaction chain");
3673 
3674  /* All okay. Set the flag to make sure the right thing happens later. */
3676 }
#define XACT_FLAGS_NEEDIMMEDIATECOMMIT
Definition: xact.h:114

References TransactionStateData::blockState, CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, IsSubTransaction(), IsTransactionBlock(), MyXactFlags, TBLOCK_DEFAULT, TBLOCK_STARTED, XACT_FLAGS_NEEDIMMEDIATECOMMIT, and XACT_FLAGS_PIPELINING.

Referenced by AlterDatabase(), AlterSubscription(), CheckAlterSubOption(), cluster(), CreateSubscription(), DiscardAll(), DropSubscription(), exec_replication_command(), ExecDropStmt(), ExecReindex(), ProcessUtilitySlow(), ReindexPartitions(), standard_ProcessUtility(), and vacuum().

◆ PushTransaction()

static void PushTransaction ( void  )
static

Definition at line 5403 of file xact.c.

5404 {
5406  TransactionState s;
5407 
5408  /*
5409  * We keep subtransaction state nodes in TopTransactionContext.
5410  */
5411  s = (TransactionState)
5413  sizeof(TransactionStateData));
5414 
5415  /*
5416  * Assign a subtransaction ID, watching out for counter wraparound.
5417  */
5420  {
5422  pfree(s);
5423  ereport(ERROR,
5424  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5425  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5426  }
5427 
5428  /*
5429  * We can now stack a minimally valid subtransaction without fear of
5430  * failure.
5431  */
5432  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5434  s->parent = p;
5435  s->nestingLevel = p->nestingLevel + 1;
5438  s->state = TRANS_DEFAULT;
5443  s->parallelModeLevel = 0;
5445  s->topXidLogged = false;
5446 
5448 
5449  /*
5450  * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5451  * with the subtransaction from here on out; in particular they should not
5452  * assume that it necessarily has a transaction context, resource owner,
5453  * or XID.
5454  */
5455 }
int NewGUCNestLevel(void)
Definition: guc.c:2234
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1215
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:635
bool startedInRecovery
Definition: xact.c:211
TransactionStateData * TransactionState
Definition: xact.c:220
static SubTransactionId currentSubTransactionId
Definition: xact.c:265

References TransactionStateData::blockState, currentSubTransactionId, CurrentTransactionState, ereport, errcode(), errmsg(), ERROR, TransactionStateData::fullTransactionId, GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, MemoryContextAllocZero(), TransactionStateData::nestingLevel, NewGUCNestLevel(), TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pfree(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, TransactionStateData::prevXactReadOnly, TransactionStateData::savepointLevel, TransactionStateData::startedInRecovery, TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_SUBBEGIN, TopTransactionContext, TransactionStateData::topXidLogged, TRANS_DEFAULT, and XactReadOnly.

Referenced by BeginInternalSubTransaction(), and DefineSavepoint().

◆ RecordTransactionAbort()

static TransactionId RecordTransactionAbort ( bool  isSubXact)
static

Definition at line 1743 of file xact.c.

1744 {
1746  TransactionId latestXid;
1747  int nrels;
1748  RelFileLocator *rels;
1749  int ndroppedstats = 0;
1750  xl_xact_stats_item *droppedstats = NULL;
1751  int nchildren;
1752  TransactionId *children;
1753  TimestampTz xact_time;
1754  bool replorigin;
1755 
1756  /*
1757  * If we haven't been assigned an XID, nobody will care whether we aborted
1758  * or not. Hence, we're done in that case. It does not matter if we have
1759  * rels to delete (note that this routine is not responsible for actually
1760  * deleting 'em). We cannot have any child XIDs, either.
1761  */
1762  if (!TransactionIdIsValid(xid))
1763  {
1764  /* Reset XactLastRecEnd until the next transaction writes something */
1765  if (!isSubXact)
1766  XactLastRecEnd = 0;
1767  return InvalidTransactionId;
1768  }
1769 
1770  /*
1771  * We have a valid XID, so we should write an ABORT record for it.
1772  *
1773  * We do not flush XLOG to disk here, since the default assumption after a
1774  * crash would be that we aborted, anyway. For the same reason, we don't
1775  * need to worry about interlocking against checkpoint start.
1776  */
1777 
1778  /*
1779  * Check that we haven't aborted halfway through RecordTransactionCommit.
1780  */
1781  if (TransactionIdDidCommit(xid))
1782  elog(PANIC, "cannot abort transaction %u, it was already committed",
1783  xid);
1784 
1785  /*
1786  * Are we using the replication origins feature? Or, in other words, are
1787  * we replaying remote actions?
1788  */
1789  replorigin = (replorigin_session_origin != InvalidRepOriginId &&
1791 
1792  /* Fetch the data we need for the abort record */
1793  nrels = smgrGetPendingDeletes(false, &rels);
1794  nchildren = xactGetCommittedChildren(&children);
1795  ndroppedstats = pgstat_get_transactional_drops(false, &droppedstats);
1796 
1797  /* XXX do we really need a critical section here? */
1799 
1800  /* Write the ABORT record */
1801  if (isSubXact)
1802  xact_time = GetCurrentTimestamp();
1803  else
1804  {
1805  xact_time = GetCurrentTransactionStopTimestamp();
1806  }
1807 
1808  XactLogAbortRecord(xact_time,
1809  nchildren, children,
1810  nrels, rels,
1811  ndroppedstats, droppedstats,
1813  NULL);
1814 
1815  if (replorigin)
1816  /* Move LSNs forward for this replication origin */
1818  XactLastRecEnd);
1819 
1820  /*
1821  * Report the latest async abort LSN, so that the WAL writer knows to
1822  * flush this abort. There's nothing to be gained by delaying this, since
1823  * WALWriter may as well do this when it can. This is important with
1824  * streaming replication because if we don't flush WAL regularly we will
1825  * find that large aborts leave us with a long backlog for when commits
1826  * occur after the abort, increasing our window of data loss should
1827  * problems occur at that point.
1828  */
1829  if (!isSubXact)
1831 
1832  /*
1833  * Mark the transaction aborted in clog. This is not absolutely necessary
1834  * but we may as well do it while we are here; also, in the subxact case
1835  * it is helpful because XactLockTableWait makes use of it to avoid
1836  * waiting for already-aborted subtransactions. It is OK to do it without
1837  * having flushed the ABORT record to disk, because in event of a crash
1838  * we'd be assumed to have aborted anyway.
1839  */
1840  TransactionIdAbortTree(xid, nchildren, children);
1841 
1842  END_CRIT_SECTION();
1843 
1844  /* Compute latestXid while we have the child XIDs handy */
1845  latestXid = TransactionIdLatest(xid, nchildren, children);
1846 
1847  /*
1848  * If we're aborting a subtransaction, we can immediately remove failed
1849  * XIDs from PGPROC's cache of running child XIDs. We do that here for
1850  * subxacts, because we already have the child XID array at hand. For
1851  * main xacts, the equivalent happens just after this function returns.
1852  */
1853  if (isSubXact)
1854  XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1855 
1856  /* Reset XactLastRecEnd until the next transaction writes something */
1857  if (!isSubXact)
1858  XactLastRecEnd = 0;
1859 
1860  /* And clean up local data */
1861  if (rels)
1862  pfree(rels);
1863  if (ndroppedstats)
1864  pfree(droppedstats);
1865 
1866  return latestXid;
1867 }
#define PANIC
Definition: elog.h:42
#define START_CRIT_SECTION()
Definition: miscadmin.h:149
#define END_CRIT_SECTION()
Definition: miscadmin.h:151
void replorigin_session_advance(XLogRecPtr remote_commit, XLogRecPtr local_commit)
Definition: origin.c:1223
RepOriginId replorigin_session_origin
Definition: origin.c:159
XLogRecPtr replorigin_session_origin_lsn
Definition: origin.c:160
#define DoNotReplicateId
Definition: origin.h:34
#define InvalidRepOriginId
Definition: origin.h:33
int pgstat_get_transactional_drops(bool isCommit, xl_xact_stats_item **items)
Definition: pgstat_xact.c:272
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition: procarray.c:3995
int smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr)
Definition: storage.c:852
TransactionId TransactionIdLatest(TransactionId mainxid, int nxids, const TransactionId *xids)
Definition: transam.c:345
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:126
void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids)
Definition: transam.c:270
int xactGetCommittedChildren(TransactionId **ptr)
Definition: xact.c:5777
TimestampTz GetCurrentTransactionStopTimestamp(void)
Definition: xact.c:890
XLogRecPtr XactLogAbortRecord(TimestampTz abort_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
Definition: xact.c:5973

References DoNotReplicateId, elog, END_CRIT_SECTION, GetCurrentTimestamp(), GetCurrentTransactionIdIfAny(), GetCurrentTransactionStopTimestamp(), InvalidRepOriginId, InvalidTransactionId, MyXactFlags, PANIC, pfree(), pgstat_get_transactional_drops(), replorigin_session_advance(), replorigin_session_origin, replorigin_session_origin_lsn, smgrGetPendingDeletes(), START_CRIT_SECTION, TransactionIdAbortTree(), TransactionIdDidCommit(), TransactionIdIsValid, TransactionIdLatest(), xactGetCommittedChildren(), XactLastRecEnd, XactLogAbortRecord(), XidCacheRemoveRunningXids(), and XLogSetAsyncXactLSN().

Referenced by AbortSubTransaction(), and AbortTransaction().

◆ RecordTransactionCommit()

static TransactionId RecordTransactionCommit ( void  )
static

Definition at line 1314 of file xact.c.

1315 {
1317  bool markXidCommitted = TransactionIdIsValid(xid);
1318  TransactionId latestXid = InvalidTransactionId;
1319  int nrels;
1320  RelFileLocator *rels;
1321  int nchildren;
1322  TransactionId *children;
1323  int ndroppedstats = 0;
1324  xl_xact_stats_item *droppedstats = NULL;
1325  int nmsgs = 0;
1326  SharedInvalidationMessage *invalMessages = NULL;
1327  bool RelcacheInitFileInval = false;
1328  bool wrote_xlog;
1329 
1330  /*
1331  * Log pending invalidations for logical decoding of in-progress
1332  * transactions. Normally for DDLs, we log this at each command end,
1333  * however, for certain cases where we directly update the system table
1334  * without a transaction block, the invalidations are not logged till this
1335  * time.
1336  */
1337  if (XLogLogicalInfoActive())
1339 
1340  /* Get data needed for commit record */
1341  nrels = smgrGetPendingDeletes(true, &rels);
1342  nchildren = xactGetCommittedChildren(&children);
1343  ndroppedstats = pgstat_get_transactional_drops(true, &droppedstats);
1344  if (XLogStandbyInfoActive())
1345  nmsgs = xactGetCommittedInvalidationMessages(&invalMessages,
1346  &RelcacheInitFileInval);
1347  wrote_xlog = (XactLastRecEnd != 0);
1348 
1349  /*
1350  * If we haven't been assigned an XID yet, we neither can, nor do we want
1351  * to write a COMMIT record.
1352  */
1353  if (!markXidCommitted)
1354  {
1355  /*
1356  * We expect that every RelationDropStorage is followed by a catalog
1357  * update, and hence XID assignment, so we shouldn't get here with any
1358  * pending deletes. Same is true for dropping stats.
1359  *
1360  * Use a real test not just an Assert to check this, since it's a bit
1361  * fragile.
1362  */
1363  if (nrels != 0 || ndroppedstats != 0)
1364  elog(ERROR, "cannot commit a transaction that deleted files but has no xid");
1365 
1366  /* Can't have child XIDs either; AssignTransactionId enforces this */
1367  Assert(nchildren == 0);
1368 
1369  /*
1370  * Transactions without an assigned xid can contain invalidation
1371  * messages (e.g. explicit relcache invalidations or catcache
1372  * invalidations for inplace updates); standbys need to process those.
1373  * We can't emit a commit record without an xid, and we don't want to
1374  * force assigning an xid, because that'd be problematic for e.g.
1375  * vacuum. Hence we emit a bespoke record for the invalidations. We
1376  * don't want to use that in case a commit record is emitted, so they
1377  * happen synchronously with commits (besides not wanting to emit more
1378  * WAL records).
1379  */
1380  if (nmsgs != 0)
1381  {
1382  LogStandbyInvalidations(nmsgs, invalMessages,
1383  RelcacheInitFileInval);
1384  wrote_xlog = true; /* not strictly necessary */
1385  }
1386 
1387  /*
1388  * If we didn't create XLOG entries, we're done here; otherwise we
1389  * should trigger flushing those entries the same as a commit record
1390  * would. This will primarily happen for HOT pruning and the like; we
1391  * want these to be flushed to disk in due time.
1392  */
1393  if (!wrote_xlog)
1394  goto cleanup;
1395  }
1396  else
1397  {
1398  bool replorigin;
1399 
1400  /*
1401  * Are we using the replication origins feature? Or, in other words,
1402  * are we replaying remote actions?
1403  */
1404  replorigin = (replorigin_session_origin != InvalidRepOriginId &&
1406 
1407  /*
1408  * Mark ourselves as within our "commit critical section". This
1409  * forces any concurrent checkpoint to wait until we've updated
1410  * pg_xact. Without this, it is possible for the checkpoint to set
1411  * REDO after the XLOG record but fail to flush the pg_xact update to
1412  * disk, leading to loss of the transaction commit if the system
1413  * crashes a little later.
1414  *
1415  * Note: we could, but don't bother to, set this flag in
1416  * RecordTransactionAbort. That's because loss of a transaction abort
1417  * is noncritical; the presumption would be that it aborted, anyway.
1418  *
1419  * It's safe to change the delayChkptFlags flag of our own backend
1420  * without holding the ProcArrayLock, since we're the only one
1421  * modifying it. This makes checkpoint's determination of which xacts
1422  * are delaying the checkpoint a bit fuzzy, but it doesn't matter.
1423  */
1427 
1428  /*
1429  * Insert the commit XLOG record.
1430  */
1432  nchildren, children, nrels, rels,
1433  ndroppedstats, droppedstats,
1434  nmsgs, invalMessages,
1435  RelcacheInitFileInval,
1436  MyXactFlags,
1437  InvalidTransactionId, NULL /* plain commit */ );
1438 
1439  if (replorigin)
1440  /* Move LSNs forward for this replication origin */
1442  XactLastRecEnd);
1443 
1444  /*
1445  * Record commit timestamp. The value comes from plain commit
1446  * timestamp if there's no replication origin; otherwise, the
1447  * timestamp was already set in replorigin_session_origin_timestamp by
1448  * replication.
1449  *
1450  * We don't need to WAL-log anything here, as the commit record
1451  * written above already contains the data.
1452  */
1453 
1454  if (!replorigin || replorigin_session_origin_timestamp == 0)
1456 
1457  TransactionTreeSetCommitTsData(xid, nchildren, children,
1460  }
1461 
1462  /*
1463  * Check if we want to commit asynchronously. We can allow the XLOG flush
1464  * to happen asynchronously if synchronous_commit=off, or if the current
1465  * transaction has not performed any WAL-logged operation or didn't assign
1466  * an xid. The transaction can end up not writing any WAL, even if it has
1467  * an xid, if it only wrote to temporary and/or unlogged tables. It can
1468  * end up having written WAL without an xid if it did HOT pruning. In
1469  * case of a crash, the loss of such a transaction will be irrelevant;
1470  * temp tables will be lost anyway, unlogged tables will be truncated and
1471  * HOT pruning will be done again later. (Given the foregoing, you might
1472  * think that it would be unnecessary to emit the XLOG record at all in
1473  * this case, but we don't currently try to do that. It would certainly
1474  * cause problems at least in Hot Standby mode, where the
1475  * KnownAssignedXids machinery requires tracking every XID assignment. It
1476  * might be OK to skip it only when wal_level < replica, but for now we
1477  * don't.)
1478  *
1479  * However, if we're doing cleanup of any non-temp rels or committing any
1480  * command that wanted to force sync commit, then we must flush XLOG
1481  * immediately. (We must not allow asynchronous commit if there are any
1482  * non-temp tables to be deleted, because we might delete the files before
1483  * the COMMIT record is flushed to disk. We do allow asynchronous commit
1484  * if all to-be-deleted tables are temporary though, since they are lost
1485  * anyway if we crash.)
1486  */
1487  if ((wrote_xlog && markXidCommitted &&
1489  forceSyncCommit || nrels > 0)
1490  {
1492 
1493  /*
1494  * Now we may update the CLOG, if we wrote a COMMIT record above
1495  */
1496  if (markXidCommitted)
1497  TransactionIdCommitTree(xid, nchildren, children);
1498  }
1499  else
1500  {
1501  /*
1502  * Asynchronous commit case:
1503  *
1504  * This enables possible committed transaction loss in the case of a
1505  * postmaster crash because WAL buffers are left unwritten. Ideally we
1506  * could issue the WAL write without the fsync, but some
1507  * wal_sync_methods do not allow separate write/fsync.
1508  *
1509  * Report the latest async commit LSN, so that the WAL writer knows to
1510  * flush this commit.
1511  */
1513 
1514  /*
1515  * We must not immediately update the CLOG, since we didn't flush the
1516  * XLOG. Instead, we store the LSN up to which the XLOG must be
1517  * flushed before the CLOG may be updated.
1518  */
1519  if (markXidCommitted)
1520  TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1521  }
1522 
1523  /*
1524  * If we entered a commit critical section, leave it now, and let
1525  * checkpoints proceed.
1526  */
1527  if (markXidCommitted)
1528  {
1530  END_CRIT_SECTION();
1531  }
1532 
1533  /* Compute latestXid while we have the child XIDs handy */
1534  latestXid = TransactionIdLatest(xid, nchildren, children);
1535 
1536  /*
1537  * Wait for synchronous replication, if required. Similar to the decision
1538  * above about using committing asynchronously we only want to wait if
1539  * this backend assigned an xid and wrote WAL. No need to wait if an xid
1540  * was assigned due to temporary/unlogged tables or due to HOT pruning.
1541  *
1542  * Note that at this stage we have marked clog, but still show as running
1543  * in the procarray and continue to hold locks.
1544  */
1545  if (wrote_xlog && markXidCommitted)
1547 
1548  /* remember end of last commit record */
1550 
1551  /* Reset XactLastRecEnd until the next transaction writes something */
1552  XactLastRecEnd = 0;
1553 cleanup:
1554  /* Clean up local data */
1555  if (rels)
1556  pfree(rels);
1557  if (ndroppedstats)
1558  pfree(droppedstats);
1559 
1560  return latestXid;
1561 }
static void cleanup(void)
Definition: bootstrap.c:683
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid)
Definition: commit_ts.c:141
void LogLogicalInvalidations(void)
Definition: inval.c:1604
int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
Definition: inval.c:882
TimestampTz replorigin_session_origin_timestamp
Definition: origin.c:161
#define DELAY_CHKPT_START
Definition: proc.h:119
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition: standby.c:1458
int delayChkptFlags
Definition: proc.h:240
void SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
Definition: syncrep.c:148
void TransactionIdAsyncCommitTree(TransactionId xid, int nxids, TransactionId *xids, XLogRecPtr lsn)
Definition: transam.c:252
void TransactionIdCommitTree(TransactionId xid, int nxids, TransactionId *xids)
Definition: transam.c:240
int synchronous_commit
Definition: xact.c:86
XLogRecPtr XactLogCommitRecord(TimestampTz commit_time, int nsubxacts, TransactionId *subxacts, int nrels, RelFileLocator *rels, int ndroppedstats, xl_xact_stats_item *droppedstats, int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInval, int xactflags, TransactionId twophase_xid, const char *twophase_gid)
Definition: xact.c:5801
@ SYNCHRONOUS_COMMIT_OFF
Definition: xact.h:70
XLogRecPtr XactLastCommitEnd
Definition: xlog.c:254
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2795

References Assert, cleanup(), DELAY_CHKPT_START, PGPROC::delayChkptFlags, DoNotReplicateId, elog, END_CRIT_SECTION, ERROR, forceSyncCommit, GetCurrentTransactionStopTimestamp(), GetTopTransactionIdIfAny(), InvalidRepOriginId, InvalidTransactionId, LogLogicalInvalidations(), LogStandbyInvalidations(), MyProc, MyXactFlags, pfree(), pgstat_get_transactional_drops(), replorigin_session_advance(), replorigin_session_origin, replorigin_session_origin_lsn, replorigin_session_origin_timestamp, smgrGetPendingDeletes(), START_CRIT_SECTION, synchronous_commit, SYNCHRONOUS_COMMIT_OFF, SyncRepWaitForLSN(), TransactionIdAsyncCommitTree(), TransactionIdCommitTree(), TransactionIdIsValid, TransactionIdLatest(), TransactionTreeSetCommitTsData(), xactGetCommittedChildren(), xactGetCommittedInvalidationMessages(), XactLastCommitEnd, XactLastRecEnd, XactLogCommitRecord(), XLogFlush(), XLogLogicalInfoActive, XLogSetAsyncXactLSN(), and XLogStandbyInfoActive.

Referenced by CommitTransaction().

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3857 of file xact.c.

3858 {
3859  SubXactCallbackItem *item;
3860 
3861  item = (SubXactCallbackItem *)
3863  item->callback = callback;
3864  item->arg = arg;
3865  item->next = SubXact_callbacks;
3866  SubXact_callbacks = item;
3867 }
void * arg
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46

References SubXactCallbackItem::arg, arg, SubXactCallbackItem::callback, callback(), MemoryContextAlloc(), SubXactCallbackItem::next, SubXact_callbacks, and TopMemoryContext.

Referenced by _PG_init(), GetConnection(), and sepgsql_init_client_label().

◆ RegisterXactCallback()

void RegisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3797 of file xact.c.

3798 {
3799  XactCallbackItem *item;
3800 
3801  item = (XactCallbackItem *)
3803  item->callback = callback;
3804  item->arg = arg;
3805  item->next = Xact_callbacks;
3806  Xact_callbacks = item;
3807 }

References XactCallbackItem::arg, arg, XactCallbackItem::callback, callback(), MemoryContextAlloc(), XactCallbackItem::next, TopMemoryContext, and Xact_callbacks.

Referenced by _PG_init(), GetConnection(), and sepgsql_init_client_label().

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

Definition at line 4761 of file xact.c.

4762 {
4764 
4765  /*
4766  * We do not check for parallel mode here. It's permissible to start and
4767  * end "internal" subtransactions while in parallel mode, so long as no
4768  * new XIDs or command IDs are assigned.
4769  */
4770 
4771  if (s->blockState != TBLOCK_SUBINPROGRESS)
4772  elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4774  Assert(s->state == TRANS_INPROGRESS);
4777  s = CurrentTransactionState; /* changed by pop */
4778  Assert(s->state == TRANS_INPROGRESS);
4779 }

References Assert, TransactionStateData::blockState, BlockStateAsString(), CommitSubTransaction(), CurrentTransactionState, CurTransactionContext, elog, ERROR, MemoryContextSwitchTo(), TransactionStateData::state, TBLOCK_SUBINPROGRESS, and TRANS_INPROGRESS.

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_subtrans_commit(), pltcl_subtransaction(), PLy_spi_subtransaction_commit(), and PLy_subtransaction_exit().

◆ ReleaseSavepoint()

void ReleaseSavepoint ( const char *  name)

Definition at line 4451 of file xact.c.

4452 {
4454  TransactionState target,
4455  xact;
4456 
4457  /*
4458  * Workers synchronize transaction state at the beginning of each parallel
4459  * operation, so we can't account for transaction state change after that
4460  * point. (Note that this check will certainly error out if s->blockState
4461  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4462  * below.)
4463  */
4465  ereport(ERROR,
4466  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4467  errmsg("cannot release savepoints during a parallel operation")));
4468 
4469  switch (s->blockState)
4470  {
4471  /*
4472  * We can't release a savepoint if there is no savepoint defined.
4473  */
4474  case TBLOCK_INPROGRESS:
4475  ereport(ERROR,
4476  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4477  errmsg("savepoint \"%s\" does not exist", name)));
4478  break;
4479 
4481  /* See comment about implicit transactions in DefineSavepoint */
4482  ereport(ERROR,
4483  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4484  /* translator: %s represents an SQL statement name */
4485  errmsg("%s can only be used in transaction blocks",
4486  "RELEASE SAVEPOINT")));
4487  break;
4488 
4489  /*
4490  * We are in a non-aborted subtransaction. This is the only valid
4491  * case.
4492  */
4493  case TBLOCK_SUBINPROGRESS:
4494  break;
4495 
4496  /* These cases are invalid. */
4497  case TBLOCK_DEFAULT:
4498  case TBLOCK_STARTED:
4499  case TBLOCK_BEGIN:
4501  case TBLOCK_SUBBEGIN:
4502  case TBLOCK_END:
4503  case TBLOCK_SUBRELEASE:
4504  case TBLOCK_SUBCOMMIT:
4505  case TBLOCK_ABORT:
4506  case TBLOCK_SUBABORT:
4507  case TBLOCK_ABORT_END:
4508  case TBLOCK_SUBABORT_END:
4509  case TBLOCK_ABORT_PENDING:
4511  case TBLOCK_SUBRESTART:
4513  case TBLOCK_PREPARE:
4514  elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4516  break;
4517  }
4518 
4519  for (target = s; PointerIsValid(target); target = target->parent)
4520  {
4521  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4522  break;
4523  }
4524 
4525  if (!PointerIsValid(target))
4526  ereport(ERROR,
4527  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4528  errmsg("savepoint \"%s\" does not exist", name)));
4529 
4530  /* disallow crossing savepoint level boundaries */
4531  if (target->savepointLevel != s->savepointLevel)
4532  ereport(ERROR,
4533  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4534  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4535 
4536  /*
4537  * Mark "commit pending" all subtransactions up to the target
4538  * subtransaction. The actual commits will happen when control gets to
4539  * CommitTransactionCommand.
4540  */
4541  xact = CurrentTransactionState;
4542  for (;;)
4543  {
4545  xact->blockState = TBLOCK_SUBRELEASE;
4546  if (xact == target)
4547  break;
4548  xact = xact->parent;
4549  Assert(PointerIsValid(xact));
4550  }
4551 }
#define PointerIsValid(pointer)
Definition: c.h:754

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), IsParallelWorker, TransactionStateData::name, name, TransactionStateData::parent, PointerIsValid, TransactionStateData::savepointLevel, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by standard_ProcessUtility().

◆ RequireTransactionBlock()

void RequireTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3706 of file xact.c.

3707 {
3708  CheckTransactionBlock(isTopLevel, true, stmtType);
3709 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3715

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4789 of file xact.c.

4790 {
4792 
4793  /*
4794  * We do not check for parallel mode here. It's permissible to start and
4795  * end "internal" subtransactions while in parallel mode, so long as no
4796  * new XIDs or command IDs are assigned.
4797  */
4798 
4799  switch (s->blockState)
4800  {
4801  /* Must be in a subtransaction */
4802  case TBLOCK_SUBINPROGRESS:
4803  case TBLOCK_SUBABORT:
4804  break;
4805 
4806  /* These cases are invalid. */
4807  case TBLOCK_DEFAULT:
4808  case TBLOCK_STARTED:
4809  case TBLOCK_BEGIN:
4812  case TBLOCK_SUBBEGIN:
4813  case TBLOCK_INPROGRESS:
4814  case TBLOCK_END:
4815  case TBLOCK_SUBRELEASE:
4816  case TBLOCK_SUBCOMMIT:
4817  case TBLOCK_ABORT:
4818  case TBLOCK_ABORT_END:
4819  case TBLOCK_SUBABORT_END:
4820  case TBLOCK_ABORT_PENDING:
4822  case TBLOCK_SUBRESTART:
4824  case TBLOCK_PREPARE:
4825  elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4827  break;
4828  }
4829 
4830  /*
4831  * Abort the current subtransaction, if needed.
4832  */
4833  if (s->blockState == TBLOCK_SUBINPROGRESS)
4835 
4836  /* And clean it up, too */
4838 
4839  s = CurrentTransactionState; /* changed by pop */
4841  s->blockState == TBLOCK_INPROGRESS ||
4844  s->blockState == TBLOCK_STARTED);
4845 }

References AbortSubTransaction(), Assert, TransactionStateData::blockState, BlockStateAsString(), CleanupSubTransaction(), CurrentTransactionState, elog, FATAL, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_subtrans_abort(), pltcl_subtransaction(), PLy_abort_open_subtransactions(), PLy_spi_subtransaction_abort(), PLy_subtransaction_exit(), ReorderBufferImmediateInvalidation(), and ReorderBufferProcessTXN().

◆ RollbackToSavepoint()

void RollbackToSavepoint ( const char *  name)

Definition at line 4560 of file xact.c.

4561 {
4563  TransactionState target,
4564  xact;
4565 
4566  /*
4567  * Workers synchronize transaction state at the beginning of each parallel
4568  * operation, so we can't account for transaction state change after that
4569  * point. (Note that this check will certainly error out if s->blockState
4570  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4571  * below.)
4572  */
4574  ereport(ERROR,
4575  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4576  errmsg("cannot rollback to savepoints during a parallel operation")));
4577 
4578  switch (s->blockState)
4579  {
4580  /*
4581  * We can't rollback to a savepoint if there is no savepoint
4582  * defined.
4583  */
4584  case TBLOCK_INPROGRESS:
4585  case TBLOCK_ABORT:
4586  ereport(ERROR,
4587  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4588  errmsg("savepoint \"%s\" does not exist", name)));
4589  break;
4590 
4592  /* See comment about implicit transactions in DefineSavepoint */
4593  ereport(ERROR,
4594  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4595  /* translator: %s represents an SQL statement name */
4596  errmsg("%s can only be used in transaction blocks",
4597  "ROLLBACK TO SAVEPOINT")));
4598  break;
4599 
4600  /*
4601  * There is at least one savepoint, so proceed.
4602  */
4603  case TBLOCK_SUBINPROGRESS:
4604  case TBLOCK_SUBABORT:
4605  break;
4606 
4607  /* These cases are invalid. */
4608  case TBLOCK_DEFAULT:
4609  case TBLOCK_STARTED:
4610  case TBLOCK_BEGIN:
4612  case TBLOCK_SUBBEGIN:
4613  case TBLOCK_END:
4614  case TBLOCK_SUBRELEASE:
4615  case TBLOCK_SUBCOMMIT:
4616  case TBLOCK_ABORT_END:
4617  case TBLOCK_SUBABORT_END:
4618  case TBLOCK_ABORT_PENDING:
4620  case TBLOCK_SUBRESTART:
4622  case TBLOCK_PREPARE:
4623  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4625  break;
4626  }
4627 
4628  for (target = s; PointerIsValid(target); target = target->parent)
4629  {
4630  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4631  break;
4632  }
4633 
4634  if (!PointerIsValid(target))
4635  ereport(ERROR,
4636  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4637  errmsg("savepoint \"%s\" does not exist", name)));
4638 
4639  /* disallow crossing savepoint level boundaries */
4640  if (target->savepointLevel != s->savepointLevel)
4641  ereport(ERROR,
4642  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4643  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4644 
4645  /*
4646  * Mark "abort pending" all subtransactions up to the target
4647  * subtransaction. The actual aborts will happen when control gets to
4648  * CommitTransactionCommand.
4649  */
4650  xact = CurrentTransactionState;
4651  for (;;)
4652  {
4653  if (xact == target)
4654  break;
4655  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4657  else if (xact->blockState == TBLOCK_SUBABORT)
4659  else
4660  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4662  xact = xact->parent;
4663  Assert(PointerIsValid(xact));
4664  }
4665 
4666  /* And mark the target as "restart pending" */
4667  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4668  xact->blockState = TBLOCK_SUBRESTART;
4669  else if (xact->blockState == TBLOCK_SUBABORT)
4671  else
4672  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4674 }

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), IsParallelWorker, TransactionStateData::name, name, TransactionStateData::parent, PointerIsValid, TransactionStateData::savepointLevel, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by pa_stream_abort(), and standard_ProcessUtility().

◆ SaveTransactionCharacteristics()

◆ SerializeTransactionState()

void SerializeTransactionState ( Size  maxsize,
char *  start_address 
)

Definition at line 5527 of file xact.c.

5528 {
5529  TransactionState s;
5530  Size nxids = 0;
5531  Size i = 0;
5532  TransactionId *workspace;
5534 
5535  result = (SerializedTransactionState *) start_address;
5536 
5537  result->xactIsoLevel = XactIsoLevel;
5538  result->xactDeferrable = XactDeferrable;
5540  result->currentFullTransactionId =
5543 
5544  /*
5545  * If we're running in a parallel worker and launching a parallel worker
5546  * of our own, we can just pass along the information that was passed to
5547  * us.
5548  */
5549  if (nParallelCurrentXids > 0)
5550  {
5552  memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5554  return;
5555  }
5556 
5557  /*
5558  * OK, we need to generate a sorted list of XIDs that our workers should
5559  * view as current. First, figure out how many there are.
5560  */
5561  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5562  {
5564  nxids = add_size(nxids, 1);
5565  nxids = add_size(nxids, s->nChildXids);
5566  }
5568  <= maxsize);
5569 
5570  /* Copy them to our scratch space. */
5571  workspace = palloc(nxids * sizeof(TransactionId));
5572  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5573  {
5575  workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5576  if (s->nChildXids > 0)
5577  memcpy(&workspace[i], s->childXids,
5578  s->nChildXids * sizeof(TransactionId));
5579  i += s->nChildXids;
5580  }
5581  Assert(i == nxids);
5582 
5583  /* Sort them. */
5584  qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5585 
5586  /* Copy data into output area. */
5587  result->nParallelCurrentXids = nxids;
5588  memcpy(&result->parallelCurrentXids[0], workspace,
5589  nxids * sizeof(TransactionId));
5590 }
int i
Definition: isn.c:73
#define qsort(a, b, c, d)
Definition: port.h:447
FullTransactionId currentFullTransactionId
Definition: xact.c:231
FullTransactionId topFullTransactionId
Definition: xact.c:230
CommandId currentCommandId
Definition: xact.c:232
TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.c:234
static TransactionId * ParallelCurrentXids
Definition: xact.c:126
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:152

References add_size(), Assert, TransactionStateData::childXids, SerializedTransactionState::currentCommandId, currentCommandId, SerializedTransactionState::currentFullTransactionId, CurrentTransactionState, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, i, TransactionStateData::nChildXids, nParallelCurrentXids, SerializedTransactionState::nParallelCurrentXids, palloc(), ParallelCurrentXids, SerializedTransactionState::parallelCurrentXids, TransactionStateData::parent, qsort, SerializedTransactionStateHeaderSize, SerializedTransactionState::topFullTransactionId, XactDeferrable, SerializedTransactionState::xactDeferrable, XactIsoLevel, SerializedTransactionState::xactIsoLevel, XactTopFullTransactionId, xidComparator(), and XidFromFullTransactionId.

Referenced by InitializeParallelDSM().

◆ SetCurrentStatementStartTimestamp()

void SetCurrentStatementStartTimestamp ( void  )

◆ SetParallelStartTimestamps()

void SetParallelStartTimestamps ( TimestampTz  xact_ts,
TimestampTz  stmt_ts 
)

Definition at line 858 of file xact.c.

859 {
861  xactStartTimestamp = xact_ts;
862  stmtStartTimestamp = stmt_ts;
863 }

References Assert, IsParallelWorker, stmtStartTimestamp, and xactStartTimestamp.

Referenced by ParallelWorkerMain().

◆ ShowTransactionState()

static void ShowTransactionState ( const char *  str)
static

Definition at line 5635 of file xact.c.

5636 {
5637  /* skip work if message will definitely not be printed */
5640 }
bool message_level_is_interesting(int elevel)
Definition: elog.c:272
#define DEBUG5
Definition: elog.h:26
const char * str
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition: xact.c:5647

References CurrentTransactionState, DEBUG5, message_level_is_interesting(), ShowTransactionStateRec(), and str.

Referenced by AbortSubTransaction(), CleanupSubTransaction(), CommitSubTransaction(), CommitTransaction(), PrepareTransaction(), StartSubTransaction(), and StartTransaction().

◆ ShowTransactionStateRec()

static void ShowTransactionStateRec ( const char *  str,
TransactionState  s 
)
static

Definition at line 5647 of file xact.c.

5648 {
5650 
5651  if (s->parent)
5652  {
5653  /*
5654  * Since this function recurses, it could be driven to stack overflow.
5655  * This is just a debugging aid, so we can leave out some details
5656  * instead of erroring out with check_stack_depth().
5657  */
5658  if (stack_is_too_deep())
5659  ereport(DEBUG5,
5660  (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5661  str, s->nestingLevel)));
5662  else
5664  }
5665 
5666  initStringInfo(&buf);
5667  if (s->nChildXids > 0)
5668  {
5669  int i;
5670 
5671  appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5672  for (i = 1; i < s->nChildXids; i++)
5673  appendStringInfo(&buf, " %u", s->childXids[i]);
5674  }
5675  ereport(DEBUG5,
5676  (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5677  str, s->nestingLevel,
5678  PointerIsValid(s->name) ? s->name : "unnamed",
5681  (unsigned int) XidFromFullTransactionId(s->fullTransactionId),
5682  (unsigned int) s->subTransactionId,
5683  (unsigned int) currentCommandId,
5684  currentCommandIdUsed ? " (used)" : "",
5685  buf.data)));
5686  pfree(buf.data);
5687 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
static char * buf
Definition: pg_test_fsync.c:73
bool stack_is_too_deep(void)
Definition: postgres.c:3578
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

References appendStringInfo(), TransactionStateData::blockState, BlockStateAsString(), buf, TransactionStateData::childXids, currentCommandId, currentCommandIdUsed, DEBUG5, ereport, errmsg_internal(), TransactionStateData::fullTransactionId, i, initStringInfo(), TransactionStateData::name, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, TransactionStateData::parent, pfree(), PointerIsValid, stack_is_too_deep(), TransactionStateData::state, str, TransactionStateData::subTransactionId, TransStateAsString(), and XidFromFullTransactionId.

Referenced by ShowTransactionState().

◆ StartParallelWorkerTransaction()

void StartParallelWorkerTransaction ( char *  tstatespace)

◆ StartSubTransaction()

static void StartSubTransaction ( void  )
static

Definition at line 5060 of file xact.c.

5061 {
5063 
5064  if (s->state != TRANS_DEFAULT)
5065  elog(WARNING, "StartSubTransaction while in %s state",
5067 
5068  s->state = TRANS_START;
5069 
5070  /*
5071  * Initialize subsystems for new subtransaction
5072  *
5073  * must initialize resource-management stuff first
5074  */
5078 
5079  s->state = TRANS_INPROGRESS;
5080 
5081  /*
5082  * Call start-of-subxact callbacks
5083  */
5085  s->parent->subTransactionId);
5086 
5087  ShowTransactionState("StartSubTransaction");
5088 }
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5307
static void AtSubStart_ResourceOwner(void)
Definition: xact.c:1282
static void AtSubStart_Memory(void)
Definition: xact.c:1253
@ SUBXACT_EVENT_START_SUB
Definition: xact.h:142

References AfterTriggerBeginSubXact(), AtSubStart_Memory(), AtSubStart_ResourceOwner(), CallSubXactCallbacks(), CurrentTransactionState, elog, TransactionStateData::parent, ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_START_SUB, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_START, TransStateAsString(), and WARNING.

Referenced by CommitTransactionCommandInternal().

◆ StartTransaction()

static void StartTransaction ( void  )
static

Definition at line 2053 of file xact.c.

2054 {
2055  TransactionState s;
2056  VirtualTransactionId vxid;
2057 
2058  /*
2059  * Let's just make sure the state stack is empty
2060  */
2063 
2065 
2066  /* check the current transaction state */
2067  Assert(s->state == TRANS_DEFAULT);
2068 
2069  /*
2070  * Set the current transaction state information appropriately during
2071  * start processing. Note that once the transaction status is switched
2072  * this process cannot fail until the user ID and the security context
2073  * flags are fetched below.
2074  */
2075  s->state = TRANS_START;
2076  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2077 
2078  /* Determine if statements are logged in this transaction */
2080  (log_xact_sample_rate == 1 ||
2082 
2083  /*
2084  * initialize current transaction state fields
2085  *
2086  * note: prevXactReadOnly is not used at the outermost level
2087  */
2088  s->nestingLevel = 1;
2089  s->gucNestLevel = 1;
2090  s->childXids = NULL;
2091  s->nChildXids = 0;
2092  s->maxChildXids = 0;
2093 
2094  /*
2095  * Once the current user ID and the security context flags are fetched,
2096  * both will be properly reset even if transaction startup fails.
2097  */
2099 
2100  /* SecurityRestrictionContext should never be set outside a transaction */
2101  Assert(s->prevSecContext == 0);
2102 
2103  /*
2104  * Make sure we've reset xact state variables
2105  *
2106  * If recovery is still in progress, mark this transaction as read-only.
2107  * We have lower level defences in XLogInsert and elsewhere to stop us
2108  * from modifying data during recovery, but this gives the normal
2109  * indication to the user that the transaction is read-only.
2110  */
2111  if (RecoveryInProgress())
2112  {
2113  s->startedInRecovery = true;
2114  XactReadOnly = true;
2115  }
2116  else
2117  {
2118  s->startedInRecovery = false;
2120  }
2123  forceSyncCommit = false;
2124  MyXactFlags = 0;
2125 
2126  /*
2127  * reinitialize within-transaction counters
2128  */
2132  currentCommandIdUsed = false;
2133 
2134  /*
2135  * initialize reported xid accounting
2136  */
2137  nUnreportedXids = 0;
2138  s->didLogXid = false;
2139 
2140  /*
2141  * must initialize resource-management stuff first
2142  */
2143  AtStart_Memory();
2145 
2146  /*
2147  * Assign a new LocalTransactionId, and combine it with the proc number to
2148  * form a virtual transaction id.
2149  */
2150  vxid.procNumber = MyProcNumber;
2152 
2153  /*
2154  * Lock the virtual transaction id before we announce it in the proc array
2155  */
2157 
2158  /*
2159  * Advertise it in the proc array. We assume assignment of
2160  * localTransactionId is atomic, and the proc number should be set
2161  * already.
2162  */
2165 
2166  TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2167 
2168  /*
2169  * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2170  * be the same as the first command's statement_timestamp(), so don't do a
2171  * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2172  * for transactions started inside procedures (i.e., nonatomic SPI
2173  * contexts), we do need to advance the timestamp. Also, in a parallel
2174  * worker, the timestamp should already have been provided by a call to
2175  * SetParallelStartTimestamps().
2176  */
2177  if (!IsParallelWorker())
2178  {
2181  else
2183  }
2184  else
2185  Assert(xactStartTimestamp != 0);
2187  /* Mark xactStopTimestamp as unset. */
2188  xactStopTimestamp = 0;
2189 
2190  /*
2191  * initialize other subsystems for new transaction
2192  */
2193  AtStart_GUC();
2194  AtStart_Cache();
2196 
2197  /*
2198  * done with start processing, set current transaction state to "in
2199  * progress"
2200  */
2201  s->state = TRANS_INPROGRESS;
2202 
2203  /* Schedule transaction timeout */
2204  if (TransactionTimeout > 0)
2206 
2207  ShowTransactionState("StartTransaction");
2208 }
#define TopSubTransactionId
Definition: c.h:650
#define FirstCommandId
Definition: c.h:659
ProcNumber MyProcNumber
Definition: globals.c:89
void AtStart_GUC(void)
Definition: guc.c:2214
double log_xact_sample_rate
Definition: guc_tables.c:530
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4519
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:268
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:701
bool SPI_inside_nonatomic_context(void)
Definition: spi.c:581
ProcNumber procNumber
Definition: proc.h:195
LocalTransactionId localTransactionId
Definition: lock.h:62
ProcNumber procNumber
Definition: lock.h:61
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:560
void AfterTriggerBeginXact(void)
Definition: trigger.c:4992
static void AtStart_Memory(void)
Definition: xact.c:1175
bool DefaultXactDeferrable
Definition: xact.c:83
static void AtStart_ResourceOwner(void)
Definition: xact.c:1225
static void AtStart_Cache(void)
Definition: xact.c:1166
int DefaultXactIsoLevel
Definition: xact.c:77
bool xact_is_sampled
Definition: xact.c:295
bool DefaultXactReadOnly
Definition: xact.c:80
bool RecoveryInProgress(void)
Definition: xlog.c:6333

References AfterTriggerBeginXact(), Assert, AtStart_Cache(), AtStart_GUC(), AtStart_Memory(), AtStart_ResourceOwner(), TransactionStateData::childXids, currentCommandId, currentCommandIdUsed, currentSubTransactionId, CurrentTransactionState, DefaultXactDeferrable, DefaultXactIsoLevel, DefaultXactReadOnly, TransactionStateData::didLogXid, enable_timeout_after(), FirstCommandId, forceSyncCommit, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetCurrentTimestamp(), GetNextLocalTransactionId(), GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, IsParallelWorker, VirtualTransactionId::localTransactionId, log_xact_sample_rate, PGPROC::lxid, TransactionStateData::maxChildXids, MyProc, MyProcNumber, MyXactFlags, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nUnreportedXids, pg_global_prng_state, pg_prng_double(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, VirtualTransactionId::procNumber, PGPROC::procNumber, RecoveryInProgress(), ShowTransactionState(), SPI_inside_nonatomic_context(), TransactionStateData::startedInRecovery, TransactionStateData::state, stmtStartTimestamp, TransactionStateData::subTransactionId, TopSubTransactionId, TopTransactionStateData, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_START, TRANSACTION_TIMEOUT, TransactionTimeout, VirtualXactLockTableInsert(), PGPROC::vxid, xact_is_sampled, XactDeferrable, XactIsoLevel, XactReadOnly, xactStartTimestamp, xactStopTimestamp, and XactTopFullTransactionId.

Referenced by _doSetFixedOutputState(), CommitTransactionCommandInternal(), restore_toc_entry(), RestoreArchive(), StartParallelWorkerTransaction(), StartRestoreLOs(), and StartTransactionCommand().

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

Definition at line 3039 of file xact.c.

3040 {
3042 
3043  switch (s->blockState)
3044  {
3045  /*
3046  * if we aren't in a transaction block, we just do our usual start
3047  * transaction.
3048  */
3049  case TBLOCK_DEFAULT:
3050  StartTransaction();
3052  break;
3053 
3054  /*
3055  * We are somewhere in a transaction block or subtransaction and
3056  * about to start a new command. For now we do nothing, but
3057  * someday we may do command-local resource initialization. (Note
3058  * that any needed CommandCounterIncrement was done by the
3059  * previous CommitTransactionCommand.)
3060  */
3061  case TBLOCK_INPROGRESS:
3063  case TBLOCK_SUBINPROGRESS:
3064  break;
3065 
3066  /*
3067  * Here we are in a failed transaction block (one of the commands
3068  * caused an abort) so we do nothing but remain in the abort
3069  * state. Eventually we will get a ROLLBACK command which will
3070  * get us out of this state. (It is up to other code to ensure
3071  * that no commands other than ROLLBACK will be processed in these
3072  * states.)
3073  */
3074  case TBLOCK_ABORT:
3075  case TBLOCK_SUBABORT:
3076  break;
3077 
3078  /* These cases are invalid. */
3079  case TBLOCK_STARTED:
3080  case TBLOCK_BEGIN:
3082  case TBLOCK_SUBBEGIN:
3083  case TBLOCK_END:
3084  case TBLOCK_SUBRELEASE:
3085  case TBLOCK_SUBCOMMIT:
3086  case TBLOCK_ABORT_END:
3087  case TBLOCK_SUBABORT_END:
3088  case TBLOCK_ABORT_PENDING:
3090  case TBLOCK_SUBRESTART:
3092  case TBLOCK_PREPARE:
3093  elog(ERROR, "StartTransactionCommand: unexpected state %s",
3095  break;
3096  }
3097 
3098  /*
3099  * We must switch to CurTransactionContext before returning. This is
3100  * already done if we called StartTransaction, otherwise not.
3101  */
3102  Assert(CurTransactionContext != NULL);
3104 }

References Assert, TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, CurTransactionContext, elog, ERROR, MemoryContextSwitchTo(), StartTransaction(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by _SPI_commit(), _SPI_rollback(), apply_handle_commit_internal(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), begin_replication_step(), BeginInternalSubTransaction(), BootstrapModeMain(), clear_subscription_skip_lsn(), cluster(), cluster_multiple_rels(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), FetchTableStates(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), ParallelApplyWorkerMain(), ParallelWorkerMain(), perform_work_item(), pg_attribute_noreturn(), process_syncing_tables_for_apply(), process_syncing_tables_for_sync(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), ReorderBufferProcessTXN(), run_apply_worker(), shell_check_detail(), SnapBuildExportSnapshot(), start_xact_command(), synchronize_slots(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 804 of file xact.c.

805 {
807 
808  for (s = CurrentTransactionState; s != NULL; s = s->parent)
809  {
810  if (s->state == TRANS_ABORT)
811  continue;
812  if (s->subTransactionId == subxid)
813  return true;
814  }
815  return false;
816 }

References CurrentTransactionState, TransactionStateData::parent, TransactionStateData::state, TransactionStateData::subTransactionId, and TRANS_ABORT.

Referenced by fmgr_sql().

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 4996 of file xact.c.

4997 {
4999 
5000  switch (s->blockState)
5001  {
5002  case TBLOCK_DEFAULT:
5003  case TBLOCK_STARTED:
5004  return 'I'; /* idle --- not in transaction */
5005  case TBLOCK_BEGIN:
5006  case TBLOCK_SUBBEGIN:
5007  case TBLOCK_INPROGRESS:
5010  case TBLOCK_SUBINPROGRESS:
5011  case TBLOCK_END:
5012  case TBLOCK_SUBRELEASE:
5013  case TBLOCK_SUBCOMMIT:
5014  case TBLOCK_PREPARE:
5015  return 'T'; /* in transaction */
5016  case TBLOCK_ABORT:
5017  case TBLOCK_SUBABORT:
5018  case TBLOCK_ABORT_END:
5019  case TBLOCK_SUBABORT_END:
5020  case TBLOCK_ABORT_PENDING:
5022  case TBLOCK_SUBRESTART:
5024  return 'E'; /* in failed transaction */
5025  }
5026 
5027  /* should never get here */
5028  elog(FATAL, "invalid transaction block state: %s",
5030  return 0; /* keep compiler quiet */
5031 }

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog, FATAL, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by ReadyForQuery().

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

Definition at line 940 of file xact.c.

941 {
943 
944  /*
945  * We always say that BootstrapTransactionId is "not my transaction ID"
946  * even when it is (ie, during bootstrap). Along with the fact that
947  * transam.c always treats BootstrapTransactionId as already committed,
948  * this causes the heapam_visibility.c routines to see all tuples as
949  * committed, which is what we need during bootstrap. (Bootstrap mode
950  * only inserts tuples, it never updates or deletes them, so all tuples
951  * can be presumed good immediately.)
952  *
953  * Likewise, InvalidTransactionId and FrozenTransactionId are certainly
954  * not my transaction ID, so we can just return "false" immediately for
955  * any non-normal XID.
956  */
957  if (!TransactionIdIsNormal(xid))
958  return false;
959 
961  return true;
962 
963  /*
964  * In parallel workers, the XIDs we must consider as current are stored in
965  * ParallelCurrentXids rather than the transaction-state stack. Note that
966  * the XIDs in this array are sorted numerically rather than according to
967  * transactionIdPrecedes order.
968  */
969  if (nParallelCurrentXids > 0)
970  {
971  int low,
972  high;
973 
974  low = 0;
975  high = nParallelCurrentXids - 1;
976  while (low <= high)
977  {
978  int middle;
979  TransactionId probe;
980 
981  middle = low + (high - low) / 2;
982  probe = ParallelCurrentXids[middle];
983  if (probe == xid)
984  return true;
985  else if (probe < xid)
986  low = middle + 1;
987  else
988  high = middle - 1;
989  }
990  return false;
991  }
992 
993  /*
994  * We will return true for the Xid of the current subtransaction, any of
995  * its subcommitted children, any of its parents, or any of their
996  * previously subcommitted children. However, a transaction being aborted
997  * is no longer "current", even though it may still have an entry on the
998  * state stack.
999  */
1000  for (s = CurrentTransactionState; s != NULL; s = s->parent)
1001  {
1002  int low,
1003  high;
1004 
1005  if (s->state == TRANS_ABORT)
1006  continue;
1008  continue; /* it can't have any child XIDs either */
1010  return true;
1011  /* As the childXids array is ordered, we can use binary search */
1012  low = 0;
1013  high = s->nChildXids - 1;
1014  while (low <= high)
1015  {
1016  int middle;
1017  TransactionId probe;
1018 
1019  middle = low + (high - low) / 2;
1020  probe = s->childXids[middle];
1021  if (TransactionIdEquals(probe, xid))
1022  return true;
1023  else if (TransactionIdPrecedes(probe, xid))
1024  low = middle + 1;
1025  else
1026  high = middle - 1;
1027  }
1028  }
1029 
1030  return false;
1031 }
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

References TransactionStateData::childXids, CurrentTransactionState, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetTopTransactionIdIfAny(), TransactionStateData::nChildXids, nParallelCurrentXids, ParallelCurrentXids, TransactionStateData::parent, TransactionStateData::state, TRANS_ABORT, TransactionIdEquals, TransactionIdIsNormal, TransactionIdPrecedes(), and XidFromFullTransactionId.

Referenced by compute_new_xmax_infomask(), Do_MultiXactIdWait(), DoesMultiXactIdConflict(), ExecCheckTupleVisible(), ExecMergeMatched(), ExecOnConflictUpdate(), FreezeMultiXactId(), heap_delete(), heap_inplace_lock(), heap_lock_tuple(), heap_update(), heapam_index_build_range_scan(), heapam_relation_copy_for_cluster(), heapam_scan_analyze_next_tuple(), heapam_tuple_lock(), HeapTupleHeaderAdjustCmax(), HeapTupleHeaderGetCmax(), HeapTupleHeaderGetCmin(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuumHorizon(), MultiXactIdIsRunning(), PredicateLockTID(), SnapBuildWaitSnapshot(), test_lockmode_for_conflict(), TransactionIdIsInProgress(), tts_buffer_is_current_xact_tuple(), and tts_heap_is_current_xact_tuple().

◆ TransactionStartedDuringRecovery()

bool TransactionStartedDuringRecovery ( void  )

Definition at line 1041 of file xact.c.

1042 {
1044 }

References CurrentTransactionState, and TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

◆ TransStateAsString()

static const char * TransStateAsString ( TransState  state)
static

Definition at line 5747 of file xact.c.

5748 {
5749  switch (state)
5750  {
5751  case TRANS_DEFAULT:
5752  return "DEFAULT";
5753  case TRANS_START:
5754  return "START";
5755  case TRANS_INPROGRESS:
5756  return "INPROGRESS";
5757  case TRANS_COMMIT:
5758  return "COMMIT";
5759  case TRANS_ABORT:
5760  return "ABORT";
5761  case TRANS_PREPARE:
5762  return "PREPARE";
5763  }
5764  return "UNRECOGNIZED";
5765 }
Definition: regguts.h:323

References TRANS_ABORT, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_PREPARE, and TRANS_START.

Referenced by AbortSubTransaction(), AbortTransaction(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), PopTransaction(), PrepareTransaction(), ShowTransactionStateRec(), and StartSubTransaction().

◆ UnregisterSubXactCallback()

void UnregisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3870 of file xact.c.

3871 {
3872  SubXactCallbackItem *item;
3873  SubXactCallbackItem *prev;
3874 
3875  prev = NULL;
3876  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3877  {
3878  if (item->callback == callback && item->arg == arg)
3879  {
3880  if (prev)
3881  prev->next = item->next;
3882  else
3883  SubXact_callbacks = item->next;
3884  pfree(item);
3885  break;
3886  }
3887  }
3888 }

References SubXactCallbackItem::arg, arg, SubXactCallbackItem::callback, callback(), SubXactCallbackItem::next, pfree(), and SubXact_callbacks.

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3810 of file xact.c.

3811 {
3812  XactCallbackItem *item;
3813  XactCallbackItem *prev;
3814 
3815  prev = NULL;
3816  for (item = Xact_callbacks; item; prev = item, item = item->next)
3817  {
3818  if (item->callback == callback && item->arg == arg)
3819  {
3820  if (prev)
3821  prev->next = item->next;
3822  else
3823  Xact_callbacks = item->next;
3824  pfree(item);
3825  break;
3826  }
3827  }
3828 }

References XactCallbackItem::arg, arg, XactCallbackItem::callback, callback(), XactCallbackItem::next, pfree(), and Xact_callbacks.

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4197 of file xact.c.

4198 {
4200 
4201  switch (s->blockState)
4202  {
4203  /*
4204  * We are inside a transaction block and we got a ROLLBACK command
4205  * from the user, so tell CommitTransactionCommand to abort and
4206  * exit the transaction block.
4207  */
4208  case TBLOCK_INPROGRESS:
4210  break;
4211 
4212  /*
4213  * We are inside a failed transaction block and we got a ROLLBACK
4214  * command from the user. Abort processing is already done, so
4215  * CommitTransactionCommand just has to cleanup and go back to
4216  * idle state.
4217  */
4218  case TBLOCK_ABORT:
4220  break;
4221 
4222  /*
4223  * We are inside a subtransaction. Mark everything up to top
4224  * level as exitable.
4225  */
4226  case TBLOCK_SUBINPROGRESS:
4227  case TBLOCK_SUBABORT:
4228  while (s->parent != NULL)
4229  {
4230  if (s->blockState == TBLOCK_SUBINPROGRESS)
4232  else if (s->blockState == TBLOCK_SUBABORT)
4234  else
4235  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4237  s = s->parent;
4238  }
4239  if (s->blockState == TBLOCK_INPROGRESS)
4241  else if (s->blockState == TBLOCK_ABORT)
4243  else
4244  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4246  break;
4247 
4248  /*
4249  * The user issued ABORT when not inside a transaction. For
4250  * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4251  * The upcoming call to CommitTransactionCommand() will then put
4252  * us back into the default state. For ROLLBACK AND CHAIN, error.
4253  *
4254  * We do the same thing with ABORT inside an implicit transaction,
4255  * although in this case we might be rolling back actual database
4256  * state changes. (It's debatable whether we should issue a
4257  * WARNING in this case, but we have done so historically.)
4258  */
4259  case TBLOCK_STARTED:
4261  if (chain)
4262  ereport(ERROR,
4263  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4264  /* translator: %s represents an SQL statement name */
4265  errmsg("%s can only be used in transaction blocks",
4266  "ROLLBACK AND CHAIN")));
4267  else
4268  ereport(WARNING,
4269  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4270  errmsg("there is no transaction in progress")));
4272  break;
4273 
4274  /*
4275  * The user issued an ABORT that somehow ran inside a parallel
4276  * worker. We can't cope with that.
4277  */
4279  ereport(FATAL,
4280  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4281  errmsg("cannot abort during a parallel operation")));
4282  break;
4283 
4284  /* These cases are invalid. */
4285  case TBLOCK_DEFAULT:
4286  case TBLOCK_BEGIN:
4287  case TBLOCK_SUBBEGIN:
4288  case TBLOCK_END:
4289  case TBLOCK_SUBRELEASE:
4290  case TBLOCK_SUBCOMMIT:
4291  case TBLOCK_ABORT_END:
4292  case TBLOCK_SUBABORT_END:
4293  case TBLOCK_ABORT_PENDING:
4295  case TBLOCK_SUBRESTART:
4297  case TBLOCK_PREPARE:
4298  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4300  break;
4301  }
4302 
4305 
4306  s->chain = chain;
4307 }

References Assert, TransactionStateData::blockState, BlockStateAsString(), TransactionStateData::chain, CurrentTransactionState, elog, ereport, errcode(), errmsg(), ERROR, FATAL, TransactionStateData::parent, TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and WARNING.

Referenced by standard_ProcessUtility().

◆ WarnNoTransactionBlock()

void WarnNoTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3700 of file xact.c.

3701 {
3702  CheckTransactionBlock(isTopLevel, false, stmtType);
3703 }

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6350 of file xact.c.

6351 {
6352  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6353 
6354  /* Backup blocks are not used in xact records */
6355  Assert(!XLogRecHasAnyBlockRefs(record));
6356 
6357  if (info == XLOG_XACT_COMMIT)
6358  {
6359  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6360  xl_xact_parsed_commit parsed;
6361 
6362  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6363  xact_redo_commit(&parsed, XLogRecGetXid(record),
6364  record->EndRecPtr, XLogRecGetOrigin(record));
6365  }
6366  else if (info == XLOG_XACT_COMMIT_PREPARED)
6367  {
6368  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6369  xl_xact_parsed_commit parsed;
6370 
6371  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6372  xact_redo_commit(&parsed, parsed.twophase_xid,
6373  record->EndRecPtr, XLogRecGetOrigin(record));
6374 
6375  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6376  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6377  PrepareRedoRemove(parsed.twophase_xid, false);
6378  LWLockRelease(TwoPhaseStateLock);
6379  }
6380  else if (info == XLOG_XACT_ABORT)
6381  {
6382  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6383  xl_xact_parsed_abort parsed;
6384 
6385  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6386  xact_redo_abort(&parsed, XLogRecGetXid(record),
6387  record->EndRecPtr, XLogRecGetOrigin(record));
6388  }
6389  else if (info == XLOG_XACT_ABORT_PREPARED)
6390  {
6391  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6392  xl_xact_parsed_abort parsed;
6393 
6394  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6395  xact_redo_abort(&parsed, parsed.twophase_xid,
6396  record->EndRecPtr, XLogRecGetOrigin(record));
6397 
6398  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6399  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6400  PrepareRedoRemove(parsed.twophase_xid, false);
6401  LWLockRelease(TwoPhaseStateLock);
6402  }
6403  else if (info == XLOG_XACT_PREPARE)
6404  {
6405  /*
6406  * Store xid and start/end pointers of the WAL record in TwoPhaseState
6407  * gxact entry.
6408  */
6409  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6411  record->ReadRecPtr,
6412  record->EndRecPtr,
6413  XLogRecGetOrigin(record));
6414  LWLockRelease(TwoPhaseStateLock);
6415  }
6416  else if (info == XLOG_XACT_ASSIGNMENT)
6417  {
6419 
6422  xlrec->nsubxacts, xlrec->xsub);
6423  }
6424  else if (info == XLOG_XACT_INVALIDATIONS)
6425  {
6426  /*
6427  * XXX we do ignore this for now, what matters are invalidations
6428  * written into the commit record.
6429  */
6430  }
6431  else
6432  elog(PANIC, "xact_redo: unknown op code %u", info);
6433 }
unsigned char uint8
Definition: c.h:504
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
@ LW_EXCLUSIVE
Definition: lwlock.h:114
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:1318
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:206
TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:222
TransactionId twophase_xid
Definition: xact.h:427
TransactionId twophase_xid
Definition: xact.h:397
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2588
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2486
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6117
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6271
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:172
#define XLOG_XACT_INVALIDATIONS
Definition: xact.h:175
#define XLOG_XACT_PREPARE
Definition: xact.h:170
#define XLOG_XACT_COMMIT
Definition: xact.h:169
#define XLOG_XACT_OPMASK
Definition: xact.h:179
#define XLOG_XACT_ABORT
Definition: xact.h:171
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:173
void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
Definition: xactdesc.c:35
void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
Definition: xactdesc.c:141
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:413
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLogRecGetXid(decoder)
Definition: xlogreader.h:412
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:417
HotStandbyState standbyState
Definition: xlogutils.c:53
@ STANDBY_INITIALIZED
Definition: xlogutils.h:53

References Assert, elog, XLogReaderState::EndRecPtr, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_xact_assignment::nsubxacts, PANIC, ParseAbortRecord(), ParseCommitRecord(), PrepareRedoAdd(), PrepareRedoRemove(), ProcArrayApplyXidAssignment(), XLogReaderState::ReadRecPtr, STANDBY_INITIALIZED, standbyState, xl_xact_parsed_commit::twophase_xid, xl_xact_parsed_abort::twophase_xid, xact_redo_abort(), xact_redo_commit(), XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_ASSIGNMENT, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_INVALIDATIONS, XLOG_XACT_OPMASK, XLOG_XACT_PREPARE, XLogRecGetData, XLogRecGetInfo, XLogRecGetOrigin, XLogRecGetXid, XLogRecHasAnyBlockRefs, xl_xact_assignment::xsub, and xl_xact_assignment::xtop.

◆ xact_redo_abort()

static void xact_redo_abort ( xl_xact_parsed_abort parsed,
TransactionId  xid,
XLogRecPtr  lsn,
RepOriginId  origin_id 
)
static

Definition at line 6271 of file xact.c.

6273 {
6274  TransactionId max_xid;
6275 
6277 
6278  /* Make sure nextXid is beyond any XID mentioned in the record. */
6279  max_xid = TransactionIdLatest(xid,
6280  parsed->nsubxacts,
6281  parsed->subxacts);
6283 
6285  {
6286  /* Mark the transaction aborted in pg_xact, no need for async stuff */
6287  TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6288  }
6289  else
6290  {
6291  /*
6292  * If a transaction completion record arrives that has as-yet
6293  * unobserved subtransactions then this will not have been fully
6294  * handled by the call to RecordKnownAssignedTransactionIds() in the
6295  * main recovery loop in xlog.c. So we need to do bookkeeping again to
6296  * cover that case. This is confusing and it is easy to think this
6297  * call is irrelevant, which has happened three times in development
6298  * already. Leave it in.
6299  */
6301 
6302  /* Mark the transaction aborted in pg_xact, no need for async stuff */
6303  TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6304 
6305  /*
6306  * We must update the ProcArray after we have marked clog.
6307  */
6308  ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6309 
6310  /*
6311  * There are no invalidation messages to send or undo.
6312  */
6313 
6314  /*
6315  * Release locks, if any. There are no invalidations to send.
6316  */
6317  if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6318  StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6319  }
6320 
6321  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6322  {
6323  /* recover apply progress */
6324  replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6325  false /* backward */ , false /* WAL */ );
6326  }
6327 
6328  /* Make sure files supposed to be dropped are dropped */
6329  if (parsed->nrels > 0)
6330  {
6331  /*
6332  * See comments about update of minimum recovery point on truncation,
6333  * in xact_redo_commit().
6334  */
6335  XLogFlush(lsn);
6336 
6337  DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6338  }
6339 
6340  if (parsed->nstats > 0)
6341  {
6342  /* see equivalent call for relations above */
6343  XLogFlush(lsn);
6344 
6345  pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6346  }
6347 }
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
Definition: md.c:1467
void replorigin_advance(RepOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition: origin.c:892
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
Definition: pgstat_xact.c:314
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition: procarray.c:4407
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition: procarray.c:4476
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition: standby.c:1091
xl_xact_stats_item * stats
Definition: xact.h:425
RelFileLocator * xlocators
Definition: xact.h:422
TransactionId * subxacts
Definition: xact.h:419
XLogRecPtr origin_lsn
Definition: xact.h:430
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition: varsup.c:304
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:193
#define XACT_XINFO_HAS_AE_LOCKS
Definition: xact.h:194
@ STANDBY_DISABLED
Definition: xlogutils.h:52

References AdvanceNextFullTransactionIdPastXid(), Assert, DropRelationFiles(), ExpireTreeKnownAssignedTransactionIds(), xl_xact_parsed_abort::nrels, xl_xact_parsed_abort::nstats, xl_xact_parsed_abort::nsubxacts, xl_xact_parsed_abort::origin_lsn, pgstat_execute_transactional_drops(), RecordKnownAssignedTransactionIds(), replorigin_advance(), STANDBY_DISABLED, StandbyReleaseLockTree(), standbyState, xl_xact_parsed_abort::stats, xl_xact_parsed_abort::subxacts, TransactionIdAbortTree(), TransactionIdIsValid, TransactionIdLatest(), XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_ORIGIN, xl_xact_parsed_abort::xinfo, xl_xact_parsed_abort::xlocators, and XLogFlush().

Referenced by xact_redo().

◆ xact_redo_commit()

static void xact_redo_commit ( xl_xact_parsed_commit parsed,
TransactionId  xid,
XLogRecPtr  lsn,
RepOriginId  origin_id 
)
static

Definition at line 6117 of file xact.c.

6121 {
6122  TransactionId max_xid;
6123  TimestampTz commit_time;
6124 
6126 
6127  max_xid = TransactionIdLatest(xid, parsed->nsubxacts, parsed->subxacts);
6128 
6129  /* Make sure nextXid is beyond any XID mentioned in the record. */
6131 
6132  Assert(((parsed->xinfo & XACT_XINFO_HAS_ORIGIN) == 0) ==
6133  (origin_id == InvalidRepOriginId));
6134 
6135  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6136  commit_time = parsed->origin_timestamp;
6137  else
6138  commit_time = parsed->xact_time;
6139 
6140  /* Set the transaction commit timestamp and metadata */
6141  TransactionTreeSetCommitTsData(xid, parsed->nsubxacts, parsed->subxacts,
6142  commit_time, origin_id);
6143 
6145  {
6146  /*
6147  * Mark the transaction committed in pg_xact.
6148  */
6149  TransactionIdCommitTree(xid, parsed->nsubxacts, parsed->subxacts);
6150  }
6151  else
6152  {
6153  /*
6154  * If a transaction completion record arrives that has as-yet
6155  * unobserved subtransactions then this will not have been fully
6156  * handled by the call to RecordKnownAssignedTransactionIds() in the
6157  * main recovery loop in xlog.c. So we need to do bookkeeping again to
6158  * cover that case. This is confusing and it is easy to think this
6159  * call is irrelevant, which has happened three times in development
6160  * already. Leave it in.
6161  */
6163 
6164  /*
6165  * Mark the transaction committed in pg_xact. We use async commit
6166  * protocol during recovery to provide information on database
6167  * consistency for when users try to set hint bits. It is important
6168  * that we do not set hint bits until the minRecoveryPoint is past
6169  * this commit record. This ensures that if we crash we don't see hint
6170  * bits set on changes made by transactions that haven't yet
6171  * recovered. It's unlikely but it's good to be safe.
6172  */
6173  TransactionIdAsyncCommitTree(xid, parsed->nsubxacts, parsed->subxacts, lsn);
6174 
6175  /*
6176  * We must mark clog before we update the ProcArray.
6177  */
6178  ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6179 
6180  /*
6181  * Send any cache invalidations attached to the commit. We must
6182  * maintain the same order of invalidation then release locks as
6183  * occurs in CommitTransaction().
6184  */
6187  parsed->dbId, parsed->tsId);
6188 
6189  /*
6190  * Release locks, if any. We do this for both two phase and normal one
6191  * phase transactions. In effect we are ignoring the prepare phase and
6192  * just going straight to lock release.
6193  */
6194  if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6195  StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6196  }
6197 
6198  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6199  {
6200  /* recover apply progress */
6201  replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6202  false /* backward */ , false /* WAL */ );
6203  }
6204 
6205  /* Make sure files supposed to be dropped are dropped */
6206  if (parsed->nrels > 0)
6207  {
6208  /*
6209  * First update minimum recovery point to cover this WAL record. Once
6210  * a relation is deleted, there's no going back. The buffer manager
6211  * enforces the WAL-first rule for normal updates to relation files,
6212  * so that the minimum recovery point is always updated before the
6213  * corresponding change in the data file is flushed to disk, but we
6214  * have to do the same here since we're bypassing the buffer manager.
6215  *
6216  * Doing this before deleting the files means that if a deletion fails
6217  * for some reason, you cannot start up the system even after restart,
6218  * until you fix the underlying situation so that the deletion will
6219  * succeed. Alternatively, we could update the minimum recovery point
6220  * after deletion, but that would leave a small window where the
6221  * WAL-first rule would be violated.
6222  */
6223  XLogFlush(lsn);
6224 
6225  /* Make sure files supposed to be dropped are dropped */
6226  DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6227  }
6228 
6229  if (parsed->nstats > 0)
6230  {
6231  /* see equivalent call for relations above */
6232  XLogFlush(lsn);
6233 
6234  pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6235  }
6236 
6237  /*
6238  * We issue an XLogFlush() for the same reason we emit ForceSyncCommit()
6239  * in normal operation. For example, in CREATE DATABASE, we copy all files
6240  * from the template database, and then commit the transaction. If we
6241  * crash after all the files have been copied but before the commit, you
6242  * have files in the data directory without an entry in pg_database. To
6243  * minimize the window for that, we use ForceSyncCommit() to rush the
6244  * commit record to disk as quick as possible. We have the same window
6245  * during recovery, and forcing an XLogFlush() (which updates
6246  * minRecoveryPoint during recovery) helps to reduce that problem window,
6247  * for any user that requested ForceSyncCommit().
6248  */
6249  if (XactCompletionForceSyncCommit(parsed->xinfo))
6250  XLogFlush(lsn);
6251 
6252  /*
6253  * If asked by the primary (because someone is waiting for a synchronous
6254  * commit = remote_apply), we will need to ask walreceiver to send a reply
6255  * immediately.
6256  */
6257  if (XactCompletionApplyFeedback(parsed->xinfo))
6259 }
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
Definition: inval.c:961
xl_xact_stats_item * stats
Definition: xact.h:392
TimestampTz xact_time
Definition: xact.h:379
RelFileLocator * xlocators
Definition: xact.h:389
TimestampTz origin_timestamp
Definition: xact.h:405
TransactionId * subxacts
Definition: xact.h:386
XLogRecPtr origin_lsn
Definition: xact.h:404
SharedInvalidationMessage * msgs
Definition: xact.h:395
#define XactCompletionForceSyncCommit(xinfo)
Definition: xact.h:215
#define XactCompletionApplyFeedback(xinfo)
Definition: xact.h:211
#define XactCompletionRelcacheInitFileInval(xinfo)
Definition: xact.h:213
void XLogRequestWalReceiverReply(void)

References AdvanceNextFullTransactionIdPastXid(), Assert, xl_xact_parsed_commit::dbId, DropRelationFiles(), ExpireTreeKnownAssignedTransactionIds(), InvalidRepOriginId, xl_xact_parsed_commit::msgs, xl_xact_parsed_commit::nmsgs, xl_xact_parsed_commit::nrels, xl_xact_parsed_commit::nstats, xl_xact_parsed_commit::nsubxacts, xl_xact_parsed_commit::origin_lsn, xl_xact_parsed_commit::origin_timestamp, pgstat_execute_transactional_drops(), ProcessCommittedInvalidationMessages(), RecordKnownAssignedTransactionIds(), replorigin_advance(), STANDBY_DISABLED, StandbyReleaseLockTree(), standbyState, xl_xact_parsed_commit::stats, xl_xact_parsed_commit::subxacts, TransactionIdAsyncCommitTree(), TransactionIdCommitTree(), TransactionIdIsValid, TransactionIdLatest(), TransactionTreeSetCommitTsData(), xl_xact_parsed_commit::tsId, xl_xact_parsed_commit::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_ORIGIN, XactCompletionApplyFeedback, XactCompletionForceSyncCommit, XactCompletionRelcacheInitFileInval, xl_xact_parsed_commit::xinfo, xl_xact_parsed_commit::xlocators, XLogFlush(), and XLogRequestWalReceiverReply().

Referenced by xact_redo().

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5777 of file xact.c.

5778 {
5780 
5781  if (s->nChildXids == 0)
5782  *ptr = NULL;
5783  else
5784  *ptr = s->childXids;
5785 
5786  return s->nChildXids;
5787 }

References TransactionStateData::childXids, CurrentTransactionState, and TransactionStateData::nChildXids.

Referenced by ExportSnapshot(), RecordTransactionAbort(), RecordTransactionCommit(), and StartPrepare().

◆ XactLogAbortRecord()

XLogRecPtr XactLogAbortRecord ( TimestampTz  abort_time,
int  nsubxacts,
TransactionId subxacts,
int  nrels,
RelFileLocator rels,
int  ndroppedstats,
xl_xact_stats_item droppedstats,
int  xactflags,
TransactionId  twophase_xid,
const char *  twophase_gid 
)

Definition at line 5973 of file xact.c.

5979 {
5980  xl_xact_abort xlrec;
5981  xl_xact_xinfo xl_xinfo;
5982  xl_xact_subxacts xl_subxacts;
5983  xl_xact_relfilelocators xl_relfilelocators;
5984  xl_xact_stats_items xl_dropped_stats;
5985  xl_xact_twophase xl_twophase;
5986  xl_xact_dbinfo xl_dbinfo;
5987  xl_xact_origin xl_origin;
5988 
5989  uint8 info;
5990 
5991  Assert(CritSectionCount > 0);
5992 
5993  xl_xinfo.xinfo = 0;
5994 
5995  /* decide between a plain and 2pc abort */
5996  if (!TransactionIdIsValid(twophase_xid))
5997  info = XLOG_XACT_ABORT;
5998  else
5999  info = XLOG_XACT_ABORT_PREPARED;
6000 
6001 
6002  /* First figure out and collect all the information needed */
6003 
6004  xlrec.xact_time = abort_time;
6005 
6006  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
6007  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
6008 
6009  if (nsubxacts > 0)
6010  {
6011  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
6012  xl_subxacts.nsubxacts = nsubxacts;
6013  }
6014 
6015  if (nrels > 0)
6016  {
6018  xl_relfilelocators.nrels = nrels;
6019  info |= XLR_SPECIAL_REL_UPDATE;
6020  }
6021 
6022  if (ndroppedstats > 0)
6023  {
6024  xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
6025  xl_dropped_stats.nitems = ndroppedstats;
6026  }
6027 
6028  if (TransactionIdIsValid(twophase_xid))
6029  {
6030  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
6031  xl_twophase.xid = twophase_xid;
6032  Assert(twophase_gid != NULL);
6033 
6034  if (XLogLogicalInfoActive())
6035  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6036  }
6037 
6038  if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6039  {
6040  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6041  xl_dbinfo.dbId = MyDatabaseId;
6042  xl_dbinfo.tsId = MyDatabaseTableSpace;
6043  }
6044 
6045  /*
6046  * Dump transaction origin information. We need this during recovery to
6047  * update the replication origin progress.
6048  */
6050  {
6051  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6052 
6055  }
6056 
6057  if (xl_xinfo.xinfo != 0)
6058  info |= XLOG_XACT_HAS_INFO;
6059 
6060  /* Then include all the collected data into the abort record. */
6061 
6062  XLogBeginInsert();
6063 
6064  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
6065 
6066  if (xl_xinfo.xinfo != 0)
6067  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
6068 
6069  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6070  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
6071 
6072  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6073  {
6074  XLogRegisterData((char *) (&xl_subxacts),
6076  XLogRegisterData((char *) subxacts,
6077  nsubxacts * sizeof(TransactionId));
6078  }
6079 
6080  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
6081  {
6082  XLogRegisterData((char *) (&xl_relfilelocators),
6084  XLogRegisterData((char *) rels,
6085  nrels * sizeof(RelFileLocator));
6086  }
6087 
6088  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6089  {
6090  XLogRegisterData((char *) (&xl_dropped_stats),
6092  XLogRegisterData((char *) droppedstats,
6093  ndroppedstats * sizeof(xl_xact_stats_item));
6094  }
6095 
6096  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6097  {
6098  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
6099  if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6100  XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6101  }
6102 
6103  if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6104  XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
6105 
6106  /* Include the replication origin */
6108 
6109  return XLogInsert(RM_XACT_ID, info);
6110 }
Oid MyDatabaseTableSpace
Definition: globals.c:95
volatile uint32 CritSectionCount
Definition: globals.c:44
TimestampTz xact_time
Definition: xact.h:338
Oid tsId
Definition: xact.h:258
Oid dbId
Definition: xact.h:257
TimestampTz origin_timestamp
Definition: xact.h:317
XLogRecPtr origin_lsn
Definition: xact.h:316
int nsubxacts
Definition: xact.h:263
TransactionId xid
Definition: xact.h:311
uint32 xinfo
Definition: xact.h:252
#define MinSizeOfXactSubxacts
Definition: xact.h:266
#define XACT_XINFO_HAS_GID
Definition: xact.h:195
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:108
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:192
#define MinSizeOfXactRelfileLocators
Definition: xact.h:273
#define MinSizeOfXactStatsItems
Definition: xact.h:300
#define XACT_XINFO_HAS_RELFILELOCATORS
Definition: xact.h:190
#define MinSizeOfXactAbort
Definition: xact.h:350
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:188
#define XLOG_XACT_HAS_INFO
Definition: xact.h:182
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:189
#define XACT_XINFO_HAS_DROPPED_STATS
Definition: xact.h:196
#define XLOG_INCLUDE_ORIGIN
Definition: xlog.h:154
void XLogSetRecordFlags(uint8 flags)
Definition: xloginsert.c:456
#define XLR_SPECIAL_REL_UPDATE
Definition: xlogrecord.h:82

References Assert, CritSectionCount, xl_xact_dbinfo::dbId, InvalidRepOriginId, MinSizeOfXactAbort, MinSizeOfXactRelfileLocators, MinSizeOfXactStatsItems, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, xl_xact_stats_items::nitems, xl_xact_relfilelocators::nrels, xl_xact_subxacts::nsubxacts, xl_xact_origin::origin_lsn, xl_xact_origin::origin_timestamp, replorigin_session_origin, replorigin_session_origin_lsn, replorigin_session_origin_timestamp, TransactionIdIsValid, xl_xact_dbinfo::tsId, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, xl_xact_abort::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_DROPPED_STATS, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILELOCATORS, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, xl_xact_twophase::xid, xl_xact_xinfo::xinfo, XLOG_INCLUDE_ORIGIN, XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogSetRecordFlags(), and XLR_SPECIAL_REL_UPDATE.

Referenced by RecordTransactionAbort(), and RecordTransactionAbortPrepared().

◆ XactLogCommitRecord()

XLogRecPtr XactLogCommitRecord ( TimestampTz  commit_time,
int  nsubxacts,
TransactionId subxacts,
int  nrels,
RelFileLocator rels,
int  ndroppedstats,
xl_xact_stats_item droppedstats,
int  nmsgs,
SharedInvalidationMessage msgs,
bool  relcacheInval,
int  xactflags,
TransactionId  twophase_xid,
const char *  twophase_gid 
)

Definition at line 5801 of file xact.c.

5809 {
5810  xl_xact_commit xlrec;
5811  xl_xact_xinfo xl_xinfo;
5812  xl_xact_dbinfo xl_dbinfo;
5813  xl_xact_subxacts xl_subxacts;
5814  xl_xact_relfilelocators xl_relfilelocators;
5815  xl_xact_stats_items xl_dropped_stats;
5816  xl_xact_invals xl_invals;
5817  xl_xact_twophase xl_twophase;
5818  xl_xact_origin xl_origin;
5819  uint8 info;
5820 
5821  Assert(CritSectionCount > 0);
5822 
5823  xl_xinfo.xinfo = 0;
5824 
5825  /* decide between a plain and 2pc commit */
5826  if (!TransactionIdIsValid(twophase_xid))
5827  info = XLOG_XACT_COMMIT;
5828  else
5830 
5831  /* First figure out and collect all the information needed */
5832 
5833  xlrec.xact_time = commit_time;
5834 
5835  if (relcacheInval)
5837  if (forceSyncCommit)
5839  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5840  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5841 
5842  /*
5843  * Check if the caller would like to ask standbys for immediate feedback
5844  * once this commit is applied.
5845  */
5848 
5849  /*
5850  * Relcache invalidations requires information about the current database
5851  * and so does logical decoding.
5852  */
5853  if (nmsgs > 0 || XLogLogicalInfoActive())
5854  {
5855  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5856  xl_dbinfo.dbId = MyDatabaseId;
5857  xl_dbinfo.tsId = MyDatabaseTableSpace;
5858  }
5859 
5860  if (nsubxacts > 0)
5861  {
5862  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5863  xl_subxacts.nsubxacts = nsubxacts;
5864  }
5865 
5866  if (nrels > 0)
5867  {
5869  xl_relfilelocators.nrels = nrels;
5870  info |= XLR_SPECIAL_REL_UPDATE;
5871  }
5872 
5873  if (ndroppedstats > 0)
5874  {
5875  xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
5876  xl_dropped_stats.nitems = ndroppedstats;
5877  }
5878 
5879  if (nmsgs > 0)
5880  {
5881  xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5882  xl_invals.nmsgs = nmsgs;
5883  }
5884 
5885  if (TransactionIdIsValid(twophase_xid))
5886  {
5887  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5888  xl_twophase.xid = twophase_xid;
5889  Assert(twophase_gid != NULL);
5890 
5891  if (XLogLogicalInfoActive())
5892  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5893  }
5894 
5895  /* dump transaction origin information */
5897  {
5898  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5899 
5902  }
5903 
5904  if (xl_xinfo.xinfo != 0)
5905  info |= XLOG_XACT_HAS_INFO;
5906 
5907  /* Then include all the collected data into the commit record. */
5908 
5909  XLogBeginInsert();
5910 
5911  XLogRegisterData((char *) (&xlrec), sizeof(xl_xact_commit));
5912 
5913  if (xl_xinfo.xinfo != 0)
5914  XLogRegisterData((char *) (&xl_xinfo.xinfo), sizeof(xl_xinfo.xinfo));
5915 
5916  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5917  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
5918 
5919  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5920  {
5921  XLogRegisterData((char *) (&xl_subxacts),
5923  XLogRegisterData((char *) subxacts,
5924  nsubxacts * sizeof(TransactionId));
5925  }
5926 
5927  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
5928  {
5929  XLogRegisterData((char *) (&xl_relfilelocators),
5931  XLogRegisterData((char *) rels,
5932  nrels * sizeof(RelFileLocator));
5933  }
5934 
5935  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5936  {
5937  XLogRegisterData((char *) (&xl_dropped_stats),
5939  XLogRegisterData((char *) droppedstats,
5940  ndroppedstats * sizeof(xl_xact_stats_item));
5941  }
5942 
5943  if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5944  {
5945  XLogRegisterData((char *) (&xl_invals), MinSizeOfXactInvals);
5946  XLogRegisterData((char *) msgs,
5947  nmsgs * sizeof(SharedInvalidationMessage));
5948  }
5949 
5950  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5951  {
5952  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
5953  if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5954  XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5955  }
5956 
5957  if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5958  XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
5959 
5960  /* we allow filtering by xacts */
5962 
5963  return XLogInsert(RM_XACT_ID, info);
5964 }
TimestampTz xact_time
Definition: xact.h:322
int nmsgs
Definition: xact.h:304
#define MinSizeOfXactInvals
Definition: xact.h:307
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE
Definition: xact.h:207
#define XACT_COMPLETION_FORCE_SYNC_COMMIT
Definition: xact.h:208
@ SYNCHRONOUS_COMMIT_REMOTE_APPLY
Definition: xact.h:75
#define XACT_COMPLETION_APPLY_FEEDBACK
Definition: xact.h:206
#define XACT_XINFO_HAS_INVALS
Definition: xact.h:191

References Assert, CritSectionCount, xl_xact_dbinfo::dbId, forceSyncCommit, InvalidRepOriginId, MinSizeOfXactInvals, MinSizeOfXactRelfileLocators, MinSizeOfXactStatsItems, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, xl_xact_stats_items::nitems, xl_xact_invals::nmsgs, xl_xact_relfilelocators::nrels, xl_xact_subxacts::nsubxacts, xl_xact_origin::origin_lsn, xl_xact_origin::origin_timestamp, replorigin_session_origin, replorigin_session_origin_lsn, replorigin_session_origin_timestamp, synchronous_commit, SYNCHRONOUS_COMMIT_REMOTE_APPLY, TransactionIdIsValid, xl_xact_dbinfo::tsId, XACT_COMPLETION_APPLY_FEEDBACK, XACT_COMPLETION_FORCE_SYNC_COMMIT, XACT_COMPLETION_UPDATE_RELCACHE_FILE, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, xl_xact_commit::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_DROPPED_STATS, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_INVALS, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILELOCATORS, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, xl_xact_twophase::xid, xl_xact_xinfo::xinfo, XLOG_INCLUDE_ORIGIN, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogSetRecordFlags(), and XLR_SPECIAL_REL_UPDATE.

Referenced by RecordTransactionCommit(), and RecordTransactionCommitPrepared().

Variable Documentation

◆ bsysscan

◆ CheckXidAlive

◆ currentCommandId

◆ currentCommandIdUsed

bool currentCommandIdUsed
static

◆ currentSubTransactionId

SubTransactionId currentSubTransactionId
static

Definition at line 265 of file xact.c.

Referenced by PushTransaction(), and StartTransaction().

◆ CurrentTransactionState

TransactionState CurrentTransactionState = &TopTransactionStateData
static

Definition at line 259 of file xact.c.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), AbortSubTransaction(), AbortTransaction(), AtCleanup_Memory(), AtCommit_Memory(), AtStart_Memory(), AtStart_ResourceOwner(), AtSubAbort_childXids(), AtSubAbort_ResourceOwner(), AtSubCleanup_Memory(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubStart_Memory(), AtSubStart_ResourceOwner(), BeginImplicitTransactionBlock(), BeginInternalSubTransaction(), BeginTransactionBlock(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), CommitTransactionCommandInternal(), DefineSavepoint(), EndImplicitTransactionBlock(), EndParallelWorkerTransaction(), EndTransactionBlock(), EnterParallelMode(), EstimateTransactionStateSpace(), ExitParallelMode(), GetCurrentFullTransactionId(), GetCurrentFullTransactionIdIfAny(), GetCurrentSubTransactionId(), GetCurrentTransactionId(), GetCurrentTransactionIdIfAny(), GetCurrentTransactionNestLevel(), GetCurrentTransactionStopTimestamp(), IsAbortedTransactionBlockState(), IsInParallelMode(), IsInTransactionBlock(), IsSubTransaction(), IsSubxactTopXidLogPending(), IsTransactionBlock(), IsTransactionOrTransactionBlock(), IsTransactionState(), MarkCurrentTransactionIdLoggedIfAny(), MarkSubxactTopXidLogged(), PopTransaction(), PrepareTransaction(), PrepareTransactionBlock(), PreventInTransactionBlock(), PushTransaction(), ReleaseCurrentSubTransaction(), ReleaseSavepoint(), RollbackAndReleaseCurrentSubTransaction(), RollbackToSavepoint(), SerializeTransactionState(), ShowTransactionState(), StartParallelWorkerTransaction(), StartSubTransaction(), StartTransaction(), StartTransactionCommand(), SubTransactionIsActive(), TransactionBlockStatusCode(), TransactionIdIsCurrentTransactionId(), TransactionStartedDuringRecovery(), UserAbortTransactionBlock(), and xactGetCommittedChildren().

◆ DefaultXactDeferrable

bool DefaultXactDeferrable = false

Definition at line 83 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactIsoLevel

int DefaultXactIsoLevel = XACT_READ_COMMITTED

Definition at line 77 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactReadOnly

bool DefaultXactReadOnly = false

Definition at line 80 of file xact.c.

Referenced by StartTransaction().

◆ forceSyncCommit

bool forceSyncCommit = false
static

◆ MyXactFlags

◆ nParallelCurrentXids

◆ nUnreportedXids

int nUnreportedXids
static

Definition at line 256 of file xact.c.

Referenced by AssignTransactionId(), and StartTransaction().

◆ ParallelCurrentXids

TransactionId* ParallelCurrentXids
static

◆ prepareGID

char* prepareGID
static

Definition at line 287 of file xact.c.

Referenced by PrepareTransaction(), and PrepareTransactionBlock().

◆ stmtStartTimestamp

◆ SubXact_callbacks

SubXactCallbackItem* SubXact_callbacks = NULL
static

◆ synchronous_commit

int synchronous_commit = SYNCHRONOUS_COMMIT_ON

Definition at line 86 of file xact.c.

Referenced by AutoVacWorkerMain(), RecordTransactionCommit(), and XactLogCommitRecord().

◆ TopTransactionStateData

TransactionStateData TopTransactionStateData
static
Initial value:
= {
.state = TRANS_DEFAULT,
.blockState = TBLOCK_DEFAULT,
.topXidLogged = false,
}

Definition at line 246 of file xact.c.

Referenced by AssignTransactionId(), GetTopFullTransactionId(), GetTopTransactionId(), and StartTransaction().

◆ TransactionAbortContext

MemoryContext TransactionAbortContext = NULL
static

◆ unreportedXids

TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
static

Definition at line 257 of file xact.c.

Referenced by AssignTransactionId().

◆ Xact_callbacks

XactCallbackItem* Xact_callbacks = NULL
static

Definition at line 314 of file xact.c.

Referenced by CallXactCallbacks(), RegisterXactCallback(), and UnregisterXactCallback().

◆ xact_is_sampled

bool xact_is_sampled = false

Definition at line 295 of file xact.c.

Referenced by check_log_duration(), and StartTransaction().

◆ XactDeferrable

◆ XactIsoLevel

◆ XactReadOnly

◆ xactStartTimestamp

TimestampTz xactStartTimestamp
static

◆ xactStopTimestamp

TimestampTz xactStopTimestamp
static

Definition at line 281 of file xact.c.

Referenced by GetCurrentTransactionStopTimestamp(), and StartTransaction().

◆ XactTopFullTransactionId