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 "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 237 of file xact.c.

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

typedef enum TBlockState TBlockState

◆ TransactionState

Definition at line 219 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 155 of file xact.c.

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

◆ TransState

enum TransState
Enumerator
TRANS_DEFAULT 
TRANS_START 
TRANS_INPROGRESS 
TRANS_COMMIT 
TRANS_ABORT 
TRANS_PREPARE 

Definition at line 139 of file xact.c.

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

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3425 of file xact.c.

3426 {
3427  /*
3428  * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3429  * done.
3430  */
3432  {
3433  }
3434 }
static bool AbortCurrentTransactionInternal(void)
Definition: xact.c:3443

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 3443 of file xact.c.

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

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 4849 of file xact.c.

4850 {
4852 
4853  /* Ensure we're not running in a doomed memory context */
4854  AtAbort_Memory();
4855 
4856  /*
4857  * Get out of any transaction or nested transaction
4858  */
4859  do
4860  {
4861  switch (s->blockState)
4862  {
4863  case TBLOCK_DEFAULT:
4864  if (s->state == TRANS_DEFAULT)
4865  {
4866  /* Not in a transaction, do nothing */
4867  }
4868  else
4869  {
4870  /*
4871  * We can get here after an error during transaction start
4872  * (state will be TRANS_START). Need to clean up the
4873  * incompletely started transaction. First, adjust the
4874  * low-level state to suppress warning message from
4875  * AbortTransaction.
4876  */
4877  if (s->state == TRANS_START)
4878  s->state = TRANS_INPROGRESS;
4879  AbortTransaction();
4881  }
4882  break;
4883  case TBLOCK_STARTED:
4884  case TBLOCK_BEGIN:
4885  case TBLOCK_INPROGRESS:
4888  case TBLOCK_END:
4889  case TBLOCK_ABORT_PENDING:
4890  case TBLOCK_PREPARE:
4891  /* In a transaction, so clean up */
4892  AbortTransaction();
4895  break;
4896  case TBLOCK_ABORT:
4897  case TBLOCK_ABORT_END:
4898 
4899  /*
4900  * AbortTransaction is already done, still need Cleanup.
4901  * However, if we failed partway through running ROLLBACK,
4902  * there will be an active portal running that command, which
4903  * we need to shut down before doing CleanupTransaction.
4904  */
4905  AtAbort_Portals();
4908  break;
4909 
4910  /*
4911  * In a subtransaction, so clean it up and abort parent too
4912  */
4913  case TBLOCK_SUBBEGIN:
4914  case TBLOCK_SUBINPROGRESS:
4915  case TBLOCK_SUBRELEASE:
4916  case TBLOCK_SUBCOMMIT:
4918  case TBLOCK_SUBRESTART:
4921  s = CurrentTransactionState; /* changed by pop */
4922  break;
4923 
4924  case TBLOCK_SUBABORT:
4925  case TBLOCK_SUBABORT_END:
4927  /* As above, but AbortSubTransaction already done */
4928  if (s->curTransactionOwner)
4929  {
4930  /* As in TBLOCK_ABORT, might have a live portal to zap */
4935  }
4937  s = CurrentTransactionState; /* changed by pop */
4938  break;
4939  }
4940  } while (s->blockState != TBLOCK_DEFAULT);
4941 
4942  /* Should be out of all subxacts now */
4943  Assert(s->parent == NULL);
4944 
4945  /*
4946  * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4947  * whether there were any transactions to close or not. (Callers that
4948  * don't intend to exit soon should switch to some other context to avoid
4949  * long-term memory leaks.)
4950  */
4952 }
#define Assert(condition)
Definition: c.h:858
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:194
struct TransactionStateData * parent
Definition: xact.c:216
ResourceOwner curTransactionOwner
Definition: xact.c:202
static void AtAbort_Memory(void)
Definition: xact.c:1872

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 5205 of file xact.c.

5206 {
5208 
5209  /* Prevent cancel/die interrupt while cleaning up */
5210  HOLD_INTERRUPTS();
5211 
5212  /* Make sure we have a valid memory context and resource owner */
5215 
5216  /*
5217  * Release any LW locks we might be holding as quickly as possible.
5218  * (Regular locks, however, must be held till we finish aborting.)
5219  * Releasing LW locks is critical since we might try to grab them again
5220  * while cleaning up!
5221  *
5222  * FIXME This may be incorrect --- Are there some locks we should keep?
5223  * Buffer locks, for example? I don't think so but I'm not sure.
5224  */
5225  LWLockReleaseAll();
5226 
5229  UnlockBuffers();
5230 
5231  /* Reset WAL record construction state */
5233 
5234  /* Cancel condition variable sleep */
5236 
5237  /*
5238  * Also clean up any open wait for lock, since the lock manager will choke
5239  * if we try to wait for another lock before doing this.
5240  */
5241  LockErrorCleanup();
5242 
5243  /*
5244  * If any timeout events are still active, make sure the timeout interrupt
5245  * is scheduled. This covers possible loss of a timeout interrupt due to
5246  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5247  * We delay this till after LockErrorCleanup so that we don't uselessly
5248  * reschedule lock or deadlock check timeouts.
5249  */
5251 
5252  /*
5253  * Re-enable signals, in case we got here by longjmp'ing out of a signal
5254  * handler. We do this fairly early in the sequence so that the timeout
5255  * infrastructure will be functional if needed while aborting.
5256  */
5257  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5258 
5259  /*
5260  * check the current transaction state
5261  */
5262  ShowTransactionState("AbortSubTransaction");
5263 
5264  if (s->state != TRANS_INPROGRESS)
5265  elog(WARNING, "AbortSubTransaction while in %s state",
5267 
5268  s->state = TRANS_ABORT;
5269 
5270  /*
5271  * Reset user ID which might have been changed transiently. (See notes in
5272  * AbortTransaction.)
5273  */
5275 
5276  /* Forget about any active REINDEX. */
5278 
5279  /* Reset logical streaming state. */
5281 
5282  /*
5283  * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5284  * exports are not supported in subtransactions.
5285  */
5286 
5287  /*
5288  * If this subxact has started any unfinished parallel operation, clean up
5289  * its workers and exit parallel mode. Don't warn about leaked resources.
5290  */
5292  s->parallelModeLevel = 0;
5293 
5294  /*
5295  * We can skip all this stuff if the subxact failed before creating a
5296  * ResourceOwner...
5297  */
5298  if (s->curTransactionOwner)
5299  {
5300  AfterTriggerEndSubXact(false);
5306  s->parent->subTransactionId);
5308 
5309  /* Advertise the fact that we aborted in pg_xact. */
5310  (void) RecordTransactionAbort(true);
5311 
5312  /* Post-abort cleanup */
5315 
5317  s->parent->subTransactionId);
5318 
5321  false, false);
5322 
5324  s->parent->subTransactionId);
5325  AtEOSubXact_Inval(false);
5328  false, false);
5331  false, false);
5332  AtSubAbort_smgr();
5333 
5334  AtEOXact_GUC(false, s->gucNestLevel);
5335  AtEOSubXact_SPI(false, s->subTransactionId);
5337  s->parent->subTransactionId);
5339  s->parent->subTransactionId);
5341  s->parent->subTransactionId);
5343  AtEOSubXact_PgStat(false, s->nestingLevel);
5345  }
5346 
5347  /*
5348  * Restore the upper transaction's read-only state, too. This should be
5349  * redundant with GUC's cleanup but we may as well do it for consistency
5350  * with the commit case.
5351  */
5353 
5355 }
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:5143
bool ConditionVariableCancelSleep(void)
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1895
#define WARNING
Definition: elog.h:36
#define elog(elevel,...)
Definition: elog.h:224
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:3132
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2261
void ResetReindexState(int nestLevel)
Definition: index.c:4146
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:4543
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:112
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:730
void AtSubAbort_smgr(void)
Definition: storage.c:934
int parallelModeLevel
Definition: xact.c:212
FullTransactionId fullTransactionId
Definition: xact.c:193
bool prevXactReadOnly
Definition: xact.c:209
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:17550
void reschedule_timeouts(void)
Definition: timeout.c:540
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5351
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3885
static void AtSubAbort_Memory(void)
Definition: xact.c:1892
static const char * TransStateAsString(TransState state)
Definition: xact.c:5741
bool XactReadOnly
Definition: xact.c:80
static void AtSubAbort_childXids(void)
Definition: xact.c:1930
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1917
static void ShowTransactionState(const char *str)
Definition: xact.c:5629
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1742
@ 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 2787 of file xact.c.

2788 {
2790  TransactionId latestXid;
2791  bool is_parallel_worker;
2792 
2793  /* Prevent cancel/die interrupt while cleaning up */
2794  HOLD_INTERRUPTS();
2795 
2796  /* Disable transaction timeout */
2797  if (TransactionTimeout > 0)
2799 
2800  /* Make sure we have a valid memory context and resource owner */
2801  AtAbort_Memory();
2803 
2804  /*
2805  * Release any LW locks we might be holding as quickly as possible.
2806  * (Regular locks, however, must be held till we finish aborting.)
2807  * Releasing LW locks is critical since we might try to grab them again
2808  * while cleaning up!
2809  */
2810  LWLockReleaseAll();
2811 
2812  /* Clear wait information and command progress indicator */
2815 
2816  /* Clean up buffer context locks, too */
2817  UnlockBuffers();
2818 
2819  /* Reset WAL record construction state */
2821 
2822  /* Cancel condition variable sleep */
2824 
2825  /*
2826  * Also clean up any open wait for lock, since the lock manager will choke
2827  * if we try to wait for another lock before doing this.
2828  */
2829  LockErrorCleanup();
2830 
2831  /*
2832  * If any timeout events are still active, make sure the timeout interrupt
2833  * is scheduled. This covers possible loss of a timeout interrupt due to
2834  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2835  * We delay this till after LockErrorCleanup so that we don't uselessly
2836  * reschedule lock or deadlock check timeouts.
2837  */
2839 
2840  /*
2841  * Re-enable signals, in case we got here by longjmp'ing out of a signal
2842  * handler. We do this fairly early in the sequence so that the timeout
2843  * infrastructure will be functional if needed while aborting.
2844  */
2845  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2846 
2847  /*
2848  * check the current transaction state
2849  */
2850  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2851  if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2852  elog(WARNING, "AbortTransaction while in %s state",
2854  Assert(s->parent == NULL);
2855 
2856  /*
2857  * set the current transaction state information appropriately during the
2858  * abort processing
2859  */
2860  s->state = TRANS_ABORT;
2861 
2862  /*
2863  * Reset user ID which might have been changed transiently. We need this
2864  * to clean up in case control escaped out of a SECURITY DEFINER function
2865  * or other local change of CurrentUserId; therefore, the prior value of
2866  * SecurityRestrictionContext also needs to be restored.
2867  *
2868  * (Note: it is not necessary to restore session authorization or role
2869  * settings here because those can only be changed via GUC, and GUC will
2870  * take care of rolling them back if need be.)
2871  */
2873 
2874  /* Forget about any active REINDEX. */
2876 
2877  /* Reset logical streaming state. */
2879 
2880  /* Reset snapshot export state. */
2882 
2883  /*
2884  * If this xact has started any unfinished parallel operation, clean up
2885  * its workers and exit parallel mode. Don't warn about leaked resources.
2886  */
2887  AtEOXact_Parallel(false);
2888  s->parallelModeLevel = 0;
2889  s->parallelChildXact = false; /* should be false already */
2890 
2891  /*
2892  * do abort processing
2893  */
2894  AfterTriggerEndXact(false); /* 'false' means it's abort */
2895  AtAbort_Portals();
2896  smgrDoPendingSyncs(false, is_parallel_worker);
2897  AtEOXact_LargeObject(false);
2898  AtAbort_Notify();
2899  AtEOXact_RelationMap(false, is_parallel_worker);
2900  AtAbort_Twophase();
2901 
2902  /*
2903  * Advertise the fact that we aborted in pg_xact (assuming that we got as
2904  * far as assigning an XID to advertise). But if we're inside a parallel
2905  * worker, skip this; the user backend must be the one to write the abort
2906  * record.
2907  */
2908  if (!is_parallel_worker)
2909  latestXid = RecordTransactionAbort(false);
2910  else
2911  {
2912  latestXid = InvalidTransactionId;
2913 
2914  /*
2915  * Since the parallel leader won't get our value of XactLastRecEnd in
2916  * this case, we nudge WAL-writer ourselves in this case. See related
2917  * comments in RecordTransactionAbort for why this matters.
2918  */
2920  }
2921 
2922  TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2923 
2924  /*
2925  * Let others know about no transaction in progress by me. Note that this
2926  * must be done _before_ releasing locks we hold and _after_
2927  * RecordTransactionAbort.
2928  */
2929  ProcArrayEndTransaction(MyProc, latestXid);
2930 
2931  /*
2932  * Post-abort cleanup. See notes in CommitTransaction() concerning
2933  * ordering. We can skip all of it if the transaction failed before
2934  * creating a resource owner.
2935  */
2936  if (TopTransactionResourceOwner != NULL)
2937  {
2938  if (is_parallel_worker)
2940  else
2942 
2945  false, true);
2946  AtEOXact_Buffers(false);
2947  AtEOXact_RelationCache(false);
2948  AtEOXact_Inval(false);
2952  false, true);
2955  false, true);
2956  smgrDoPendingDeletes(false);
2957 
2958  AtEOXact_GUC(false, 1);
2959  AtEOXact_SPI(false);
2960  AtEOXact_Enum();
2962  AtEOXact_Namespace(false, is_parallel_worker);
2963  AtEOXact_SMgr();
2964  AtEOXact_Files(false);
2966  AtEOXact_HashTables(false);
2967  AtEOXact_PgStat(false, is_parallel_worker);
2968  AtEOXact_ApplyLauncher(false);
2971  }
2972 
2973  /*
2974  * State remains TRANS_ABORT until CleanupTransaction().
2975  */
2977 }
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:4983
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:3571
uint32 TransactionId
Definition: c.h:652
void AtEOXact_ComboCid(void)
Definition: combocid.c:182
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1869
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3165
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:1800
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition: namespace.c:4497
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:807
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:766
void AtEOXact_SPI(bool isCommit)
Definition: spi.c:428
PGPROC * MyProc
Definition: proc.c:66
int TransactionTimeout
Definition: proc.c:61
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:700
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:632
LocalTransactionId lxid
Definition: proc.h:195
struct PGPROC::@117 vxid
bool parallelChildXact
Definition: xact.c:213
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:17518
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:5255
void AtAbort_Twophase(void)
Definition: twophase.c:304
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1904
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3825
@ XACT_EVENT_ABORT
Definition: xact.h:130
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:131
XLogRecPtr XactLastRecEnd
Definition: xlog.c:252
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2629

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, 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 633 of file xact.c.

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

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

References MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1904 of file xact.c.

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

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1567 of file xact.c.

1568 {
1569  /*
1570  * Make any pending relation map changes visible. We must do this before
1571  * processing local sinval messages, so that the map changes will get
1572  * reflected into the relcache when relcache invals are processed.
1573  */
1575 
1576  /*
1577  * Make catalog changes visible to me for the next command.
1578  */
1580 }
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 1962 of file xact.c.

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

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 1586 of file xact.c.

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

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 1165 of file xact.c.

1166 {
1168 }
void AcceptInvalidationMessages(void)
Definition: inval.c:806

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1174 of file xact.c.

1175 {
1177 
1178  /*
1179  * Remember the memory context that was active prior to transaction start.
1180  */
1182 
1183  /*
1184  * If this is the first time through, create a private context for
1185  * AbortTransaction to work in. By reserving some space now, we can
1186  * insulate AbortTransaction from out-of-memory scenarios. Like
1187  * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1188  * size, so that space will be reserved immediately.
1189  */
1190  if (TransactionAbortContext == NULL)
1193  "TransactionAbortContext",
1194  32 * 1024,
1195  32 * 1024,
1196  32 * 1024);
1197 
1198  /*
1199  * Likewise, if this is the first time through, create a top-level context
1200  * for transaction-local data. This context will be reset at transaction
1201  * end, and then re-used in later transactions.
1202  */
1203  if (TopTransactionContext == NULL)
1206  "TopTransactionContext",
1208 
1209  /*
1210  * In a top-level transaction, CurTransactionContext is the same as
1211  * TopTransactionContext.
1212  */
1215 
1216  /* Make the CurTransactionContext active. */
1218 }
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 1224 of file xact.c.

1225 {
1227 
1228  /*
1229  * We shouldn't have a transaction resource owner already.
1230  */
1232 
1233  /*
1234  * Create a toplevel resource owner for the transaction.
1235  */
1236  s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1237 
1241 }
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 1930 of file xact.c.

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

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

Definition at line 1892 of file xact.c.

1893 {
1895 
1897 }

References Assert, MemoryContextSwitchTo(), and TransactionAbortContext.

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1917 of file xact.c.

1918 {
1920 
1921  /* Make sure we have a valid ResourceOwner */
1923 }

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 2010 of file xact.c.

2011 {
2013 
2014  Assert(s->parent != NULL);
2015 
2016  /*
2017  * Return to the memory context that was current before we started the
2018  * subtransaction. (In principle, this could not be any of the contexts
2019  * we are about to delete. If it somehow is, assertions in mcxt.c will
2020  * complain.)
2021  */
2023 
2024  /* Update CurTransactionContext (might not be same as priorContext) */
2026 
2027  /*
2028  * Clear the special abort context for next time.
2029  */
2030  if (TransactionAbortContext != NULL)
2032 
2033  /*
2034  * Delete the subxact local memory contexts. Its CurTransactionContext can
2035  * go too (note this also kills CurTransactionContexts from any children
2036  * of the subxact).
2037  */
2038  if (s->curTransactionContext)
2040  s->curTransactionContext = NULL;
2041 }
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 1652 of file xact.c.

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

1624 {
1626 
1627  Assert(s->parent != NULL);
1628 
1629  /* Return to parent transaction level's memory context. */
1632 
1633  /*
1634  * Ordinarily we cannot throw away the child's CurTransactionContext,
1635  * since the data it contains will be needed at upper commit. However, if
1636  * there isn't actually anything in it, we can throw it away. This avoids
1637  * a small memory leak in the common case of "trivial" subxacts.
1638  */
1640  {
1642  s->curTransactionContext = NULL;
1643  }
1644 }
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 1252 of file xact.c.

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

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 1281 of file xact.c.

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

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

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4313 of file xact.c.

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

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

Referenced by exec_simple_query().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4681 of file xact.c.

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

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 3911 of file xact.c.

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

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 5688 of file xact.c.

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

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 3885 of file xact.c.

3888 {
3889  SubXactCallbackItem *item;
3891 
3892  for (item = SubXact_callbacks; item; item = next)
3893  {
3894  /* allow callbacks to unregister themselves when called */
3895  next = item->next;
3896  item->callback(event, mySubid, parentSubid, item->arg);
3897  }
3898 }
static int32 next
Definition: blutils.c:221
struct SubXactCallbackItem * next
Definition: xact.c:320
SubXactCallback callback
Definition: xact.c:321
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:325

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 3825 of file xact.c.

3826 {
3827  XactCallbackItem *item;
3829 
3830  for (item = Xact_callbacks; item; item = next)
3831  {
3832  /* allow callbacks to unregister themselves when called */
3833  next = item->next;
3834  item->callback(event, item->arg);
3835  }
3836 }
struct XactCallbackItem * next
Definition: xact.c:308
void * arg
Definition: xact.c:310
XactCallback callback
Definition: xact.c:309
static XactCallbackItem * Xact_callbacks
Definition: xact.c:313

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 3709 of file xact.c.

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

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

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5364 of file xact.c.

5365 {
5367 
5368  ShowTransactionState("CleanupSubTransaction");
5369 
5370  if (s->state != TRANS_ABORT)
5371  elog(WARNING, "CleanupSubTransaction while in %s state",
5373 
5375 
5378  if (s->curTransactionOwner)
5380  s->curTransactionOwner = NULL;
5381 
5383 
5384  s->state = TRANS_DEFAULT;
5385 
5386  PopTransaction();
5387 }
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:2010
static void PopTransaction(void)
Definition: xact.c:5459

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 2983 of file xact.c.

2984 {
2986 
2987  /*
2988  * State should still be TRANS_ABORT from AbortTransaction().
2989  */
2990  if (s->state != TRANS_ABORT)
2991  elog(FATAL, "CleanupTransaction: unexpected state %s",
2993 
2994  /*
2995  * do abort cleanup processing
2996  */
2997  AtCleanup_Portals(); /* now safe to release portal memory */
2998  AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2999 
3000  CurrentResourceOwner = NULL; /* and resource owner */
3003  s->curTransactionOwner = NULL;
3006 
3007  AtCleanup_Memory(); /* and transaction memory */
3008 
3011  s->nestingLevel = 0;
3012  s->gucNestLevel = 0;
3013  s->childXids = NULL;
3014  s->nChildXids = 0;
3015  s->maxChildXids = 0;
3016  s->parallelModeLevel = 0;
3017  s->parallelChildXact = false;
3018 
3021 
3022  /*
3023  * done with abort processing, set current transaction state back to
3024  * default
3025  */
3026  s->state = TRANS_DEFAULT;
3027 }
#define InvalidSubTransactionId
Definition: c.h:658
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:1962
static int nParallelCurrentXids
Definition: xact.c:124

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 1098 of file xact.c.

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

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

Referenced by _SPI_execute_plan(), acquire_inherited_sample_rows(), addFkRecurseReferenced(), addFkRecurseReferencing(), AddRoleMems(), AlterPublicationOptions(), AlterRole(), ATAddCheckConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecCmd(), ATExecDropColumn(), ATExecDropConstraint(), ATExecDropExpression(), ATExecDropIdentity(), ATExecMergePartitions(), ATExecSetAccessMethodNoStorage(), ATExecSetCompression(), ATExecSetExpression(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), ATExecSplitPartition(), ATParseTransformCmd(), ATRewriteTables(), AttachPartitionEnsureIndexes(), btadjustmembers(), CloneFkReferencing(), 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 5091 of file xact.c.

5092 {
5094 
5095  ShowTransactionState("CommitSubTransaction");
5096 
5097  if (s->state != TRANS_INPROGRESS)
5098  elog(WARNING, "CommitSubTransaction while in %s state",
5100 
5101  /* Pre-commit processing goes here */
5102 
5104  s->parent->subTransactionId);
5105 
5106  /*
5107  * If this subxact has started any unfinished parallel operation, clean up
5108  * its workers and exit parallel mode. Warn about leaked resources.
5109  */
5111  if (s->parallelModeLevel != 0)
5112  {
5113  elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5114  s->parallelModeLevel);
5115  s->parallelModeLevel = 0;
5116  }
5117 
5118  /* Do the actual "commit", such as it is */
5119  s->state = TRANS_COMMIT;
5120 
5121  /* Must CCI to ensure commands of subtransaction are seen as done */
5123 
5124  /*
5125  * Prior to 8.4 we marked subcommit in clog at this point. We now only
5126  * perform that step, if required, as part of the atomic update of the
5127  * whole transaction tree at top level commit or abort.
5128  */
5129 
5130  /* Post-commit cleanup */
5133  AfterTriggerEndSubXact(true);
5136  s->parent->nestingLevel,
5139  s->parent->subTransactionId);
5141 
5143  s->parent->subTransactionId);
5144 
5147  true, false);
5149  s->parent->subTransactionId);
5150  AtEOSubXact_Inval(true);
5151  AtSubCommit_smgr();
5152 
5153  /*
5154  * The only lock we actually release here is the subtransaction XID lock.
5155  */
5159 
5160  /*
5161  * Other locks should get transferred to their parent resource owner.
5162  */
5165  true, false);
5168  true, false);
5169 
5170  AtEOXact_GUC(true, s->gucNestLevel);
5173  s->parent->subTransactionId);
5175  s->parent->subTransactionId);
5177  s->parent->subTransactionId);
5179  AtEOSubXact_PgStat(true, s->nestingLevel);
5181 
5182  /*
5183  * We need to restore the upper transaction's read-only state, in case the
5184  * upper is read-write while the child is read-only; GUC will incorrectly
5185  * think it should leave the child state in place.
5186  */
5188 
5192  s->curTransactionOwner = NULL;
5193 
5195 
5196  s->state = TRANS_DEFAULT;
5197 
5198  PopTransaction();
5199 }
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:1623
static void AtSubCommit_childXids(void)
Definition: xact.c:1652
void CommandCounterIncrement(void)
Definition: xact.c:1098
@ 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 2216 of file xact.c.

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

3132 {
3133  /*
3134  * Repeatedly call CommitTransactionCommandInternal() until all the work
3135  * is done.
3136  */
3138  {
3139  }
3140 }
static bool CommitTransactionCommandInternal(void)
Definition: xact.c:3149

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 3149 of file xact.c.

3150 {
3153 
3154  /* Must save in case we need to restore below */
3156 
3157  switch (s->blockState)
3158  {
3159  /*
3160  * These shouldn't happen. TBLOCK_DEFAULT means the previous
3161  * StartTransactionCommand didn't set the STARTED state
3162  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3163  * by EndParallelWorkerTransaction(), not this function.
3164  */
3165  case TBLOCK_DEFAULT:
3167  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3169  break;
3170 
3171  /*
3172  * If we aren't in a transaction block, just do our usual
3173  * transaction commit, and return to the idle state.
3174  */
3175  case TBLOCK_STARTED:
3178  break;
3179 
3180  /*
3181  * We are completing a "BEGIN TRANSACTION" command, so we change
3182  * to the "transaction block in progress" state and return. (We
3183  * assume the BEGIN did nothing to the database, so we need no
3184  * CommandCounterIncrement.)
3185  */
3186  case TBLOCK_BEGIN:
3188  break;
3189 
3190  /*
3191  * This is the case when we have finished executing a command
3192  * someplace within a transaction block. We increment the command
3193  * counter and return.
3194  */
3195  case TBLOCK_INPROGRESS:
3197  case TBLOCK_SUBINPROGRESS:
3199  break;
3200 
3201  /*
3202  * We are completing a "COMMIT" command. Do it and return to the
3203  * idle state.
3204  */
3205  case TBLOCK_END:
3208  if (s->chain)
3209  {
3210  StartTransaction();
3212  s->chain = false;
3214  }
3215  break;
3216 
3217  /*
3218  * Here we are in the middle of a transaction block but one of the
3219  * commands caused an abort so we do nothing but remain in the
3220  * abort state. Eventually we will get a ROLLBACK command.
3221  */
3222  case TBLOCK_ABORT:
3223  case TBLOCK_SUBABORT:
3224  break;
3225 
3226  /*
3227  * Here we were in an aborted transaction block and we just got
3228  * the ROLLBACK command from the user, so clean up the
3229  * already-aborted transaction and return to the idle state.
3230  */
3231  case TBLOCK_ABORT_END:
3234  if (s->chain)
3235  {
3236  StartTransaction();
3238  s->chain = false;
3240  }
3241  break;
3242 
3243  /*
3244  * Here we were in a perfectly good transaction block but the user
3245  * told us to ROLLBACK anyway. We have to abort the transaction
3246  * and then clean up.
3247  */
3248  case TBLOCK_ABORT_PENDING:
3249  AbortTransaction();
3252  if (s->chain)
3253  {
3254  StartTransaction();
3256  s->chain = false;
3258  }
3259  break;
3260 
3261  /*
3262  * We are completing a "PREPARE TRANSACTION" command. Do it and
3263  * return to the idle state.
3264  */
3265  case TBLOCK_PREPARE:
3268  break;
3269 
3270  /*
3271  * The user issued a SAVEPOINT inside a transaction block. Start a
3272  * subtransaction. (DefineSavepoint already did PushTransaction,
3273  * so as to have someplace to put the SUBBEGIN state.)
3274  */
3275  case TBLOCK_SUBBEGIN:
3278  break;
3279 
3280  /*
3281  * The user issued a RELEASE command, so we end the current
3282  * subtransaction and return to the parent transaction. The parent
3283  * might be ended too, so repeat till we find an INPROGRESS
3284  * transaction or subtransaction.
3285  */
3286  case TBLOCK_SUBRELEASE:
3287  do
3288  {
3290  s = CurrentTransactionState; /* changed by pop */
3291  } while (s->blockState == TBLOCK_SUBRELEASE);
3292 
3295  break;
3296 
3297  /*
3298  * The user issued a COMMIT, so we end the current subtransaction
3299  * hierarchy and perform final commit. We do this by rolling up
3300  * any subtransactions into their parent, which leads to O(N^2)
3301  * operations with respect to resource owners - this isn't that
3302  * bad until we approach a thousands of savepoints but is
3303  * necessary for correctness should after triggers create new
3304  * resource owners.
3305  */
3306  case TBLOCK_SUBCOMMIT:
3307  do
3308  {
3310  s = CurrentTransactionState; /* changed by pop */
3311  } while (s->blockState == TBLOCK_SUBCOMMIT);
3312  /* If we had a COMMIT command, finish off the main xact too */
3313  if (s->blockState == TBLOCK_END)
3314  {
3315  Assert(s->parent == NULL);
3318  if (s->chain)
3319  {
3320  StartTransaction();
3322  s->chain = false;
3324  }
3325  }
3326  else if (s->blockState == TBLOCK_PREPARE)
3327  {
3328  Assert(s->parent == NULL);
3331  }
3332  else
3333  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3335  break;
3336 
3337  /*
3338  * The current already-failed subtransaction is ending due to a
3339  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3340  * examine the parent (which could be in any of several states).
3341  * As we need to examine the parent, return false to request the
3342  * caller to do the next iteration.
3343  */
3344  case TBLOCK_SUBABORT_END:
3346  return false;
3347 
3348  /*
3349  * As above, but it's not dead yet, so abort first.
3350  */
3354  return false;
3355 
3356  /*
3357  * The current subtransaction is the target of a ROLLBACK TO
3358  * command. Abort and pop it, then start a new subtransaction
3359  * with the same name.
3360  */
3361  case TBLOCK_SUBRESTART:
3362  {
3363  char *name;
3364  int savepointLevel;
3365 
3366  /* save name and keep Cleanup from freeing it */
3367  name = s->name;
3368  s->name = NULL;
3369  savepointLevel = s->savepointLevel;
3370 
3373 
3374  DefineSavepoint(NULL);
3375  s = CurrentTransactionState; /* changed by push */
3376  s->name = name;
3377  s->savepointLevel = savepointLevel;
3378 
3379  /* This is the same as TBLOCK_SUBBEGIN case */
3383  }
3384  break;
3385 
3386  /*
3387  * Same as above, but the subtransaction had already failed, so we
3388  * don't need AbortSubTransaction.
3389  */
3391  {
3392  char *name;
3393  int savepointLevel;
3394 
3395  /* save name and keep Cleanup from freeing it */
3396  name = s->name;
3397  s->name = NULL;
3398  savepointLevel = s->savepointLevel;
3399 
3401 
3402  DefineSavepoint(NULL);
3403  s = CurrentTransactionState; /* changed by push */
3404  s->name = name;
3405  s->savepointLevel = savepointLevel;
3406 
3407  /* This is the same as TBLOCK_SUBBEGIN case */
3411  }
3412  break;
3413  }
3414 
3415  /* Done, no more iterations required */
3416  return true;
3417 }
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3110
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3118
static void StartTransaction(void)
Definition: xact.c:2052
void DefineSavepoint(const char *name)
Definition: xact.c:4360
static void CommitSubTransaction(void)
Definition: xact.c:5091
static void CommitTransaction(void)
Definition: xact.c:2216
static void PrepareTransaction(void)
Definition: xact.c:2498
static void StartSubTransaction(void)
Definition: xact.c:5054

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 4360 of file xact.c.

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

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 4338 of file xact.c.

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

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

Referenced by exec_simple_query().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 4031 of file xact.c.

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

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 5493 of file xact.c.

5494 {
5495  TransactionState s;
5496  Size nxids = 0;
5498 
5499  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5500  {
5502  nxids = add_size(nxids, 1);
5503  nxids = add_size(nxids, s->nChildXids);
5504  }
5505 
5506  return add_size(size, mul_size(sizeof(TransactionId), nxids));
5507 }
size_t Size
Definition: c.h:605
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:237

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 1150 of file xact.c.

1151 {
1152  forceSyncCommit = true;
1153 }
static bool forceSyncCommit
Definition: xact.c:291

References forceSyncCommit.

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 827 of file xact.c.

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

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

Referenced by ATRewriteTable(), CatalogTuplesMultiInsertWithInfo(), CopyFrom(), create_edata_for_relation(), create_estate_for_relation(), GetSnapshotData(), GetSnapshotDataReuse(), intorel_startup(), moveMergedTablesRows(), moveSplitTableRows(), 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 528 of file xact.c.

529 {
531 }

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 877 of file xact.c.

878 {
879  return stmtStartTimestamp;
880 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:279

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 868 of file xact.c.

869 {
870  return xactStartTimestamp;
871 }
static TimestampTz xactStartTimestamp
Definition: xact.c:278

References xactStartTimestamp.

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

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 889 of file xact.c.

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

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 605 of file xact.c.

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

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 497 of file xact.c.

498 {
500 }

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3753 of file xact.c.

3754 {
3755  /*
3756  * Return true on same conditions that would make
3757  * PreventInTransactionBlock error out
3758  */
3759  if (IsTransactionBlock())
3760  return true;
3761 
3762  if (IsSubTransaction())
3763  return true;
3764 
3766  return true;
3767 
3768  if (!isTopLevel)
3769  return true;
3770 
3773  return true;
3774 
3775  return false;
3776 }
int MyXactFlags
Definition: xact.c:134
#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 557 of file xact.c.

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

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

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 385 of file xact.c.

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

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 589 of file xact.c.

590 {
592 
594 }
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:557

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

Referenced by XLogInsertRecord().

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5459 of file xact.c.

5460 {
5462 
5463  if (s->state != TRANS_DEFAULT)
5464  elog(WARNING, "PopTransaction while in %s state",
5466 
5467  if (s->parent == NULL)
5468  elog(FATAL, "PopTransaction with no parent");
5469 
5471 
5472  /* Let's just make sure CurTransactionContext is good */
5475 
5476  /* Ditto for ResourceOwner links */
5479 
5480  /* Free the old child structure */
5481  if (s->name)
5482  pfree(s->name);
5483  pfree(s);
5484 }

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 2498 of file xact.c.

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

3980 {
3981  TransactionState s;
3982  bool result;
3983 
3984  /* Set up to commit the current transaction */
3985  result = EndTransactionBlock(false);
3986 
3987  /* If successful, change outer tblock state to PREPARE */
3988  if (result)
3989  {
3991 
3992  while (s->parent != NULL)
3993  s = s->parent;
3994 
3995  if (s->blockState == TBLOCK_END)
3996  {
3997  /* Save GID where PrepareTransaction can find it again */
3999 
4001  }
4002  else
4003  {
4004  /*
4005  * ignore case where we are not in a transaction;
4006  * EndTransactionBlock already issued a warning.
4007  */
4010  /* Don't send back a PREPARE result tag... */
4011  result = false;
4012  }
4013  }
4014 
4015  return result;
4016 }
bool EndTransactionBlock(bool chain)
Definition: xact.c:4031

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 3622 of file xact.c.

3623 {
3624  /*
3625  * xact block already started?
3626  */
3627  if (IsTransactionBlock())
3628  ereport(ERROR,
3629  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3630  /* translator: %s represents an SQL statement name */
3631  errmsg("%s cannot run inside a transaction block",
3632  stmtType)));
3633 
3634  /*
3635  * subtransaction?
3636  */
3637  if (IsSubTransaction())
3638  ereport(ERROR,
3639  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3640  /* translator: %s represents an SQL statement name */
3641  errmsg("%s cannot run inside a subtransaction",
3642  stmtType)));
3643 
3644  /*
3645  * inside a pipeline that has started an implicit transaction?
3646  */
3648  ereport(ERROR,
3649  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3650  /* translator: %s represents an SQL statement name */
3651  errmsg("%s cannot be executed within a pipeline",
3652  stmtType)));
3653 
3654  /*
3655  * inside a function call?
3656  */
3657  if (!isTopLevel)
3658  ereport(ERROR,
3659  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3660  /* translator: %s represents an SQL statement name */
3661  errmsg("%s cannot be executed from a function", stmtType)));
3662 
3663  /* If we got past IsTransactionBlock test, should be in default state */
3666  elog(FATAL, "cannot prevent transaction chain");
3667 
3668  /* All okay. Set the flag to make sure the right thing happens later. */
3670 }
#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 5397 of file xact.c.

5398 {
5400  TransactionState s;
5401 
5402  /*
5403  * We keep subtransaction state nodes in TopTransactionContext.
5404  */
5405  s = (TransactionState)
5407  sizeof(TransactionStateData));
5408 
5409  /*
5410  * Assign a subtransaction ID, watching out for counter wraparound.
5411  */
5414  {
5416  pfree(s);
5417  ereport(ERROR,
5418  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5419  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5420  }
5421 
5422  /*
5423  * We can now stack a minimally valid subtransaction without fear of
5424  * failure.
5425  */
5426  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5428  s->parent = p;
5429  s->nestingLevel = p->nestingLevel + 1;
5432  s->state = TRANS_DEFAULT;
5437  s->parallelModeLevel = 0;
5439  s->topXidLogged = false;
5440 
5442 
5443  /*
5444  * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5445  * with the subtransaction from here on out; in particular they should not
5446  * assume that it necessarily has a transaction context, resource owner,
5447  * or XID.
5448  */
5449 }
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:210
TransactionStateData * TransactionState
Definition: xact.c:219
static SubTransactionId currentSubTransactionId
Definition: xact.c:264

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 1742 of file xact.c.

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

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 1313 of file xact.c.

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

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 3851 of file xact.c.

3852 {
3853  SubXactCallbackItem *item;
3854 
3855  item = (SubXactCallbackItem *)
3857  item->callback = callback;
3858  item->arg = arg;
3859  item->next = SubXact_callbacks;
3860  SubXact_callbacks = item;
3861 }
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 3791 of file xact.c.

3792 {
3793  XactCallbackItem *item;
3794 
3795  item = (XactCallbackItem *)
3797  item->callback = callback;
3798  item->arg = arg;
3799  item->next = Xact_callbacks;
3800  Xact_callbacks = item;
3801 }

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 4755 of file xact.c.

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

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 4445 of file xact.c.

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

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 3700 of file xact.c.

3701 {
3702  CheckTransactionBlock(isTopLevel, true, stmtType);
3703 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3709

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4783 of file xact.c.

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

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 4554 of file xact.c.

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

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 5521 of file xact.c.

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

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 857 of file xact.c.

858 {
860  xactStartTimestamp = xact_ts;
861  stmtStartTimestamp = stmt_ts;
862 }

References Assert, IsParallelWorker, stmtStartTimestamp, and xactStartTimestamp.

Referenced by ParallelWorkerMain().

◆ ShowTransactionState()

static void ShowTransactionState ( const char *  str)
static

Definition at line 5629 of file xact.c.

5630 {
5631  /* skip work if message will definitely not be printed */
5634 }
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:5641

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 5641 of file xact.c.

5642 {
5644 
5645  if (s->parent)
5646  {
5647  /*
5648  * Since this function recurses, it could be driven to stack overflow.
5649  * This is just a debugging aid, so we can leave out some details
5650  * instead of erroring out with check_stack_depth().
5651  */
5652  if (stack_is_too_deep())
5653  ereport(DEBUG5,
5654  (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5655  str, s->nestingLevel)));
5656  else
5658  }
5659 
5660  initStringInfo(&buf);
5661  if (s->nChildXids > 0)
5662  {
5663  int i;
5664 
5665  appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5666  for (i = 1; i < s->nChildXids; i++)
5667  appendStringInfo(&buf, " %u", s->childXids[i]);
5668  }
5669  ereport(DEBUG5,
5670  (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5671  str, s->nestingLevel,
5672  PointerIsValid(s->name) ? s->name : "unnamed",
5675  (unsigned int) XidFromFullTransactionId(s->fullTransactionId),
5676  (unsigned int) s->subTransactionId,
5677  (unsigned int) currentCommandId,
5678  currentCommandIdUsed ? " (used)" : "",
5679  buf.data)));
5680  pfree(buf.data);
5681 }
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:3544
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 5054 of file xact.c.

5055 {
5057 
5058  if (s->state != TRANS_DEFAULT)
5059  elog(WARNING, "StartSubTransaction while in %s state",
5061 
5062  s->state = TRANS_START;
5063 
5064  /*
5065  * Initialize subsystems for new subtransaction
5066  *
5067  * must initialize resource-management stuff first
5068  */
5072 
5073  s->state = TRANS_INPROGRESS;
5074 
5075  /*
5076  * Call start-of-subxact callbacks
5077  */
5079  s->parent->subTransactionId);
5080 
5081  ShowTransactionState("StartSubTransaction");
5082 }
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5303
static void AtSubStart_ResourceOwner(void)
Definition: xact.c:1281
static void AtSubStart_Memory(void)
Definition: xact.c:1252
@ 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 2052 of file xact.c.

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

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 3033 of file xact.c.

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

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 803 of file xact.c.

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

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

Referenced by fmgr_sql().

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 4990 of file xact.c.

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

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 939 of file xact.c.

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

1041 {
1043 }

References CurrentTransactionState, and TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

◆ TransStateAsString()

static const char * TransStateAsString ( TransState  state)
static

Definition at line 5741 of file xact.c.

5742 {
5743  switch (state)
5744  {
5745  case TRANS_DEFAULT:
5746  return "DEFAULT";
5747  case TRANS_START:
5748  return "START";
5749  case TRANS_INPROGRESS:
5750  return "INPROGRESS";
5751  case TRANS_COMMIT:
5752  return "COMMIT";
5753  case TRANS_ABORT:
5754  return "ABORT";
5755  case TRANS_PREPARE:
5756  return "PREPARE";
5757  }
5758  return "UNRECOGNIZED";
5759 }
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 3864 of file xact.c.

3865 {
3866  SubXactCallbackItem *item;
3867  SubXactCallbackItem *prev;
3868 
3869  prev = NULL;
3870  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3871  {
3872  if (item->callback == callback && item->arg == arg)
3873  {
3874  if (prev)
3875  prev->next = item->next;
3876  else
3877  SubXact_callbacks = item->next;
3878  pfree(item);
3879  break;
3880  }
3881  }
3882 }

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

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3804 of file xact.c.

3805 {
3806  XactCallbackItem *item;
3807  XactCallbackItem *prev;
3808 
3809  prev = NULL;
3810  for (item = Xact_callbacks; item; prev = item, item = item->next)
3811  {
3812  if (item->callback == callback && item->arg == arg)
3813  {
3814  if (prev)
3815  prev->next = item->next;
3816  else
3817  Xact_callbacks = item->next;
3818  pfree(item);
3819  break;
3820  }
3821  }
3822 }

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

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4191 of file xact.c.

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

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 3694 of file xact.c.

3695 {
3696  CheckTransactionBlock(isTopLevel, false, stmtType);
3697 }

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6344 of file xact.c.

6345 {
6346  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6347 
6348  /* Backup blocks are not used in xact records */
6349  Assert(!XLogRecHasAnyBlockRefs(record));
6350 
6351  if (info == XLOG_XACT_COMMIT)
6352  {
6353  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6354  xl_xact_parsed_commit parsed;
6355 
6356  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6357  xact_redo_commit(&parsed, XLogRecGetXid(record),
6358  record->EndRecPtr, XLogRecGetOrigin(record));
6359  }
6360  else if (info == XLOG_XACT_COMMIT_PREPARED)
6361  {
6362  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6363  xl_xact_parsed_commit parsed;
6364 
6365  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6366  xact_redo_commit(&parsed, parsed.twophase_xid,
6367  record->EndRecPtr, XLogRecGetOrigin(record));
6368 
6369  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6370  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6371  PrepareRedoRemove(parsed.twophase_xid, false);
6372  LWLockRelease(TwoPhaseStateLock);
6373  }
6374  else if (info == XLOG_XACT_ABORT)
6375  {
6376  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6377  xl_xact_parsed_abort parsed;
6378 
6379  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6380  xact_redo_abort(&parsed, XLogRecGetXid(record),
6381  record->EndRecPtr, XLogRecGetOrigin(record));
6382  }
6383  else if (info == XLOG_XACT_ABORT_PREPARED)
6384  {
6385  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6386  xl_xact_parsed_abort parsed;
6387 
6388  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6389  xact_redo_abort(&parsed, parsed.twophase_xid,
6390  record->EndRecPtr, XLogRecGetOrigin(record));
6391 
6392  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6393  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6394  PrepareRedoRemove(parsed.twophase_xid, false);
6395  LWLockRelease(TwoPhaseStateLock);
6396  }
6397  else if (info == XLOG_XACT_PREPARE)
6398  {
6399  /*
6400  * Store xid and start/end pointers of the WAL record in TwoPhaseState
6401  * gxact entry.
6402  */
6403  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6405  record->ReadRecPtr,
6406  record->EndRecPtr,
6407  XLogRecGetOrigin(record));
6408  LWLockRelease(TwoPhaseStateLock);
6409  }
6410  else if (info == XLOG_XACT_ASSIGNMENT)
6411  {
6413 
6416  xlrec->nsubxacts, xlrec->xsub);
6417  }
6418  else if (info == XLOG_XACT_INVALIDATIONS)
6419  {
6420  /*
6421  * XXX we do ignore this for now, what matters are invalidations
6422  * written into the commit record.
6423  */
6424  }
6425  else
6426  elog(PANIC, "xact_redo: unknown op code %u", info);
6427 }
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:421
TransactionId twophase_xid
Definition: xact.h:391
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2581
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2479
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6111
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6265
#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 6265 of file xact.c.

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

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

5772 {
5774 
5775  if (s->nChildXids == 0)
5776  *ptr = NULL;
5777  else
5778  *ptr = s->childXids;
5779 
5780  return s->nChildXids;
5781 }

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 5967 of file xact.c.

5973 {
5974  xl_xact_abort xlrec;
5975  xl_xact_xinfo xl_xinfo;
5976  xl_xact_subxacts xl_subxacts;
5977  xl_xact_relfilelocators xl_relfilelocators;
5978  xl_xact_stats_items xl_dropped_stats;
5979  xl_xact_twophase xl_twophase;
5980  xl_xact_dbinfo xl_dbinfo;
5981  xl_xact_origin xl_origin;
5982 
5983  uint8 info;
5984 
5985  Assert(CritSectionCount > 0);
5986 
5987  xl_xinfo.xinfo = 0;
5988 
5989  /* decide between a plain and 2pc abort */
5990  if (!TransactionIdIsValid(twophase_xid))
5991  info = XLOG_XACT_ABORT;
5992  else
5993  info = XLOG_XACT_ABORT_PREPARED;
5994 
5995 
5996  /* First figure out and collect all the information needed */
5997 
5998  xlrec.xact_time = abort_time;
5999 
6000  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
6001  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
6002 
6003  if (nsubxacts > 0)
6004  {
6005  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
6006  xl_subxacts.nsubxacts = nsubxacts;
6007  }
6008 
6009  if (nrels > 0)
6010  {
6012  xl_relfilelocators.nrels = nrels;
6013  info |= XLR_SPECIAL_REL_UPDATE;
6014  }
6015 
6016  if (ndroppedstats > 0)
6017  {
6018  xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
6019  xl_dropped_stats.nitems = ndroppedstats;
6020  }
6021 
6022  if (TransactionIdIsValid(twophase_xid))
6023  {
6024  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
6025  xl_twophase.xid = twophase_xid;
6026  Assert(twophase_gid != NULL);
6027 
6028  if (XLogLogicalInfoActive())
6029  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6030  }
6031 
6032  if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6033  {
6034  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6035  xl_dbinfo.dbId = MyDatabaseId;
6036  xl_dbinfo.tsId = MyDatabaseTableSpace;
6037  }
6038 
6039  /*
6040  * Dump transaction origin information. We need this during recovery to
6041  * update the replication origin progress.
6042  */
6044  {
6045  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6046 
6049  }
6050 
6051  if (xl_xinfo.xinfo != 0)
6052  info |= XLOG_XACT_HAS_INFO;
6053 
6054  /* Then include all the collected data into the abort record. */
6055 
6056  XLogBeginInsert();
6057 
6058  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
6059 
6060  if (xl_xinfo.xinfo != 0)
6061  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
6062 
6063  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6064  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
6065 
6066  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6067  {
6068  XLogRegisterData((char *) (&xl_subxacts),
6070  XLogRegisterData((char *) subxacts,
6071  nsubxacts * sizeof(TransactionId));
6072  }
6073 
6074  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
6075  {
6076  XLogRegisterData((char *) (&xl_relfilelocators),
6078  XLogRegisterData((char *) rels,
6079  nrels * sizeof(RelFileLocator));
6080  }
6081 
6082  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6083  {
6084  XLogRegisterData((char *) (&xl_dropped_stats),
6086  XLogRegisterData((char *) droppedstats,
6087  ndroppedstats * sizeof(xl_xact_stats_item));
6088  }
6089 
6090  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6091  {
6092  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
6093  if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6094  XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
6095  }
6096 
6097  if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6098  XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
6099 
6100  /* Include the replication origin */
6102 
6103  return XLogInsert(RM_XACT_ID, info);
6104 }
#define unconstify(underlying_type, expr)
Definition: c.h:1245
Oid MyDatabaseTableSpace
Definition: globals.c:94
volatile uint32 CritSectionCount
Definition: globals.c:44
TimestampTz xact_time
Definition: xact.h:332
Oid tsId
Definition: xact.h:258
Oid dbId
Definition: xact.h:257
TimestampTz origin_timestamp
Definition: xact.h:311
XLogRecPtr origin_lsn
Definition: xact.h:310
int nsubxacts
Definition: xact.h:263
TransactionId xid
Definition: xact.h:305
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:294
#define XACT_XINFO_HAS_RELFILELOCATORS
Definition: xact.h:190
#define MinSizeOfXactAbort
Definition: xact.h:344
#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, unconstify, 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 5795 of file xact.c.

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

Referenced by PushTransaction(), and StartTransaction().

◆ CurrentTransactionState

TransactionState CurrentTransactionState = &TopTransactionStateData
static

Definition at line 258 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 82 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactIsoLevel

int DefaultXactIsoLevel = XACT_READ_COMMITTED

Definition at line 76 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactReadOnly

bool DefaultXactReadOnly = false

Definition at line 79 of file xact.c.

Referenced by StartTransaction().

◆ forceSyncCommit

bool forceSyncCommit = false
static

◆ MyXactFlags

◆ nParallelCurrentXids

◆ nUnreportedXids

int nUnreportedXids
static

Definition at line 255 of file xact.c.

Referenced by AssignTransactionId(), and StartTransaction().

◆ ParallelCurrentXids

TransactionId* ParallelCurrentXids
static

◆ prepareGID

char* prepareGID
static

Definition at line 286 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 85 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 245 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 256 of file xact.c.

Referenced by AssignTransactionId().

◆ Xact_callbacks

XactCallbackItem* Xact_callbacks = NULL
static

Definition at line 313 of file xact.c.

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

◆ xact_is_sampled

bool xact_is_sampled = false

Definition at line 294 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 280 of file xact.c.

Referenced by GetCurrentTransactionStopTimestamp(), and StartTransaction().

◆ XactTopFullTransactionId