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 void CommitTransactionCommandInternal (void)
 
static void 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 236 of file xact.c.

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

typedef enum TBlockState TBlockState

◆ TransactionState

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

3392 {
3393  while (true)
3394  {
3396  {
3397  /*
3398  * If we failed while trying to create a subtransaction, clean
3399  * up the broken subtransaction and abort the parent. The
3400  * same applies if we get a failure while ending a
3401  * subtransaction.
3402  */
3403  case TBLOCK_SUBBEGIN:
3404  case TBLOCK_SUBRELEASE:
3405  case TBLOCK_SUBCOMMIT:
3407  case TBLOCK_SUBRESTART:
3410  continue;
3411 
3412  /*
3413  * Same as above, except the Abort() was already done.
3414  */
3415  case TBLOCK_SUBABORT_END:
3418  continue;
3419  default:
3420  break;
3421  }
3423  break;
3424  }
3425 }
TBlockState blockState
Definition: xact.c:198
static void AbortCurrentTransactionInternal(void)
Definition: xact.c:3433
static void CleanupSubTransaction(void)
Definition: xact.c:5347
static void AbortSubTransaction(void)
Definition: xact.c:5175
static TransactionState CurrentTransactionState
Definition: xact.c:257

References AbortCurrentTransactionInternal(), AbortSubTransaction(), TransactionStateData::blockState, CleanupSubTransaction(), CurrentTransactionState, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

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

◆ AbortCurrentTransactionInternal()

static void AbortCurrentTransactionInternal ( void  )
static

Definition at line 3433 of file xact.c.

3434 {
3436 
3437  /* This states are handled in AbortCurrentTransaction() */
3439  s->blockState != TBLOCK_SUBRELEASE &&
3440  s->blockState != TBLOCK_SUBCOMMIT &&
3442  s->blockState != TBLOCK_SUBRESTART &&
3445 
3446  switch (s->blockState)
3447  {
3448  case TBLOCK_DEFAULT:
3449  if (s->state == TRANS_DEFAULT)
3450  {
3451  /* we are idle, so nothing to do */
3452  }
3453  else
3454  {
3455  /*
3456  * We can get here after an error during transaction start
3457  * (state will be TRANS_START). Need to clean up the
3458  * incompletely started transaction. First, adjust the
3459  * low-level state to suppress warning message from
3460  * AbortTransaction.
3461  */
3462  if (s->state == TRANS_START)
3463  s->state = TRANS_INPROGRESS;
3464  AbortTransaction();
3466  }
3467  break;
3468 
3469  /*
3470  * If we aren't in a transaction block, we just do the basic abort
3471  * & cleanup transaction. For this purpose, we treat an implicit
3472  * transaction block as if it were a simple statement.
3473  */
3474  case TBLOCK_STARTED:
3476  AbortTransaction();
3479  break;
3480 
3481  /*
3482  * If we are in TBLOCK_BEGIN it means something screwed up right
3483  * after reading "BEGIN TRANSACTION". We assume that the user
3484  * will interpret the error as meaning the BEGIN failed to get him
3485  * into a transaction block, so we should abort and return to idle
3486  * state.
3487  */
3488  case TBLOCK_BEGIN:
3489  AbortTransaction();
3492  break;
3493 
3494  /*
3495  * We are somewhere in a transaction block and we've gotten a
3496  * failure, so we abort the transaction and set up the persistent
3497  * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3498  */
3499  case TBLOCK_INPROGRESS:
3501  AbortTransaction();
3502  s->blockState = TBLOCK_ABORT;
3503  /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3504  break;
3505 
3506  /*
3507  * Here, we failed while trying to COMMIT. Clean up the
3508  * transaction and return to idle state (we do not want to stay in
3509  * the transaction).
3510  */
3511  case TBLOCK_END:
3512  AbortTransaction();
3515  break;
3516 
3517  /*
3518  * Here, we are already in an aborted transaction state and are
3519  * waiting for a ROLLBACK, but for some reason we failed again! So
3520  * we just remain in the abort state.
3521  */
3522  case TBLOCK_ABORT:
3523  case TBLOCK_SUBABORT:
3524  break;
3525 
3526  /*
3527  * We are in a failed transaction and we got the ROLLBACK command.
3528  * We have already aborted, we just need to cleanup and go to idle
3529  * state.
3530  */
3531  case TBLOCK_ABORT_END:
3534  break;
3535 
3536  /*
3537  * We are in a live transaction and we got a ROLLBACK command.
3538  * Abort, cleanup, go to idle state.
3539  */
3540  case TBLOCK_ABORT_PENDING:
3541  AbortTransaction();
3544  break;
3545 
3546  /*
3547  * Here, we failed while trying to PREPARE. Clean up the
3548  * transaction and return to idle state (we do not want to stay in
3549  * the transaction).
3550  */
3551  case TBLOCK_PREPARE:
3552  AbortTransaction();
3555  break;
3556 
3557  /*
3558  * We got an error inside a subtransaction. Abort just the
3559  * subtransaction, and go to the persistent SUBABORT state until
3560  * we get ROLLBACK.
3561  */
3562  case TBLOCK_SUBINPROGRESS:
3565  break;
3566  default:
3567  /* Keep compiler quiet */
3568  break;
3569  }
3570 }
Assert(fmt[strlen(fmt) - 1] !='\n')
TransState state
Definition: xact.c:197
static void CleanupTransaction(void)
Definition: xact.c:2945
static void AbortTransaction(void)
Definition: xact.c:2749

References AbortSubTransaction(), AbortTransaction(), Assert(), TransactionStateData::blockState, 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 4824 of file xact.c.

4825 {
4827 
4828  /* Ensure we're not running in a doomed memory context */
4829  AtAbort_Memory();
4830 
4831  /*
4832  * Get out of any transaction or nested transaction
4833  */
4834  do
4835  {
4836  switch (s->blockState)
4837  {
4838  case TBLOCK_DEFAULT:
4839  if (s->state == TRANS_DEFAULT)
4840  {
4841  /* Not in a transaction, do nothing */
4842  }
4843  else
4844  {
4845  /*
4846  * We can get here after an error during transaction start
4847  * (state will be TRANS_START). Need to clean up the
4848  * incompletely started transaction. First, adjust the
4849  * low-level state to suppress warning message from
4850  * AbortTransaction.
4851  */
4852  if (s->state == TRANS_START)
4853  s->state = TRANS_INPROGRESS;
4854  AbortTransaction();
4856  }
4857  break;
4858  case TBLOCK_STARTED:
4859  case TBLOCK_BEGIN:
4860  case TBLOCK_INPROGRESS:
4863  case TBLOCK_END:
4864  case TBLOCK_ABORT_PENDING:
4865  case TBLOCK_PREPARE:
4866  /* In a transaction, so clean up */
4867  AbortTransaction();
4870  break;
4871  case TBLOCK_ABORT:
4872  case TBLOCK_ABORT_END:
4873 
4874  /*
4875  * AbortTransaction is already done, still need Cleanup.
4876  * However, if we failed partway through running ROLLBACK,
4877  * there will be an active portal running that command, which
4878  * we need to shut down before doing CleanupTransaction.
4879  */
4880  AtAbort_Portals();
4883  break;
4884 
4885  /*
4886  * In a subtransaction, so clean it up and abort parent too
4887  */
4888  case TBLOCK_SUBBEGIN:
4889  case TBLOCK_SUBINPROGRESS:
4890  case TBLOCK_SUBRELEASE:
4891  case TBLOCK_SUBCOMMIT:
4893  case TBLOCK_SUBRESTART:
4896  s = CurrentTransactionState; /* changed by pop */
4897  break;
4898 
4899  case TBLOCK_SUBABORT:
4900  case TBLOCK_SUBABORT_END:
4902  /* As above, but AbortSubTransaction already done */
4903  if (s->curTransactionOwner)
4904  {
4905  /* As in TBLOCK_ABORT, might have a live portal to zap */
4910  }
4912  s = CurrentTransactionState; /* changed by pop */
4913  break;
4914  }
4915  } while (s->blockState != TBLOCK_DEFAULT);
4916 
4917  /* Should be out of all subxacts now */
4918  Assert(s->parent == NULL);
4919 
4920  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4921  AtCleanup_Memory();
4922 }
void AtAbort_Portals(void)
Definition: portalmem.c:781
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:979
SubTransactionId subTransactionId
Definition: xact.c:194
struct TransactionStateData * parent
Definition: xact.c:215
ResourceOwner curTransactionOwner
Definition: xact.c:202
static void AtCleanup_Memory(void)
Definition: xact.c:1943
static void AtAbort_Memory(void)
Definition: xact.c:1853

References AbortSubTransaction(), AbortTransaction(), Assert(), AtAbort_Memory(), AtAbort_Portals(), AtCleanup_Memory(), AtSubAbort_Portals(), TransactionStateData::blockState, CleanupSubTransaction(), CleanupTransaction(), CurrentTransactionState, TransactionStateData::curTransactionOwner, 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, 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 5175 of file xact.c.

5176 {
5178 
5179  /* Prevent cancel/die interrupt while cleaning up */
5180  HOLD_INTERRUPTS();
5181 
5182  /* Make sure we have a valid memory context and resource owner */
5185 
5186  /*
5187  * Release any LW locks we might be holding as quickly as possible.
5188  * (Regular locks, however, must be held till we finish aborting.)
5189  * Releasing LW locks is critical since we might try to grab them again
5190  * while cleaning up!
5191  *
5192  * FIXME This may be incorrect --- Are there some locks we should keep?
5193  * Buffer locks, for example? I don't think so but I'm not sure.
5194  */
5195  LWLockReleaseAll();
5196 
5199  UnlockBuffers();
5200 
5201  /* Reset WAL record construction state */
5203 
5204  /* Cancel condition variable sleep */
5206 
5207  /*
5208  * Also clean up any open wait for lock, since the lock manager will choke
5209  * if we try to wait for another lock before doing this.
5210  */
5211  LockErrorCleanup();
5212 
5213  /*
5214  * If any timeout events are still active, make sure the timeout interrupt
5215  * is scheduled. This covers possible loss of a timeout interrupt due to
5216  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5217  * We delay this till after LockErrorCleanup so that we don't uselessly
5218  * reschedule lock or deadlock check timeouts.
5219  */
5221 
5222  /*
5223  * Re-enable signals, in case we got here by longjmp'ing out of a signal
5224  * handler. We do this fairly early in the sequence so that the timeout
5225  * infrastructure will be functional if needed while aborting.
5226  */
5227  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5228 
5229  /*
5230  * check the current transaction state
5231  */
5232  ShowTransactionState("AbortSubTransaction");
5233 
5234  if (s->state != TRANS_INPROGRESS)
5235  elog(WARNING, "AbortSubTransaction while in %s state",
5237 
5238  s->state = TRANS_ABORT;
5239 
5240  /*
5241  * Reset user ID which might have been changed transiently. (See notes in
5242  * AbortTransaction.)
5243  */
5245 
5246  /* Forget about any active REINDEX. */
5248 
5249  /* Reset logical streaming state. */
5251 
5252  /*
5253  * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5254  * exports are not supported in subtransactions.
5255  */
5256 
5257  /*
5258  * If this subxact has started any unfinished parallel operation, clean up
5259  * its workers and exit parallel mode. Don't warn about leaked resources.
5260  */
5262  s->parallelModeLevel = 0;
5263 
5264  /*
5265  * We can skip all this stuff if the subxact failed before creating a
5266  * ResourceOwner...
5267  */
5268  if (s->curTransactionOwner)
5269  {
5270  AfterTriggerEndSubXact(false);
5276  s->parent->subTransactionId);
5278 
5279  /* Advertise the fact that we aborted in pg_xact. */
5280  (void) RecordTransactionAbort(true);
5281 
5282  /* Post-abort cleanup */
5285 
5287  s->parent->subTransactionId);
5288 
5291  false, false);
5292 
5294  s->parent->subTransactionId);
5295 
5296 
5297  /*
5298  * AtEOSubXact_Inval sometimes needs to temporarily bump the refcount
5299  * on the relcache entries that it processes. We cannot use the
5300  * subtransaction's resource owner anymore, because we've already
5301  * started releasing it. But we can use the parent resource owner.
5302  */
5304 
5305  AtEOSubXact_Inval(false);
5306 
5308 
5311  false, false);
5314  false, false);
5315  AtSubAbort_smgr();
5316 
5317  AtEOXact_GUC(false, s->gucNestLevel);
5318  AtEOSubXact_SPI(false, s->subTransactionId);
5320  s->parent->subTransactionId);
5322  s->parent->subTransactionId);
5324  s->parent->subTransactionId);
5326  AtEOSubXact_PgStat(false, s->nestingLevel);
5328  }
5329 
5330  /*
5331  * Restore the upper transaction's read-only state, too. This should be
5332  * redundant with GUC's cleanup but we may as well do it for consistency
5333  * with the commit case.
5334  */
5336 
5338 }
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:4767
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:2264
void ResetReindexState(int nestLevel)
Definition: index.c:4142
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1082
void ResetLogicalStreamingState(void)
Definition: logical.c:1914
void LWLockReleaseAll(void)
Definition: lwlock.c:1877
#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:3341
ResourceOwner CurrentResourceOwner
Definition: resowner.c:165
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:211
FullTransactionId fullTransactionId
Definition: xact.c:193
bool prevXactReadOnly
Definition: xact.c:208
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:18280
void reschedule_timeouts(void)
Definition: timeout.c:540
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5324
static void pgstat_report_wait_end(void)
Definition: wait_event.h:104
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3860
static void AtSubAbort_Memory(void)
Definition: xact.c:1873
static const char * TransStateAsString(TransState state)
Definition: xact.c:5724
bool XactReadOnly
Definition: xact.c:80
static void AtSubAbort_childXids(void)
Definition: xact.c:1911
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1898
static void ShowTransactionState(const char *str)
Definition: xact.c:5612
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1723
@ 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(), CurrentResourceOwner, 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 AbortCurrentTransaction(), AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), CommitTransactionCommand(), CommitTransactionCommandInternal(), and RollbackAndReleaseCurrentSubTransaction().

◆ AbortTransaction()

static void AbortTransaction ( void  )
static

Definition at line 2749 of file xact.c.

2750 {
2752  TransactionId latestXid;
2753  bool is_parallel_worker;
2754 
2755  /* Prevent cancel/die interrupt while cleaning up */
2756  HOLD_INTERRUPTS();
2757 
2758  /* Disable transaction timeout */
2759  if (TransactionTimeout > 0)
2761 
2762  /* Make sure we have a valid memory context and resource owner */
2763  AtAbort_Memory();
2765 
2766  /*
2767  * Release any LW locks we might be holding as quickly as possible.
2768  * (Regular locks, however, must be held till we finish aborting.)
2769  * Releasing LW locks is critical since we might try to grab them again
2770  * while cleaning up!
2771  */
2772  LWLockReleaseAll();
2773 
2774  /* Clear wait information and command progress indicator */
2777 
2778  /* Clean up buffer context locks, too */
2779  UnlockBuffers();
2780 
2781  /* Reset WAL record construction state */
2783 
2784  /* Cancel condition variable sleep */
2786 
2787  /*
2788  * Also clean up any open wait for lock, since the lock manager will choke
2789  * if we try to wait for another lock before doing this.
2790  */
2791  LockErrorCleanup();
2792 
2793  /*
2794  * If any timeout events are still active, make sure the timeout interrupt
2795  * is scheduled. This covers possible loss of a timeout interrupt due to
2796  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2797  * We delay this till after LockErrorCleanup so that we don't uselessly
2798  * reschedule lock or deadlock check timeouts.
2799  */
2801 
2802  /*
2803  * Re-enable signals, in case we got here by longjmp'ing out of a signal
2804  * handler. We do this fairly early in the sequence so that the timeout
2805  * infrastructure will be functional if needed while aborting.
2806  */
2807  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2808 
2809  /*
2810  * check the current transaction state
2811  */
2812  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2813  if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2814  elog(WARNING, "AbortTransaction while in %s state",
2816  Assert(s->parent == NULL);
2817 
2818  /*
2819  * set the current transaction state information appropriately during the
2820  * abort processing
2821  */
2822  s->state = TRANS_ABORT;
2823 
2824  /*
2825  * Reset user ID which might have been changed transiently. We need this
2826  * to clean up in case control escaped out of a SECURITY DEFINER function
2827  * or other local change of CurrentUserId; therefore, the prior value of
2828  * SecurityRestrictionContext also needs to be restored.
2829  *
2830  * (Note: it is not necessary to restore session authorization or role
2831  * settings here because those can only be changed via GUC, and GUC will
2832  * take care of rolling them back if need be.)
2833  */
2835 
2836  /* Forget about any active REINDEX. */
2838 
2839  /* Reset logical streaming state. */
2841 
2842  /* Reset snapshot export state. */
2844 
2845  /*
2846  * If this xact has started any unfinished parallel operation, clean up
2847  * its workers and exit parallel mode. Don't warn about leaked resources.
2848  */
2849  AtEOXact_Parallel(false);
2850  s->parallelModeLevel = 0;
2851  s->parallelChildXact = false; /* should be false already */
2852 
2853  /*
2854  * do abort processing
2855  */
2856  AfterTriggerEndXact(false); /* 'false' means it's abort */
2857  AtAbort_Portals();
2858  smgrDoPendingSyncs(false, is_parallel_worker);
2859  AtEOXact_LargeObject(false);
2860  AtAbort_Notify();
2861  AtEOXact_RelationMap(false, is_parallel_worker);
2862  AtAbort_Twophase();
2863 
2864  /*
2865  * Advertise the fact that we aborted in pg_xact (assuming that we got as
2866  * far as assigning an XID to advertise). But if we're inside a parallel
2867  * worker, skip this; the user backend must be the one to write the abort
2868  * record.
2869  */
2870  if (!is_parallel_worker)
2871  latestXid = RecordTransactionAbort(false);
2872  else
2873  {
2874  latestXid = InvalidTransactionId;
2875 
2876  /*
2877  * Since the parallel leader won't get our value of XactLastRecEnd in
2878  * this case, we nudge WAL-writer ourselves in this case. See related
2879  * comments in RecordTransactionAbort for why this matters.
2880  */
2882  }
2883 
2884  TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2885 
2886  /*
2887  * Let others know about no transaction in progress by me. Note that this
2888  * must be done _before_ releasing locks we hold and _after_
2889  * RecordTransactionAbort.
2890  */
2891  ProcArrayEndTransaction(MyProc, latestXid);
2892 
2893  /*
2894  * Post-abort cleanup. See notes in CommitTransaction() concerning
2895  * ordering. We can skip all of it if the transaction failed before
2896  * creating a resource owner.
2897  */
2898  if (TopTransactionResourceOwner != NULL)
2899  {
2900  if (is_parallel_worker)
2902  else
2904 
2907  false, true);
2908  AtEOXact_Buffers(false);
2909  AtEOXact_RelationCache(false);
2910  AtEOXact_Inval(false);
2914  false, true);
2917  false, true);
2918  smgrDoPendingDeletes(false);
2919 
2920  AtEOXact_GUC(false, 1);
2921  AtEOXact_SPI(false);
2922  AtEOXact_Enum();
2924  AtEOXact_Namespace(false, is_parallel_worker);
2925  AtEOXact_SMgr();
2926  AtEOXact_Files(false);
2928  AtEOXact_HashTables(false);
2929  AtEOXact_PgStat(false, is_parallel_worker);
2930  AtEOXact_ApplyLauncher(false);
2933  }
2934 
2935  /*
2936  * State remains TRANS_ABORT until CleanupTransaction().
2937  */
2939 }
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:5003
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:3212
uint32 TransactionId
Definition: c.h:639
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:1086
void AtEOXact_MultiXact(void)
Definition: multixact.c:1734
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:3189
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition: relmapper.c:541
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:167
void AtEOXact_SMgr(void)
Definition: smgr.c:806
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:756
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:196
struct PGPROC::@116 vxid
bool parallelChildXact
Definition: xact.c:212
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:18248
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:5228
void AtAbort_Twophase(void)
Definition: twophase.c:304
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1885
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3800
@ XACT_EVENT_ABORT
Definition: xact.h:130
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:131
XLogRecPtr XactLastRecEnd
Definition: xlog.c:254
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2564

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

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

1854 {
1855  /*
1856  * Switch into TransactionAbortContext, which should have some free space
1857  * even if nothing else does. We'll work in this context until we've
1858  * finished cleaning up.
1859  *
1860  * It is barely possible to get here when we've not been able to create
1861  * TransactionAbortContext yet; if so use TopMemoryContext.
1862  */
1863  if (TransactionAbortContext != NULL)
1865  else
1867 }
MemoryContext TopMemoryContext
Definition: mcxt.c:137
MemoryContextSwitchTo(old_ctx)
static MemoryContext TransactionAbortContext
Definition: xact.c:300

References MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1885 of file xact.c.

1886 {
1887  /*
1888  * Make sure we have a valid ResourceOwner, if possible (else it will be
1889  * NULL, which is OK)
1890  */
1892 }

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1558 of file xact.c.

1559 {
1560  /*
1561  * Make any pending relation map changes visible. We must do this before
1562  * processing local sinval messages, so that the map changes will get
1563  * reflected into the relcache when relcache invals are processed.
1564  */
1566 
1567  /*
1568  * Make catalog changes visible to me for the next command.
1569  */
1571 }
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 1943 of file xact.c.

1944 {
1946 
1947  /*
1948  * Now that we're "out" of a transaction, have the system allocate things
1949  * in the top memory context instead of per-transaction contexts.
1950  */
1952 
1953  /*
1954  * Clear the special abort context for next time.
1955  */
1956  if (TransactionAbortContext != NULL)
1958 
1959  /*
1960  * Release all transaction-local memory.
1961  */
1962  if (TopTransactionContext != NULL)
1964  TopTransactionContext = NULL;
1965  CurTransactionContext = NULL;
1967 }
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:371
MemoryContext TopTransactionContext
Definition: mcxt.c:142
MemoryContext CurTransactionContext
Definition: mcxt.c:143
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:442
MemoryContext curTransactionContext
Definition: xact.c:201

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

Referenced by AbortOutOfAnyTransaction(), and CleanupTransaction().

◆ AtCommit_Memory()

static void AtCommit_Memory ( void  )
static

Definition at line 1577 of file xact.c.

1578 {
1579  /*
1580  * Now that we're "out" of a transaction, have the system allocate things
1581  * in the top memory context instead of per-transaction contexts.
1582  */
1584 
1585  /*
1586  * Release all transaction-local memory.
1587  */
1588  Assert(TopTransactionContext != NULL);
1590  TopTransactionContext = NULL;
1591  CurTransactionContext = NULL;
1593 }

References Assert(), CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, MemoryContextDelete(), MemoryContextSwitchTo(), TopMemoryContext, and TopTransactionContext.

Referenced by CommitTransaction(), and PrepareTransaction().

◆ AtStart_Cache()

static void AtStart_Cache ( void  )
static

Definition at line 1164 of file xact.c.

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

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1173 of file xact.c.

1174 {
1176 
1177  /*
1178  * If this is the first time through, create a private context for
1179  * AbortTransaction to work in. By reserving some space now, we can
1180  * insulate AbortTransaction from out-of-memory scenarios. Like
1181  * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1182  * size, so that space will be reserved immediately.
1183  */
1184  if (TransactionAbortContext == NULL)
1187  "TransactionAbortContext",
1188  32 * 1024,
1189  32 * 1024,
1190  32 * 1024);
1191 
1192  /*
1193  * We shouldn't have a transaction context already.
1194  */
1195  Assert(TopTransactionContext == NULL);
1196 
1197  /*
1198  * Create a toplevel context for the transaction.
1199  */
1202  "TopTransactionContext",
1204 
1205  /*
1206  * In a top-level transaction, CurTransactionContext is the same as
1207  * TopTransactionContext.
1208  */
1211 
1212  /* Make the CurTransactionContext active. */
1214 }
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:153

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

Referenced by StartTransaction().

◆ AtStart_ResourceOwner()

static void AtStart_ResourceOwner ( void  )
static

Definition at line 1220 of file xact.c.

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

1912 {
1914 
1915  /*
1916  * We keep the child-XID arrays in TopTransactionContext (see
1917  * AtSubCommit_childXids). This means we'd better free the array
1918  * explicitly at abort to avoid leakage.
1919  */
1920  if (s->childXids != NULL)
1921  pfree(s->childXids);
1922  s->childXids = NULL;
1923  s->nChildXids = 0;
1924  s->maxChildXids = 0;
1925 
1926  /*
1927  * We could prune the unreportedXids array here. But we don't bother. That
1928  * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1929  * would likely introduce more CPU time into the more common paths, so we
1930  * choose not to do that.
1931  */
1932 }
TransactionId * childXids
Definition: xact.c:203

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

Definition at line 1873 of file xact.c.

1874 {
1876 
1878 }

References Assert(), MemoryContextSwitchTo(), and TransactionAbortContext.

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1898 of file xact.c.

1899 {
1901 
1902  /* Make sure we have a valid ResourceOwner */
1904 }

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 1979 of file xact.c.

1980 {
1982 
1983  Assert(s->parent != NULL);
1984 
1985  /* Make sure we're not in an about-to-be-deleted context */
1988 
1989  /*
1990  * Clear the special abort context for next time.
1991  */
1992  if (TransactionAbortContext != NULL)
1994 
1995  /*
1996  * Delete the subxact local memory contexts. Its CurTransactionContext can
1997  * go too (note this also kills CurTransactionContexts from any children
1998  * of the subxact).
1999  */
2000  if (s->curTransactionContext)
2002  s->curTransactionContext = NULL;
2003 }

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

Referenced by CleanupSubTransaction().

◆ AtSubCommit_childXids()

static void AtSubCommit_childXids ( void  )
static

Definition at line 1633 of file xact.c.

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

1605 {
1607 
1608  Assert(s->parent != NULL);
1609 
1610  /* Return to parent transaction level's memory context. */
1613 
1614  /*
1615  * Ordinarily we cannot throw away the child's CurTransactionContext,
1616  * since the data it contains will be needed at upper commit. However, if
1617  * there isn't actually anything in it, we can throw it away. This avoids
1618  * a small memory leak in the common case of "trivial" subxacts.
1619  */
1621  {
1623  s->curTransactionContext = NULL;
1624  }
1625 }
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:731

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

1249 {
1251 
1252  Assert(CurTransactionContext != NULL);
1253 
1254  /*
1255  * Create a CurTransactionContext, which will be used to hold data that
1256  * survives subtransaction commit but disappears on subtransaction abort.
1257  * We make it a child of the immediate parent's CurTransactionContext.
1258  */
1260  "CurTransactionContext",
1263 
1264  /* Make the CurTransactionContext active. */
1266 }

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

Referenced by StartSubTransaction().

◆ AtSubStart_ResourceOwner()

static void AtSubStart_ResourceOwner ( void  )
static

Definition at line 1272 of file xact.c.

1273 {
1275 
1276  Assert(s->parent != NULL);
1277 
1278  /*
1279  * Create a resource owner for the subtransaction. We make it a child of
1280  * the immediate parent's resource owner.
1281  */
1282  s->curTransactionOwner =
1284  "SubTransaction");
1285 
1288 }

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

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4288 of file xact.c.

4289 {
4291 
4292  /*
4293  * If we are in STARTED state (that is, no transaction block is open),
4294  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4295  * block.
4296  *
4297  * For caller convenience, we consider all other transaction states as
4298  * legal here; otherwise the caller would need its own state check, which
4299  * seems rather pointless.
4300  */
4301  if (s->blockState == TBLOCK_STARTED)
4303 }

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

Referenced by exec_simple_query().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4656 of file xact.c.

4657 {
4659  bool save_ExitOnAnyError = ExitOnAnyError;
4660 
4661  /*
4662  * Errors within this function are improbable, but if one does happen we
4663  * force a FATAL exit. Callers generally aren't prepared to handle losing
4664  * control, and moreover our transaction state is probably corrupted if we
4665  * fail partway through; so an ordinary ERROR longjmp isn't okay.
4666  */
4667  ExitOnAnyError = true;
4668 
4669  /*
4670  * We do not check for parallel mode here. It's permissible to start and
4671  * end "internal" subtransactions while in parallel mode, so long as no
4672  * new XIDs or command IDs are assigned. Enforcement of that occurs in
4673  * AssignTransactionId() and CommandCounterIncrement().
4674  */
4675 
4676  switch (s->blockState)
4677  {
4678  case TBLOCK_STARTED:
4679  case TBLOCK_INPROGRESS:
4682  case TBLOCK_END:
4683  case TBLOCK_PREPARE:
4684  case TBLOCK_SUBINPROGRESS:
4685  /* Normal subtransaction start */
4686  PushTransaction();
4687  s = CurrentTransactionState; /* changed by push */
4688 
4689  /*
4690  * Savepoint names, like the TransactionState block itself, live
4691  * in TopTransactionContext.
4692  */
4693  if (name)
4695  break;
4696 
4697  /* These cases are invalid. */
4698  case TBLOCK_DEFAULT:
4699  case TBLOCK_BEGIN:
4700  case TBLOCK_SUBBEGIN:
4701  case TBLOCK_SUBRELEASE:
4702  case TBLOCK_SUBCOMMIT:
4703  case TBLOCK_ABORT:
4704  case TBLOCK_SUBABORT:
4705  case TBLOCK_ABORT_END:
4706  case TBLOCK_SUBABORT_END:
4707  case TBLOCK_ABORT_PENDING:
4709  case TBLOCK_SUBRESTART:
4711  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4713  break;
4714  }
4715 
4718 
4719  ExitOnAnyError = save_ExitOnAnyError;
4720 }
#define FATAL
Definition: elog.h:41
bool ExitOnAnyError
Definition: globals.c:120
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1670
const char * name
static void PushTransaction(void)
Definition: xact.c:5380
void StartTransactionCommand(void)
Definition: xact.c:2995
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5671
void CommitTransactionCommand(void)
Definition: xact.c:3093

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

3887 {
3889 
3890  switch (s->blockState)
3891  {
3892  /*
3893  * We are not inside a transaction block, so allow one to begin.
3894  */
3895  case TBLOCK_STARTED:
3896  s->blockState = TBLOCK_BEGIN;
3897  break;
3898 
3899  /*
3900  * BEGIN converts an implicit transaction block to a regular one.
3901  * (Note that we allow this even if we've already done some
3902  * commands, which is a bit odd but matches historical practice.)
3903  */
3905  s->blockState = TBLOCK_BEGIN;
3906  break;
3907 
3908  /*
3909  * Already a transaction block in progress.
3910  */
3911  case TBLOCK_INPROGRESS:
3913  case TBLOCK_SUBINPROGRESS:
3914  case TBLOCK_ABORT:
3915  case TBLOCK_SUBABORT:
3916  ereport(WARNING,
3917  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3918  errmsg("there is already a transaction in progress")));
3919  break;
3920 
3921  /* These cases are invalid. */
3922  case TBLOCK_DEFAULT:
3923  case TBLOCK_BEGIN:
3924  case TBLOCK_SUBBEGIN:
3925  case TBLOCK_END:
3926  case TBLOCK_SUBRELEASE:
3927  case TBLOCK_SUBCOMMIT:
3928  case TBLOCK_ABORT_END:
3929  case TBLOCK_SUBABORT_END:
3930  case TBLOCK_ABORT_PENDING:
3932  case TBLOCK_SUBRESTART:
3934  case TBLOCK_PREPARE:
3935  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3937  break;
3938  }
3939 }

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

5672 {
5673  switch (blockState)
5674  {
5675  case TBLOCK_DEFAULT:
5676  return "DEFAULT";
5677  case TBLOCK_STARTED:
5678  return "STARTED";
5679  case TBLOCK_BEGIN:
5680  return "BEGIN";
5681  case TBLOCK_INPROGRESS:
5682  return "INPROGRESS";
5684  return "IMPLICIT_INPROGRESS";
5686  return "PARALLEL_INPROGRESS";
5687  case TBLOCK_END:
5688  return "END";
5689  case TBLOCK_ABORT:
5690  return "ABORT";
5691  case TBLOCK_ABORT_END:
5692  return "ABORT_END";
5693  case TBLOCK_ABORT_PENDING:
5694  return "ABORT_PENDING";
5695  case TBLOCK_PREPARE:
5696  return "PREPARE";
5697  case TBLOCK_SUBBEGIN:
5698  return "SUBBEGIN";
5699  case TBLOCK_SUBINPROGRESS:
5700  return "SUBINPROGRESS";
5701  case TBLOCK_SUBRELEASE:
5702  return "SUBRELEASE";
5703  case TBLOCK_SUBCOMMIT:
5704  return "SUBCOMMIT";
5705  case TBLOCK_SUBABORT:
5706  return "SUBABORT";
5707  case TBLOCK_SUBABORT_END:
5708  return "SUBABORT_END";
5710  return "SUBABORT_PENDING";
5711  case TBLOCK_SUBRESTART:
5712  return "SUBRESTART";
5714  return "SUBABORT_RESTART";
5715  }
5716  return "UNRECOGNIZED";
5717 }

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

3863 {
3864  SubXactCallbackItem *item;
3866 
3867  for (item = SubXact_callbacks; item; item = next)
3868  {
3869  /* allow callbacks to unregister themselves when called */
3870  next = item->next;
3871  item->callback(event, mySubid, parentSubid, item->arg);
3872  }
3873 }
static int32 next
Definition: blutils.c:221
struct SubXactCallbackItem * next
Definition: xact.c:319
SubXactCallback callback
Definition: xact.c:320
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:324

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

3801 {
3802  XactCallbackItem *item;
3804 
3805  for (item = Xact_callbacks; item; item = next)
3806  {
3807  /* allow callbacks to unregister themselves when called */
3808  next = item->next;
3809  item->callback(event, item->arg);
3810  }
3811 }
struct XactCallbackItem * next
Definition: xact.c:307
void * arg
Definition: xact.c:309
XactCallback callback
Definition: xact.c:308
static XactCallbackItem * Xact_callbacks
Definition: xact.c:312

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

3685 {
3686  /*
3687  * xact block already started?
3688  */
3689  if (IsTransactionBlock())
3690  return;
3691 
3692  /*
3693  * subtransaction?
3694  */
3695  if (IsSubTransaction())
3696  return;
3697 
3698  /*
3699  * inside a function call?
3700  */
3701  if (!isTopLevel)
3702  return;
3703 
3704  ereport(throwError ? ERROR : WARNING,
3705  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3706  /* translator: %s represents an SQL statement name */
3707  errmsg("%s can only be used in transaction blocks",
3708  stmtType)));
3709 }
bool IsSubTransaction(void)
Definition: xact.c:5001
bool IsTransactionBlock(void)
Definition: xact.c:4928

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

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5347 of file xact.c.

5348 {
5350 
5351  ShowTransactionState("CleanupSubTransaction");
5352 
5353  if (s->state != TRANS_ABORT)
5354  elog(WARNING, "CleanupSubTransaction while in %s state",
5356 
5358 
5361  if (s->curTransactionOwner)
5363  s->curTransactionOwner = NULL;
5364 
5366 
5367  s->state = TRANS_DEFAULT;
5368 
5369  PopTransaction();
5370 }
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:1979
static void PopTransaction(void)
Definition: xact.c:5442

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 AbortCurrentTransaction(), AbortOutOfAnyTransaction(), CommitTransactionCommand(), CommitTransactionCommandInternal(), and RollbackAndReleaseCurrentSubTransaction().

◆ CleanupTransaction()

static void CleanupTransaction ( void  )
static

Definition at line 2945 of file xact.c.

2946 {
2948 
2949  /*
2950  * State should still be TRANS_ABORT from AbortTransaction().
2951  */
2952  if (s->state != TRANS_ABORT)
2953  elog(FATAL, "CleanupTransaction: unexpected state %s",
2955 
2956  /*
2957  * do abort cleanup processing
2958  */
2959  AtCleanup_Portals(); /* now safe to release portal memory */
2960  AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2961 
2962  CurrentResourceOwner = NULL; /* and resource owner */
2965  s->curTransactionOwner = NULL;
2968 
2969  AtCleanup_Memory(); /* and transaction memory */
2970 
2973  s->nestingLevel = 0;
2974  s->gucNestLevel = 0;
2975  s->childXids = NULL;
2976  s->nChildXids = 0;
2977  s->maxChildXids = 0;
2978  s->parallelModeLevel = 0;
2979  s->parallelChildXact = false;
2980 
2983 
2984  /*
2985  * done with abort processing, set current transaction state back to
2986  * default
2987  */
2988  s->state = TRANS_DEFAULT;
2989 }
#define InvalidSubTransactionId
Definition: c.h:645
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 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 1097 of file xact.c.

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

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(), ATAddCheckNNConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecCmd(), ATExecDropColumn(), ATExecDropExpression(), ATExecDropIdentity(), ATExecSetAccessMethodNoStorage(), ATExecSetCompression(), ATExecSetExpression(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), ATInheritAdjustNotNulls(), 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(), DropClonedTriggersFromPartition(), dropconstraint_internal(), 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(), RemoveRoleFromObjectPolicy(), RenumberEnumType(), replorigin_create(), replorigin_drop_by_name(), ri_PerformCheck(), SetDatatabaseHasLoginEventTriggers(), SetDefaultACL(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), standard_ProcessUtility(), StoreConstraints(), StorePartitionBound(), tryAttachPartitionForeignKey(), vacuum(), and validatePartitionedIndex().

◆ CommitSubTransaction()

static void CommitSubTransaction ( void  )
static

Definition at line 5061 of file xact.c.

5062 {
5064 
5065  ShowTransactionState("CommitSubTransaction");
5066 
5067  if (s->state != TRANS_INPROGRESS)
5068  elog(WARNING, "CommitSubTransaction while in %s state",
5070 
5071  /* Pre-commit processing goes here */
5072 
5074  s->parent->subTransactionId);
5075 
5076  /*
5077  * If this subxact has started any unfinished parallel operation, clean up
5078  * its workers and exit parallel mode. Warn about leaked resources.
5079  */
5081  if (s->parallelModeLevel != 0)
5082  {
5083  elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5084  s->parallelModeLevel);
5085  s->parallelModeLevel = 0;
5086  }
5087 
5088  /* Do the actual "commit", such as it is */
5089  s->state = TRANS_COMMIT;
5090 
5091  /* Must CCI to ensure commands of subtransaction are seen as done */
5093 
5094  /*
5095  * Prior to 8.4 we marked subcommit in clog at this point. We now only
5096  * perform that step, if required, as part of the atomic update of the
5097  * whole transaction tree at top level commit or abort.
5098  */
5099 
5100  /* Post-commit cleanup */
5103  AfterTriggerEndSubXact(true);
5106  s->parent->nestingLevel,
5109  s->parent->subTransactionId);
5111 
5113  s->parent->subTransactionId);
5114 
5117  true, false);
5119  s->parent->subTransactionId);
5120  AtEOSubXact_Inval(true);
5121  AtSubCommit_smgr();
5122 
5123  /*
5124  * The only lock we actually release here is the subtransaction XID lock.
5125  */
5129 
5130  /*
5131  * Other locks should get transferred to their parent resource owner.
5132  */
5135  true, false);
5138  true, false);
5139 
5140  AtEOXact_GUC(true, s->gucNestLevel);
5143  s->parent->subTransactionId);
5145  s->parent->subTransactionId);
5147  s->parent->subTransactionId);
5149  AtEOSubXact_PgStat(true, s->nestingLevel);
5151 
5152  /*
5153  * We need to restore the upper transaction's read-only state, in case the
5154  * upper is read-write while the child is read-only; GUC will incorrectly
5155  * think it should leave the child state in place.
5156  */
5158 
5162  s->curTransactionOwner = NULL;
5163 
5165 
5166  s->state = TRANS_DEFAULT;
5167 
5168  PopTransaction();
5169 }
void AtSubCommit_Notify(void)
Definition: async.c:1691
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:643
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:1604
static void AtSubCommit_childXids(void)
Definition: xact.c:1633
void CommandCounterIncrement(void)
Definition: xact.c:1097
@ 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 2178 of file xact.c.

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

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 3093 of file xact.c.

3094 {
3095  while (true)
3096  {
3098  {
3099  /*
3100  * The current already-failed subtransaction is ending due to
3101  * a ROLLBACK or ROLLBACK TO command, so pop it and
3102  * recursively examine the parent (which could be in any of
3103  * several states).
3104  */
3105  case TBLOCK_SUBABORT_END:
3107  continue;
3108 
3109  /*
3110  * As above, but it's not dead yet, so abort first.
3111  */
3115  continue;
3116  default:
3117  break;
3118  }
3120  break;
3121  }
3122 }
static void CommitTransactionCommandInternal(void)
Definition: xact.c:3130

References AbortSubTransaction(), TransactionStateData::blockState, CleanupSubTransaction(), CommitTransactionCommandInternal(), CurrentTransactionState, TBLOCK_SUBABORT_END, and TBLOCK_SUBABORT_PENDING.

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 void CommitTransactionCommandInternal ( void  )
static

Definition at line 3130 of file xact.c.

3131 {
3134 
3135  /* This states are handled in CommitTransactionCommand() */
3138 
3139  /* Must save in case we need to restore below */
3141 
3142  switch (s->blockState)
3143  {
3144  /*
3145  * These shouldn't happen. TBLOCK_DEFAULT means the previous
3146  * StartTransactionCommand didn't set the STARTED state
3147  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3148  * by EndParallelWorkerTransaction(), not this function.
3149  */
3150  case TBLOCK_DEFAULT:
3152  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3154  break;
3155 
3156  /*
3157  * If we aren't in a transaction block, just do our usual
3158  * transaction commit, and return to the idle state.
3159  */
3160  case TBLOCK_STARTED:
3163  break;
3164 
3165  /*
3166  * We are completing a "BEGIN TRANSACTION" command, so we change
3167  * to the "transaction block in progress" state and return. (We
3168  * assume the BEGIN did nothing to the database, so we need no
3169  * CommandCounterIncrement.)
3170  */
3171  case TBLOCK_BEGIN:
3173  break;
3174 
3175  /*
3176  * This is the case when we have finished executing a command
3177  * someplace within a transaction block. We increment the command
3178  * counter and return.
3179  */
3180  case TBLOCK_INPROGRESS:
3182  case TBLOCK_SUBINPROGRESS:
3184  break;
3185 
3186  /*
3187  * We are completing a "COMMIT" command. Do it and return to the
3188  * idle state.
3189  */
3190  case TBLOCK_END:
3193  if (s->chain)
3194  {
3195  StartTransaction();
3197  s->chain = false;
3199  }
3200  break;
3201 
3202  /*
3203  * Here we are in the middle of a transaction block but one of the
3204  * commands caused an abort so we do nothing but remain in the
3205  * abort state. Eventually we will get a ROLLBACK command.
3206  */
3207  case TBLOCK_ABORT:
3208  case TBLOCK_SUBABORT:
3209  break;
3210 
3211  /*
3212  * Here we were in an aborted transaction block and we just got
3213  * the ROLLBACK command from the user, so clean up the
3214  * already-aborted transaction and return to the idle state.
3215  */
3216  case TBLOCK_ABORT_END:
3219  if (s->chain)
3220  {
3221  StartTransaction();
3223  s->chain = false;
3225  }
3226  break;
3227 
3228  /*
3229  * Here we were in a perfectly good transaction block but the user
3230  * told us to ROLLBACK anyway. We have to abort the transaction
3231  * and then clean up.
3232  */
3233  case TBLOCK_ABORT_PENDING:
3234  AbortTransaction();
3237  if (s->chain)
3238  {
3239  StartTransaction();
3241  s->chain = false;
3243  }
3244  break;
3245 
3246  /*
3247  * We are completing a "PREPARE TRANSACTION" command. Do it and
3248  * return to the idle state.
3249  */
3250  case TBLOCK_PREPARE:
3253  break;
3254 
3255  /*
3256  * The user issued a SAVEPOINT inside a transaction block. Start a
3257  * subtransaction. (DefineSavepoint already did PushTransaction,
3258  * so as to have someplace to put the SUBBEGIN state.)
3259  */
3260  case TBLOCK_SUBBEGIN:
3263  break;
3264 
3265  /*
3266  * The user issued a RELEASE command, so we end the current
3267  * subtransaction and return to the parent transaction. The parent
3268  * might be ended too, so repeat till we find an INPROGRESS
3269  * transaction or subtransaction.
3270  */
3271  case TBLOCK_SUBRELEASE:
3272  do
3273  {
3275  s = CurrentTransactionState; /* changed by pop */
3276  } while (s->blockState == TBLOCK_SUBRELEASE);
3277 
3280  break;
3281 
3282  /*
3283  * The user issued a COMMIT, so we end the current subtransaction
3284  * hierarchy and perform final commit. We do this by rolling up
3285  * any subtransactions into their parent, which leads to O(N^2)
3286  * operations with respect to resource owners - this isn't that
3287  * bad until we approach a thousands of savepoints but is
3288  * necessary for correctness should after triggers create new
3289  * resource owners.
3290  */
3291  case TBLOCK_SUBCOMMIT:
3292  do
3293  {
3295  s = CurrentTransactionState; /* changed by pop */
3296  } while (s->blockState == TBLOCK_SUBCOMMIT);
3297  /* If we had a COMMIT command, finish off the main xact too */
3298  if (s->blockState == TBLOCK_END)
3299  {
3300  Assert(s->parent == NULL);
3303  if (s->chain)
3304  {
3305  StartTransaction();
3307  s->chain = false;
3309  }
3310  }
3311  else if (s->blockState == TBLOCK_PREPARE)
3312  {
3313  Assert(s->parent == NULL);
3316  }
3317  else
3318  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3320  break;
3321 
3322  /*
3323  * The current subtransaction is the target of a ROLLBACK TO
3324  * command. Abort and pop it, then start a new subtransaction
3325  * with the same name.
3326  */
3327  case TBLOCK_SUBRESTART:
3328  {
3329  char *name;
3330  int savepointLevel;
3331 
3332  /* save name and keep Cleanup from freeing it */
3333  name = s->name;
3334  s->name = NULL;
3335  savepointLevel = s->savepointLevel;
3336 
3339 
3340  DefineSavepoint(NULL);
3341  s = CurrentTransactionState; /* changed by push */
3342  s->name = name;
3343  s->savepointLevel = savepointLevel;
3344 
3345  /* This is the same as TBLOCK_SUBBEGIN case */
3349  }
3350  break;
3351 
3352  /*
3353  * Same as above, but the subtransaction had already failed, so we
3354  * don't need AbortSubTransaction.
3355  */
3357  {
3358  char *name;
3359  int savepointLevel;
3360 
3361  /* save name and keep Cleanup from freeing it */
3362  name = s->name;
3363  s->name = NULL;
3364  savepointLevel = s->savepointLevel;
3365 
3367 
3368  DefineSavepoint(NULL);
3369  s = CurrentTransactionState; /* changed by push */
3370  s->name = name;
3371  s->savepointLevel = savepointLevel;
3372 
3373  /* This is the same as TBLOCK_SUBBEGIN case */
3377  }
3378  break;
3379  default:
3380  /* Keep compiler quiet */
3381  break;
3382  }
3383 }
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3072
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3080
static void StartTransaction(void)
Definition: xact.c:2014
void DefineSavepoint(const char *name)
Definition: xact.c:4335
static void CommitSubTransaction(void)
Definition: xact.c:5061
static void CommitTransaction(void)
Definition: xact.c:2178
static void PrepareTransaction(void)
Definition: xact.c:2460
static void StartSubTransaction(void)
Definition: xact.c:5024

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

4336 {
4338 
4339  /*
4340  * Workers synchronize transaction state at the beginning of each parallel
4341  * operation, so we can't account for new subtransactions after that
4342  * point. (Note that this check will certainly error out if s->blockState
4343  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4344  * below.)
4345  */
4347  ereport(ERROR,
4348  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4349  errmsg("cannot define savepoints during a parallel operation")));
4350 
4351  switch (s->blockState)
4352  {
4353  case TBLOCK_INPROGRESS:
4354  case TBLOCK_SUBINPROGRESS:
4355  /* Normal subtransaction start */
4356  PushTransaction();
4357  s = CurrentTransactionState; /* changed by push */
4358 
4359  /*
4360  * Savepoint names, like the TransactionState block itself, live
4361  * in TopTransactionContext.
4362  */
4363  if (name)
4365  break;
4366 
4367  /*
4368  * We disallow savepoint commands in implicit transaction blocks.
4369  * There would be no great difficulty in allowing them so far as
4370  * this module is concerned, but a savepoint seems inconsistent
4371  * with exec_simple_query's behavior of abandoning the whole query
4372  * string upon error. Also, the point of an implicit transaction
4373  * block (as opposed to a regular one) is to automatically close
4374  * after an error, so it's hard to see how a savepoint would fit
4375  * into that.
4376  *
4377  * The error messages for this are phrased as if there were no
4378  * active transaction block at all, which is historical but
4379  * perhaps could be improved.
4380  */
4382  ereport(ERROR,
4383  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4384  /* translator: %s represents an SQL statement name */
4385  errmsg("%s can only be used in transaction blocks",
4386  "SAVEPOINT")));
4387  break;
4388 
4389  /* These cases are invalid. */
4390  case TBLOCK_DEFAULT:
4391  case TBLOCK_STARTED:
4392  case TBLOCK_BEGIN:
4394  case TBLOCK_SUBBEGIN:
4395  case TBLOCK_END:
4396  case TBLOCK_SUBRELEASE:
4397  case TBLOCK_SUBCOMMIT:
4398  case TBLOCK_ABORT:
4399  case TBLOCK_SUBABORT:
4400  case TBLOCK_ABORT_END:
4401  case TBLOCK_SUBABORT_END:
4402  case TBLOCK_ABORT_PENDING:
4404  case TBLOCK_SUBRESTART:
4406  case TBLOCK_PREPARE:
4407  elog(FATAL, "DefineSavepoint: unexpected state %s",
4409  break;
4410  }
4411 }

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

4314 {
4316 
4317  /*
4318  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4319  * allowing CommitTransactionCommand to commit whatever happened during
4320  * the implicit transaction block as though it were a single statement.
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  */
4328 }

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

Referenced by exec_simple_query().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 4006 of file xact.c.

4007 {
4009  bool result = false;
4010 
4011  switch (s->blockState)
4012  {
4013  /*
4014  * We are in a transaction block, so tell CommitTransactionCommand
4015  * to COMMIT.
4016  */
4017  case TBLOCK_INPROGRESS:
4018  s->blockState = TBLOCK_END;
4019  result = true;
4020  break;
4021 
4022  /*
4023  * We are in an implicit transaction block. If AND CHAIN was
4024  * specified, error. Otherwise commit, but issue a warning
4025  * because there was no explicit BEGIN before this.
4026  */
4028  if (chain)
4029  ereport(ERROR,
4030  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4031  /* translator: %s represents an SQL statement name */
4032  errmsg("%s can only be used in transaction blocks",
4033  "COMMIT AND CHAIN")));
4034  else
4035  ereport(WARNING,
4036  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4037  errmsg("there is no transaction in progress")));
4038  s->blockState = TBLOCK_END;
4039  result = true;
4040  break;
4041 
4042  /*
4043  * We are in a failed transaction block. Tell
4044  * CommitTransactionCommand it's time to exit the block.
4045  */
4046  case TBLOCK_ABORT:
4048  break;
4049 
4050  /*
4051  * We are in a live subtransaction block. Set up to subcommit all
4052  * open subtransactions and then commit the main transaction.
4053  */
4054  case TBLOCK_SUBINPROGRESS:
4055  while (s->parent != NULL)
4056  {
4057  if (s->blockState == TBLOCK_SUBINPROGRESS)
4059  else
4060  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4062  s = s->parent;
4063  }
4064  if (s->blockState == TBLOCK_INPROGRESS)
4065  s->blockState = TBLOCK_END;
4066  else
4067  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4069  result = true;
4070  break;
4071 
4072  /*
4073  * Here we are inside an aborted subtransaction. Treat the COMMIT
4074  * as ROLLBACK: set up to abort everything and exit the main
4075  * transaction.
4076  */
4077  case TBLOCK_SUBABORT:
4078  while (s->parent != NULL)
4079  {
4080  if (s->blockState == TBLOCK_SUBINPROGRESS)
4082  else if (s->blockState == TBLOCK_SUBABORT)
4084  else
4085  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4087  s = s->parent;
4088  }
4089  if (s->blockState == TBLOCK_INPROGRESS)
4091  else if (s->blockState == TBLOCK_ABORT)
4093  else
4094  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4096  break;
4097 
4098  /*
4099  * The user issued COMMIT when not inside a transaction. For
4100  * COMMIT without CHAIN, issue a WARNING, staying in
4101  * TBLOCK_STARTED state. The upcoming call to
4102  * CommitTransactionCommand() will then close the transaction and
4103  * put us back into the default state. For COMMIT AND CHAIN,
4104  * error.
4105  */
4106  case TBLOCK_STARTED:
4107  if (chain)
4108  ereport(ERROR,
4109  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4110  /* translator: %s represents an SQL statement name */
4111  errmsg("%s can only be used in transaction blocks",
4112  "COMMIT AND CHAIN")));
4113  else
4114  ereport(WARNING,
4115  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4116  errmsg("there is no transaction in progress")));
4117  result = true;
4118  break;
4119 
4120  /*
4121  * The user issued a COMMIT that somehow ran inside a parallel
4122  * worker. We can't cope with that.
4123  */
4125  ereport(FATAL,
4126  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4127  errmsg("cannot commit during a parallel operation")));
4128  break;
4129 
4130  /* These cases are invalid. */
4131  case TBLOCK_DEFAULT:
4132  case TBLOCK_BEGIN:
4133  case TBLOCK_SUBBEGIN:
4134  case TBLOCK_END:
4135  case TBLOCK_SUBRELEASE:
4136  case TBLOCK_SUBCOMMIT:
4137  case TBLOCK_ABORT_END:
4138  case TBLOCK_SUBABORT_END:
4139  case TBLOCK_ABORT_PENDING:
4141  case TBLOCK_SUBRESTART:
4143  case TBLOCK_PREPARE:
4144  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4146  break;
4147  }
4148 
4150  s->blockState == TBLOCK_END ||
4151  s->blockState == TBLOCK_ABORT_END ||
4153 
4154  s->chain = chain;
4155 
4156  return result;
4157 }

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

5477 {
5478  TransactionState s;
5479  Size nxids = 0;
5481 
5482  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5483  {
5485  nxids = add_size(nxids, 1);
5486  nxids = add_size(nxids, s->nChildXids);
5487  }
5488 
5489  return add_size(size, mul_size(sizeof(TransactionId), nxids));
5490 }
size_t Size
Definition: c.h:592
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:236

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

1150 {
1151  forceSyncCommit = true;
1152 }
static bool forceSyncCommit
Definition: xact.c:290

References forceSyncCommit.

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 826 of file xact.c.

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

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(), 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 527 of file xact.c.

528 {
530 }

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 876 of file xact.c.

877 {
878  return stmtStartTimestamp;
879 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:278

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

868 {
869  return xactStartTimestamp;
870 }
static TimestampTz xactStartTimestamp
Definition: xact.c:277

References xactStartTimestamp.

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

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 888 of file xact.c.

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

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

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

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

497 {
499 }

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3728 of file xact.c.

3729 {
3730  /*
3731  * Return true on same conditions that would make
3732  * PreventInTransactionBlock error out
3733  */
3734  if (IsTransactionBlock())
3735  return true;
3736 
3737  if (IsSubTransaction())
3738  return true;
3739 
3741  return true;
3742 
3743  if (!isTopLevel)
3744  return true;
3745 
3748  return true;
3749 
3750  return false;
3751 }
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 556 of file xact.c.

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

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

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 384 of file xact.c.

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

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(), 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 588 of file xact.c.

589 {
591 
593 }
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:556

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

Referenced by XLogInsertRecord().

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5442 of file xact.c.

5443 {
5445 
5446  if (s->state != TRANS_DEFAULT)
5447  elog(WARNING, "PopTransaction while in %s state",
5449 
5450  if (s->parent == NULL)
5451  elog(FATAL, "PopTransaction with no parent");
5452 
5454 
5455  /* Let's just make sure CurTransactionContext is good */
5458 
5459  /* Ditto for ResourceOwner links */
5462 
5463  /* Free the old child structure */
5464  if (s->name)
5465  pfree(s->name);
5466  pfree(s);
5467 }

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

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

3955 {
3956  TransactionState s;
3957  bool result;
3958 
3959  /* Set up to commit the current transaction */
3960  result = EndTransactionBlock(false);
3961 
3962  /* If successful, change outer tblock state to PREPARE */
3963  if (result)
3964  {
3966 
3967  while (s->parent != NULL)
3968  s = s->parent;
3969 
3970  if (s->blockState == TBLOCK_END)
3971  {
3972  /* Save GID where PrepareTransaction can find it again */
3974 
3976  }
3977  else
3978  {
3979  /*
3980  * ignore case where we are not in a transaction;
3981  * EndTransactionBlock already issued a warning.
3982  */
3985  /* Don't send back a PREPARE result tag... */
3986  result = false;
3987  }
3988  }
3989 
3990  return result;
3991 }
bool EndTransactionBlock(bool chain)
Definition: xact.c:4006

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

3598 {
3599  /*
3600  * xact block already started?
3601  */
3602  if (IsTransactionBlock())
3603  ereport(ERROR,
3604  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3605  /* translator: %s represents an SQL statement name */
3606  errmsg("%s cannot run inside a transaction block",
3607  stmtType)));
3608 
3609  /*
3610  * subtransaction?
3611  */
3612  if (IsSubTransaction())
3613  ereport(ERROR,
3614  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3615  /* translator: %s represents an SQL statement name */
3616  errmsg("%s cannot run inside a subtransaction",
3617  stmtType)));
3618 
3619  /*
3620  * inside a pipeline that has started an implicit transaction?
3621  */
3623  ereport(ERROR,
3624  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3625  /* translator: %s represents an SQL statement name */
3626  errmsg("%s cannot be executed within a pipeline",
3627  stmtType)));
3628 
3629  /*
3630  * inside a function call?
3631  */
3632  if (!isTopLevel)
3633  ereport(ERROR,
3634  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3635  /* translator: %s represents an SQL statement name */
3636  errmsg("%s cannot be executed from a function", stmtType)));
3637 
3638  /* If we got past IsTransactionBlock test, should be in default state */
3641  elog(FATAL, "cannot prevent transaction chain");
3642 
3643  /* All okay. Set the flag to make sure the right thing happens later. */
3645 }
#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(), cluster(), CreateSubscription(), DiscardAll(), DropSubscription(), exec_replication_command(), ExecDropStmt(), ExecReindex(), ProcessUtilitySlow(), ReindexPartitions(), standard_ProcessUtility(), and vacuum().

◆ PushTransaction()

static void PushTransaction ( void  )
static

Definition at line 5380 of file xact.c.

5381 {
5383  TransactionState s;
5384 
5385  /*
5386  * We keep subtransaction state nodes in TopTransactionContext.
5387  */
5388  s = (TransactionState)
5390  sizeof(TransactionStateData));
5391 
5392  /*
5393  * Assign a subtransaction ID, watching out for counter wraparound.
5394  */
5397  {
5399  pfree(s);
5400  ereport(ERROR,
5401  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5402  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5403  }
5404 
5405  /*
5406  * We can now stack a minimally valid subtransaction without fear of
5407  * failure.
5408  */
5409  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5411  s->parent = p;
5412  s->nestingLevel = p->nestingLevel + 1;
5415  s->state = TRANS_DEFAULT;
5420  s->parallelModeLevel = 0;
5422  s->topXidLogged = false;
5423 
5425 
5426  /*
5427  * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5428  * with the subtransaction from here on out; in particular they should not
5429  * assume that it necessarily has a transaction context, resource owner,
5430  * or XID.
5431  */
5432 }
int NewGUCNestLevel(void)
Definition: guc.c:2237
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1202
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:635
bool startedInRecovery
Definition: xact.c:209
TransactionStateData * TransactionState
Definition: xact.c:218
static SubTransactionId currentSubTransactionId
Definition: xact.c:263

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

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

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

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

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

3827 {
3828  SubXactCallbackItem *item;
3829 
3830  item = (SubXactCallbackItem *)
3832  item->callback = callback;
3833  item->arg = arg;
3834  item->next = SubXact_callbacks;
3835  SubXact_callbacks = item;
3836 }
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 3766 of file xact.c.

3767 {
3768  XactCallbackItem *item;
3769 
3770  item = (XactCallbackItem *)
3772  item->callback = callback;
3773  item->arg = arg;
3774  item->next = Xact_callbacks;
3775  Xact_callbacks = item;
3776 }

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

4731 {
4733 
4734  /*
4735  * We do not check for parallel mode here. It's permissible to start and
4736  * end "internal" subtransactions while in parallel mode, so long as no
4737  * new XIDs or command IDs are assigned.
4738  */
4739 
4740  if (s->blockState != TBLOCK_SUBINPROGRESS)
4741  elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4743  Assert(s->state == TRANS_INPROGRESS);
4746  s = CurrentTransactionState; /* changed by pop */
4747  Assert(s->state == TRANS_INPROGRESS);
4748 }

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

4421 {
4423  TransactionState target,
4424  xact;
4425 
4426  /*
4427  * Workers synchronize transaction state at the beginning of each parallel
4428  * operation, so we can't account for transaction state change after that
4429  * point. (Note that this check will certainly error out if s->blockState
4430  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4431  * below.)
4432  */
4434  ereport(ERROR,
4435  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4436  errmsg("cannot release savepoints during a parallel operation")));
4437 
4438  switch (s->blockState)
4439  {
4440  /*
4441  * We can't release a savepoint if there is no savepoint defined.
4442  */
4443  case TBLOCK_INPROGRESS:
4444  ereport(ERROR,
4445  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4446  errmsg("savepoint \"%s\" does not exist", name)));
4447  break;
4448 
4450  /* See comment about implicit transactions in DefineSavepoint */
4451  ereport(ERROR,
4452  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4453  /* translator: %s represents an SQL statement name */
4454  errmsg("%s can only be used in transaction blocks",
4455  "RELEASE SAVEPOINT")));
4456  break;
4457 
4458  /*
4459  * We are in a non-aborted subtransaction. This is the only valid
4460  * case.
4461  */
4462  case TBLOCK_SUBINPROGRESS:
4463  break;
4464 
4465  /* These cases are invalid. */
4466  case TBLOCK_DEFAULT:
4467  case TBLOCK_STARTED:
4468  case TBLOCK_BEGIN:
4470  case TBLOCK_SUBBEGIN:
4471  case TBLOCK_END:
4472  case TBLOCK_SUBRELEASE:
4473  case TBLOCK_SUBCOMMIT:
4474  case TBLOCK_ABORT:
4475  case TBLOCK_SUBABORT:
4476  case TBLOCK_ABORT_END:
4477  case TBLOCK_SUBABORT_END:
4478  case TBLOCK_ABORT_PENDING:
4480  case TBLOCK_SUBRESTART:
4482  case TBLOCK_PREPARE:
4483  elog(FATAL, "ReleaseSavepoint: unexpected state %s",
4485  break;
4486  }
4487 
4488  for (target = s; PointerIsValid(target); target = target->parent)
4489  {
4490  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4491  break;
4492  }
4493 
4494  if (!PointerIsValid(target))
4495  ereport(ERROR,
4496  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4497  errmsg("savepoint \"%s\" does not exist", name)));
4498 
4499  /* disallow crossing savepoint level boundaries */
4500  if (target->savepointLevel != s->savepointLevel)
4501  ereport(ERROR,
4502  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4503  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4504 
4505  /*
4506  * Mark "commit pending" all subtransactions up to the target
4507  * subtransaction. The actual commits will happen when control gets to
4508  * CommitTransactionCommand.
4509  */
4510  xact = CurrentTransactionState;
4511  for (;;)
4512  {
4514  xact->blockState = TBLOCK_SUBRELEASE;
4515  if (xact == target)
4516  break;
4517  xact = xact->parent;
4518  Assert(PointerIsValid(xact));
4519  }
4520 }
#define PointerIsValid(pointer)
Definition: c.h:750

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

3676 {
3677  CheckTransactionBlock(isTopLevel, true, stmtType);
3678 }
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3684

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4758 of file xact.c.

4759 {
4761 
4762  /*
4763  * We do not check for parallel mode here. It's permissible to start and
4764  * end "internal" subtransactions while in parallel mode, so long as no
4765  * new XIDs or command IDs are assigned.
4766  */
4767 
4768  switch (s->blockState)
4769  {
4770  /* Must be in a subtransaction */
4771  case TBLOCK_SUBINPROGRESS:
4772  case TBLOCK_SUBABORT:
4773  break;
4774 
4775  /* These cases are invalid. */
4776  case TBLOCK_DEFAULT:
4777  case TBLOCK_STARTED:
4778  case TBLOCK_BEGIN:
4781  case TBLOCK_SUBBEGIN:
4782  case TBLOCK_INPROGRESS:
4783  case TBLOCK_END:
4784  case TBLOCK_SUBRELEASE:
4785  case TBLOCK_SUBCOMMIT:
4786  case TBLOCK_ABORT:
4787  case TBLOCK_ABORT_END:
4788  case TBLOCK_SUBABORT_END:
4789  case TBLOCK_ABORT_PENDING:
4791  case TBLOCK_SUBRESTART:
4793  case TBLOCK_PREPARE:
4794  elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4796  break;
4797  }
4798 
4799  /*
4800  * Abort the current subtransaction, if needed.
4801  */
4802  if (s->blockState == TBLOCK_SUBINPROGRESS)
4804 
4805  /* And clean it up, too */
4807 
4808  s = CurrentTransactionState; /* changed by pop */
4810  s->blockState == TBLOCK_INPROGRESS ||
4813  s->blockState == TBLOCK_STARTED);
4814 }

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

4530 {
4532  TransactionState target,
4533  xact;
4534 
4535  /*
4536  * Workers synchronize transaction state at the beginning of each parallel
4537  * operation, so we can't account for transaction state change after that
4538  * point. (Note that this check will certainly error out if s->blockState
4539  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4540  * below.)
4541  */
4543  ereport(ERROR,
4544  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4545  errmsg("cannot rollback to savepoints during a parallel operation")));
4546 
4547  switch (s->blockState)
4548  {
4549  /*
4550  * We can't rollback to a savepoint if there is no savepoint
4551  * defined.
4552  */
4553  case TBLOCK_INPROGRESS:
4554  case TBLOCK_ABORT:
4555  ereport(ERROR,
4556  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4557  errmsg("savepoint \"%s\" does not exist", name)));
4558  break;
4559 
4561  /* See comment about implicit transactions in DefineSavepoint */
4562  ereport(ERROR,
4563  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4564  /* translator: %s represents an SQL statement name */
4565  errmsg("%s can only be used in transaction blocks",
4566  "ROLLBACK TO SAVEPOINT")));
4567  break;
4568 
4569  /*
4570  * There is at least one savepoint, so proceed.
4571  */
4572  case TBLOCK_SUBINPROGRESS:
4573  case TBLOCK_SUBABORT:
4574  break;
4575 
4576  /* These cases are invalid. */
4577  case TBLOCK_DEFAULT:
4578  case TBLOCK_STARTED:
4579  case TBLOCK_BEGIN:
4581  case TBLOCK_SUBBEGIN:
4582  case TBLOCK_END:
4583  case TBLOCK_SUBRELEASE:
4584  case TBLOCK_SUBCOMMIT:
4585  case TBLOCK_ABORT_END:
4586  case TBLOCK_SUBABORT_END:
4587  case TBLOCK_ABORT_PENDING:
4589  case TBLOCK_SUBRESTART:
4591  case TBLOCK_PREPARE:
4592  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4594  break;
4595  }
4596 
4597  for (target = s; PointerIsValid(target); target = target->parent)
4598  {
4599  if (PointerIsValid(target->name) && strcmp(target->name, name) == 0)
4600  break;
4601  }
4602 
4603  if (!PointerIsValid(target))
4604  ereport(ERROR,
4605  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4606  errmsg("savepoint \"%s\" does not exist", name)));
4607 
4608  /* disallow crossing savepoint level boundaries */
4609  if (target->savepointLevel != s->savepointLevel)
4610  ereport(ERROR,
4611  (errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
4612  errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
4613 
4614  /*
4615  * Mark "abort pending" all subtransactions up to the target
4616  * subtransaction. The actual aborts will happen when control gets to
4617  * CommitTransactionCommand.
4618  */
4619  xact = CurrentTransactionState;
4620  for (;;)
4621  {
4622  if (xact == target)
4623  break;
4624  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4626  else if (xact->blockState == TBLOCK_SUBABORT)
4628  else
4629  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4631  xact = xact->parent;
4632  Assert(PointerIsValid(xact));
4633  }
4634 
4635  /* And mark the target as "restart pending" */
4636  if (xact->blockState == TBLOCK_SUBINPROGRESS)
4637  xact->blockState = TBLOCK_SUBRESTART;
4638  else if (xact->blockState == TBLOCK_SUBABORT)
4640  else
4641  elog(FATAL, "RollbackToSavepoint: unexpected state %s",
4643 }

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

5505 {
5506  TransactionState s;
5507  Size nxids = 0;
5508  Size i = 0;
5509  TransactionId *workspace;
5511 
5512  result = (SerializedTransactionState *) start_address;
5513 
5514  result->xactIsoLevel = XactIsoLevel;
5515  result->xactDeferrable = XactDeferrable;
5517  result->currentFullTransactionId =
5520 
5521  /*
5522  * If we're running in a parallel worker and launching a parallel worker
5523  * of our own, we can just pass along the information that was passed to
5524  * us.
5525  */
5526  if (nParallelCurrentXids > 0)
5527  {
5529  memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5531  return;
5532  }
5533 
5534  /*
5535  * OK, we need to generate a sorted list of XIDs that our workers should
5536  * view as current. First, figure out how many there are.
5537  */
5538  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5539  {
5541  nxids = add_size(nxids, 1);
5542  nxids = add_size(nxids, s->nChildXids);
5543  }
5545  <= maxsize);
5546 
5547  /* Copy them to our scratch space. */
5548  workspace = palloc(nxids * sizeof(TransactionId));
5549  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5550  {
5552  workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5553  if (s->nChildXids > 0)
5554  memcpy(&workspace[i], s->childXids,
5555  s->nChildXids * sizeof(TransactionId));
5556  i += s->nChildXids;
5557  }
5558  Assert(i == nxids);
5559 
5560  /* Sort them. */
5561  qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5562 
5563  /* Copy data into output area. */
5564  result->nParallelCurrentXids = nxids;
5565  memcpy(&result->parallelCurrentXids[0], workspace,
5566  nxids * sizeof(TransactionId));
5567 }
int i
Definition: isn.c:73
#define qsort(a, b, c, d)
Definition: port.h:449
FullTransactionId currentFullTransactionId
Definition: xact.c:229
FullTransactionId topFullTransactionId
Definition: xact.c:228
CommandId currentCommandId
Definition: xact.c:230
TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.c:232
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 856 of file xact.c.

857 {
859  xactStartTimestamp = xact_ts;
860  stmtStartTimestamp = stmt_ts;
861 }

References Assert(), IsParallelWorker, stmtStartTimestamp, and xactStartTimestamp.

Referenced by ParallelWorkerMain().

◆ ShowTransactionState()

static void ShowTransactionState ( const char *  str)
static

Definition at line 5612 of file xact.c.

5613 {
5614  /* skip work if message will definitely not be printed */
5617 }
bool message_level_is_interesting(int elevel)
Definition: elog.c:276
#define DEBUG5
Definition: elog.h:26
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition: xact.c:5624

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

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

◆ ShowTransactionStateRec()

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

Definition at line 5624 of file xact.c.

5625 {
5627 
5628  if (s->parent)
5629  {
5630  /*
5631  * Since this function recurses, it could be driven to stack overflow.
5632  * This is just a debugging aid, so we can leave out some details
5633  * instead of erroring out with check_stack_depth().
5634  */
5635  if (stack_is_too_deep())
5636  ereport(DEBUG5,
5637  (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5638  str, s->nestingLevel)));
5639  else
5641  }
5642 
5643  initStringInfo(&buf);
5644  if (s->nChildXids > 0)
5645  {
5646  int i;
5647 
5648  appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5649  for (i = 1; i < s->nChildXids; i++)
5650  appendStringInfo(&buf, " %u", s->childXids[i]);
5651  }
5652  ereport(DEBUG5,
5653  (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5654  str, s->nestingLevel,
5655  PointerIsValid(s->name) ? s->name : "unnamed",
5658  (unsigned int) XidFromFullTransactionId(s->fullTransactionId),
5659  (unsigned int) s->subTransactionId,
5660  (unsigned int) currentCommandId,
5661  currentCommandIdUsed ? " (used)" : "",
5662  buf.data)));
5663  pfree(buf.data);
5664 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1159
static char * buf
Definition: pg_test_fsync.c:73
bool stack_is_too_deep(void)
Definition: postgres.c:3545
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, generate_unaccent_rules::str, TransactionStateData::subTransactionId, TransStateAsString(), and XidFromFullTransactionId.

Referenced by ShowTransactionState().

◆ StartParallelWorkerTransaction()

void StartParallelWorkerTransaction ( char *  tstatespace)

◆ StartSubTransaction()

static void StartSubTransaction ( void  )
static

Definition at line 5024 of file xact.c.

5025 {
5027 
5028  if (s->state != TRANS_DEFAULT)
5029  elog(WARNING, "StartSubTransaction while in %s state",
5031 
5032  s->state = TRANS_START;
5033 
5034  /*
5035  * Initialize subsystems for new subtransaction
5036  *
5037  * must initialize resource-management stuff first
5038  */
5042 
5043  s->state = TRANS_INPROGRESS;
5044 
5045  /*
5046  * Call start-of-subxact callbacks
5047  */
5049  s->parent->subTransactionId);
5050 
5051  ShowTransactionState("StartSubTransaction");
5052 }
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5276
static void AtSubStart_ResourceOwner(void)
Definition: xact.c:1272
static void AtSubStart_Memory(void)
Definition: xact.c:1248
@ 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 2014 of file xact.c.

2015 {
2016  TransactionState s;
2017  VirtualTransactionId vxid;
2018 
2019  /*
2020  * Let's just make sure the state stack is empty
2021  */
2024 
2026 
2027  /* check the current transaction state */
2028  Assert(s->state == TRANS_DEFAULT);
2029 
2030  /*
2031  * Set the current transaction state information appropriately during
2032  * start processing. Note that once the transaction status is switched
2033  * this process cannot fail until the user ID and the security context
2034  * flags are fetched below.
2035  */
2036  s->state = TRANS_START;
2037  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2038 
2039  /* Determine if statements are logged in this transaction */
2041  (log_xact_sample_rate == 1 ||
2043 
2044  /*
2045  * initialize current transaction state fields
2046  *
2047  * note: prevXactReadOnly is not used at the outermost level
2048  */
2049  s->nestingLevel = 1;
2050  s->gucNestLevel = 1;
2051  s->childXids = NULL;
2052  s->nChildXids = 0;
2053  s->maxChildXids = 0;
2054 
2055  /*
2056  * Once the current user ID and the security context flags are fetched,
2057  * both will be properly reset even if transaction startup fails.
2058  */
2060 
2061  /* SecurityRestrictionContext should never be set outside a transaction */
2062  Assert(s->prevSecContext == 0);
2063 
2064  /*
2065  * Make sure we've reset xact state variables
2066  *
2067  * If recovery is still in progress, mark this transaction as read-only.
2068  * We have lower level defences in XLogInsert and elsewhere to stop us
2069  * from modifying data during recovery, but this gives the normal
2070  * indication to the user that the transaction is read-only.
2071  */
2072  if (RecoveryInProgress())
2073  {
2074  s->startedInRecovery = true;
2075  XactReadOnly = true;
2076  }
2077  else
2078  {
2079  s->startedInRecovery = false;
2081  }
2084  forceSyncCommit = false;
2085  MyXactFlags = 0;
2086 
2087  /*
2088  * reinitialize within-transaction counters
2089  */
2093  currentCommandIdUsed = false;
2094 
2095  /*
2096  * initialize reported xid accounting
2097  */
2098  nUnreportedXids = 0;
2099  s->didLogXid = false;
2100 
2101  /*
2102  * must initialize resource-management stuff first
2103  */
2104  AtStart_Memory();
2106 
2107  /*
2108  * Assign a new LocalTransactionId, and combine it with the proc number to
2109  * form a virtual transaction id.
2110  */
2111  vxid.procNumber = MyProcNumber;
2113 
2114  /*
2115  * Lock the virtual transaction id before we announce it in the proc array
2116  */
2118 
2119  /*
2120  * Advertise it in the proc array. We assume assignment of
2121  * localTransactionId is atomic, and the proc number should be set
2122  * already.
2123  */
2126 
2127  TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2128 
2129  /*
2130  * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2131  * be the same as the first command's statement_timestamp(), so don't do a
2132  * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2133  * for transactions started inside procedures (i.e., nonatomic SPI
2134  * contexts), we do need to advance the timestamp. Also, in a parallel
2135  * worker, the timestamp should already have been provided by a call to
2136  * SetParallelStartTimestamps().
2137  */
2138  if (!IsParallelWorker())
2139  {
2142  else
2144  }
2145  else
2146  Assert(xactStartTimestamp != 0);
2148  /* Mark xactStopTimestamp as unset. */
2149  xactStopTimestamp = 0;
2150 
2151  /*
2152  * initialize other subsystems for new transaction
2153  */
2154  AtStart_GUC();
2155  AtStart_Cache();
2157 
2158  /*
2159  * done with start processing, set current transaction state to "in
2160  * progress"
2161  */
2162  s->state = TRANS_INPROGRESS;
2163 
2164  /* Schedule transaction timeout */
2165  if (TransactionTimeout > 0)
2167 
2168  ShowTransactionState("StartTransaction");
2169 }
#define TopSubTransactionId
Definition: c.h:646
#define FirstCommandId
Definition: c.h:655
ProcNumber MyProcNumber
Definition: globals.c:87
void AtStart_GUC(void)
Definition: guc.c:2217
double log_xact_sample_rate
Definition: guc_tables.c:530
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4405
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:191
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:4961
static void AtStart_Memory(void)
Definition: xact.c:1173
bool DefaultXactDeferrable
Definition: xact.c:82
static void AtStart_ResourceOwner(void)
Definition: xact.c:1220
static void AtStart_Cache(void)
Definition: xact.c:1164
int DefaultXactIsoLevel
Definition: xact.c:76
bool xact_is_sampled
Definition: xact.c:293
bool DefaultXactReadOnly
Definition: xact.c:79
bool RecoveryInProgress(void)
Definition: xlog.c:6201

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 CommitTransactionCommandInternal(), restore_toc_entry(), RestoreArchive(), StartParallelWorkerTransaction(), StartRestoreLOs(), and StartTransactionCommand().

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

Definition at line 2995 of file xact.c.

2996 {
2998 
2999  switch (s->blockState)
3000  {
3001  /*
3002  * if we aren't in a transaction block, we just do our usual start
3003  * transaction.
3004  */
3005  case TBLOCK_DEFAULT:
3006  StartTransaction();
3008  break;
3009 
3010  /*
3011  * We are somewhere in a transaction block or subtransaction and
3012  * about to start a new command. For now we do nothing, but
3013  * someday we may do command-local resource initialization. (Note
3014  * that any needed CommandCounterIncrement was done by the
3015  * previous CommitTransactionCommand.)
3016  */
3017  case TBLOCK_INPROGRESS:
3019  case TBLOCK_SUBINPROGRESS:
3020  break;
3021 
3022  /*
3023  * Here we are in a failed transaction block (one of the commands
3024  * caused an abort) so we do nothing but remain in the abort
3025  * state. Eventually we will get a ROLLBACK command which will
3026  * get us out of this state. (It is up to other code to ensure
3027  * that no commands other than ROLLBACK will be processed in these
3028  * states.)
3029  */
3030  case TBLOCK_ABORT:
3031  case TBLOCK_SUBABORT:
3032  break;
3033 
3034  /* These cases are invalid. */
3035  case TBLOCK_STARTED:
3036  case TBLOCK_BEGIN:
3038  case TBLOCK_SUBBEGIN:
3039  case TBLOCK_END:
3040  case TBLOCK_SUBRELEASE:
3041  case TBLOCK_SUBCOMMIT:
3042  case TBLOCK_ABORT_END:
3043  case TBLOCK_SUBABORT_END:
3044  case TBLOCK_ABORT_PENDING:
3046  case TBLOCK_SUBRESTART:
3048  case TBLOCK_PREPARE:
3049  elog(ERROR, "StartTransactionCommand: unexpected state %s",
3051  break;
3052  }
3053 
3054  /*
3055  * We must switch to CurTransactionContext before returning. This is
3056  * already done if we called StartTransaction, otherwise not.
3057  */
3058  Assert(CurTransactionContext != NULL);
3060 }

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

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

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

Referenced by fmgr_sql().

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 4960 of file xact.c.

4961 {
4963 
4964  switch (s->blockState)
4965  {
4966  case TBLOCK_DEFAULT:
4967  case TBLOCK_STARTED:
4968  return 'I'; /* idle --- not in transaction */
4969  case TBLOCK_BEGIN:
4970  case TBLOCK_SUBBEGIN:
4971  case TBLOCK_INPROGRESS:
4974  case TBLOCK_SUBINPROGRESS:
4975  case TBLOCK_END:
4976  case TBLOCK_SUBRELEASE:
4977  case TBLOCK_SUBCOMMIT:
4978  case TBLOCK_PREPARE:
4979  return 'T'; /* in transaction */
4980  case TBLOCK_ABORT:
4981  case TBLOCK_SUBABORT:
4982  case TBLOCK_ABORT_END:
4983  case TBLOCK_SUBABORT_END:
4984  case TBLOCK_ABORT_PENDING:
4986  case TBLOCK_SUBRESTART:
4988  return 'E'; /* in failed transaction */
4989  }
4990 
4991  /* should never get here */
4992  elog(FATAL, "invalid transaction block state: %s",
4994  return 0; /* keep compiler quiet */
4995 }

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

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

1040 {
1042 }

References CurrentTransactionState, and TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

◆ TransStateAsString()

static const char * TransStateAsString ( TransState  state)
static

Definition at line 5724 of file xact.c.

5725 {
5726  switch (state)
5727  {
5728  case TRANS_DEFAULT:
5729  return "DEFAULT";
5730  case TRANS_START:
5731  return "START";
5732  case TRANS_INPROGRESS:
5733  return "INPROGRESS";
5734  case TRANS_COMMIT:
5735  return "COMMIT";
5736  case TRANS_ABORT:
5737  return "ABORT";
5738  case TRANS_PREPARE:
5739  return "PREPARE";
5740  }
5741  return "UNRECOGNIZED";
5742 }
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 3839 of file xact.c.

3840 {
3841  SubXactCallbackItem *item;
3842  SubXactCallbackItem *prev;
3843 
3844  prev = NULL;
3845  for (item = SubXact_callbacks; item; prev = item, item = item->next)
3846  {
3847  if (item->callback == callback && item->arg == arg)
3848  {
3849  if (prev)
3850  prev->next = item->next;
3851  else
3852  SubXact_callbacks = item->next;
3853  pfree(item);
3854  break;
3855  }
3856  }
3857 }

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

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3779 of file xact.c.

3780 {
3781  XactCallbackItem *item;
3782  XactCallbackItem *prev;
3783 
3784  prev = NULL;
3785  for (item = Xact_callbacks; item; prev = item, item = item->next)
3786  {
3787  if (item->callback == callback && item->arg == arg)
3788  {
3789  if (prev)
3790  prev->next = item->next;
3791  else
3792  Xact_callbacks = item->next;
3793  pfree(item);
3794  break;
3795  }
3796  }
3797 }

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

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4166 of file xact.c.

4167 {
4169 
4170  switch (s->blockState)
4171  {
4172  /*
4173  * We are inside a transaction block and we got a ROLLBACK command
4174  * from the user, so tell CommitTransactionCommand to abort and
4175  * exit the transaction block.
4176  */
4177  case TBLOCK_INPROGRESS:
4179  break;
4180 
4181  /*
4182  * We are inside a failed transaction block and we got a ROLLBACK
4183  * command from the user. Abort processing is already done, so
4184  * CommitTransactionCommand just has to cleanup and go back to
4185  * idle state.
4186  */
4187  case TBLOCK_ABORT:
4189  break;
4190 
4191  /*
4192  * We are inside a subtransaction. Mark everything up to top
4193  * level as exitable.
4194  */
4195  case TBLOCK_SUBINPROGRESS:
4196  case TBLOCK_SUBABORT:
4197  while (s->parent != NULL)
4198  {
4199  if (s->blockState == TBLOCK_SUBINPROGRESS)
4201  else if (s->blockState == TBLOCK_SUBABORT)
4203  else
4204  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4206  s = s->parent;
4207  }
4208  if (s->blockState == TBLOCK_INPROGRESS)
4210  else if (s->blockState == TBLOCK_ABORT)
4212  else
4213  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4215  break;
4216 
4217  /*
4218  * The user issued ABORT when not inside a transaction. For
4219  * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4220  * The upcoming call to CommitTransactionCommand() will then put
4221  * us back into the default state. For ROLLBACK AND CHAIN, error.
4222  *
4223  * We do the same thing with ABORT inside an implicit transaction,
4224  * although in this case we might be rolling back actual database
4225  * state changes. (It's debatable whether we should issue a
4226  * WARNING in this case, but we have done so historically.)
4227  */
4228  case TBLOCK_STARTED:
4230  if (chain)
4231  ereport(ERROR,
4232  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4233  /* translator: %s represents an SQL statement name */
4234  errmsg("%s can only be used in transaction blocks",
4235  "ROLLBACK AND CHAIN")));
4236  else
4237  ereport(WARNING,
4238  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4239  errmsg("there is no transaction in progress")));
4241  break;
4242 
4243  /*
4244  * The user issued an ABORT that somehow ran inside a parallel
4245  * worker. We can't cope with that.
4246  */
4248  ereport(FATAL,
4249  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4250  errmsg("cannot abort during a parallel operation")));
4251  break;
4252 
4253  /* These cases are invalid. */
4254  case TBLOCK_DEFAULT:
4255  case TBLOCK_BEGIN:
4256  case TBLOCK_SUBBEGIN:
4257  case TBLOCK_END:
4258  case TBLOCK_SUBRELEASE:
4259  case TBLOCK_SUBCOMMIT:
4260  case TBLOCK_ABORT_END:
4261  case TBLOCK_SUBABORT_END:
4262  case TBLOCK_ABORT_PENDING:
4264  case TBLOCK_SUBRESTART:
4266  case TBLOCK_PREPARE:
4267  elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4269  break;
4270  }
4271 
4274 
4275  s->chain = chain;
4276 }

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

3670 {
3671  CheckTransactionBlock(isTopLevel, false, stmtType);
3672 }

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6327 of file xact.c.

6328 {
6329  uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6330 
6331  /* Backup blocks are not used in xact records */
6332  Assert(!XLogRecHasAnyBlockRefs(record));
6333 
6334  if (info == XLOG_XACT_COMMIT)
6335  {
6336  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6337  xl_xact_parsed_commit parsed;
6338 
6339  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6340  xact_redo_commit(&parsed, XLogRecGetXid(record),
6341  record->EndRecPtr, XLogRecGetOrigin(record));
6342  }
6343  else if (info == XLOG_XACT_COMMIT_PREPARED)
6344  {
6345  xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6346  xl_xact_parsed_commit parsed;
6347 
6348  ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6349  xact_redo_commit(&parsed, parsed.twophase_xid,
6350  record->EndRecPtr, XLogRecGetOrigin(record));
6351 
6352  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6353  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6354  PrepareRedoRemove(parsed.twophase_xid, false);
6355  LWLockRelease(TwoPhaseStateLock);
6356  }
6357  else if (info == XLOG_XACT_ABORT)
6358  {
6359  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6360  xl_xact_parsed_abort parsed;
6361 
6362  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6363  xact_redo_abort(&parsed, XLogRecGetXid(record),
6364  record->EndRecPtr, XLogRecGetOrigin(record));
6365  }
6366  else if (info == XLOG_XACT_ABORT_PREPARED)
6367  {
6368  xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6369  xl_xact_parsed_abort parsed;
6370 
6371  ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6372  xact_redo_abort(&parsed, parsed.twophase_xid,
6373  record->EndRecPtr, XLogRecGetOrigin(record));
6374 
6375  /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6376  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6377  PrepareRedoRemove(parsed.twophase_xid, false);
6378  LWLockRelease(TwoPhaseStateLock);
6379  }
6380  else if (info == XLOG_XACT_PREPARE)
6381  {
6382  /*
6383  * Store xid and start/end pointers of the WAL record in TwoPhaseState
6384  * gxact entry.
6385  */
6386  LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6388  record->ReadRecPtr,
6389  record->EndRecPtr,
6390  XLogRecGetOrigin(record));
6391  LWLockRelease(TwoPhaseStateLock);
6392  }
6393  else if (info == XLOG_XACT_ASSIGNMENT)
6394  {
6396 
6399  xlrec->nsubxacts, xlrec->xsub);
6400  }
6401  else if (info == XLOG_XACT_INVALIDATIONS)
6402  {
6403  /*
6404  * XXX we do ignore this for now, what matters are invalidations
6405  * written into the commit record.
6406  */
6407  }
6408  else
6409  elog(PANIC, "xact_redo: unknown op code %u", info);
6410 }
unsigned char uint8
Definition: c.h:491
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1169
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1782
@ LW_EXCLUSIVE
Definition: lwlock.h:114
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:1306
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:2582
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2480
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6094
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6248
#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:50

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

6250 {
6251  TransactionId max_xid;
6252 
6254 
6255  /* Make sure nextXid is beyond any XID mentioned in the record. */
6256  max_xid = TransactionIdLatest(xid,
6257  parsed->nsubxacts,
6258  parsed->subxacts);
6260 
6262  {
6263  /* Mark the transaction aborted in pg_xact, no need for async stuff */
6264  TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6265  }
6266  else
6267  {
6268  /*
6269  * If a transaction completion record arrives that has as-yet
6270  * unobserved subtransactions then this will not have been fully
6271  * handled by the call to RecordKnownAssignedTransactionIds() in the
6272  * main recovery loop in xlog.c. So we need to do bookkeeping again to
6273  * cover that case. This is confusing and it is easy to think this
6274  * call is irrelevant, which has happened three times in development
6275  * already. Leave it in.
6276  */
6278 
6279  /* Mark the transaction aborted in pg_xact, no need for async stuff */
6280  TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6281 
6282  /*
6283  * We must update the ProcArray after we have marked clog.
6284  */
6285  ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6286 
6287  /*
6288  * There are no invalidation messages to send or undo.
6289  */
6290 
6291  /*
6292  * Release locks, if any. There are no invalidations to send.
6293  */
6294  if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6295  StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6296  }
6297 
6298  if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6299  {
6300  /* recover apply progress */
6301  replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6302  false /* backward */ , false /* WAL */ );
6303  }
6304 
6305  /* Make sure files supposed to be dropped are dropped */
6306  if (parsed->nrels > 0)
6307  {
6308  /*
6309  * See comments about update of minimum recovery point on truncation,
6310  * in xact_redo_commit().
6311  */
6312  XLogFlush(lsn);
6313 
6314  DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6315  }
6316 
6317  if (parsed->nstats > 0)
6318  {
6319  /* see equivalent call for relations above */
6320  XLogFlush(lsn);
6321 
6322  pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6323  }
6324 }
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:4417
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition: procarray.c:4486
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:49

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

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

5755 {
5757 
5758  if (s->nChildXids == 0)
5759  *ptr = NULL;
5760  else
5761  *ptr = s->childXids;
5762 
5763  return s->nChildXids;
5764 }

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

5956 {
5957  xl_xact_abort xlrec;
5958  xl_xact_xinfo xl_xinfo;
5959  xl_xact_subxacts xl_subxacts;
5960  xl_xact_relfilelocators xl_relfilelocators;
5961  xl_xact_stats_items xl_dropped_stats;
5962  xl_xact_twophase xl_twophase;
5963  xl_xact_dbinfo xl_dbinfo;
5964  xl_xact_origin xl_origin;
5965 
5966  uint8 info;
5967 
5968  Assert(CritSectionCount > 0);
5969 
5970  xl_xinfo.xinfo = 0;
5971 
5972  /* decide between a plain and 2pc abort */
5973  if (!TransactionIdIsValid(twophase_xid))
5974  info = XLOG_XACT_ABORT;
5975  else
5976  info = XLOG_XACT_ABORT_PREPARED;
5977 
5978 
5979  /* First figure out and collect all the information needed */
5980 
5981  xlrec.xact_time = abort_time;
5982 
5983  if ((xactflags & XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK))
5984  xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5985 
5986  if (nsubxacts > 0)
5987  {
5988  xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5989  xl_subxacts.nsubxacts = nsubxacts;
5990  }
5991 
5992  if (nrels > 0)
5993  {
5995  xl_relfilelocators.nrels = nrels;
5996  info |= XLR_SPECIAL_REL_UPDATE;
5997  }
5998 
5999  if (ndroppedstats > 0)
6000  {
6001  xl_xinfo.xinfo |= XACT_XINFO_HAS_DROPPED_STATS;
6002  xl_dropped_stats.nitems = ndroppedstats;
6003  }
6004 
6005  if (TransactionIdIsValid(twophase_xid))
6006  {
6007  xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
6008  xl_twophase.xid = twophase_xid;
6009  Assert(twophase_gid != NULL);
6010 
6011  if (XLogLogicalInfoActive())
6012  xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6013  }
6014 
6015  if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6016  {
6017  xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6018  xl_dbinfo.dbId = MyDatabaseId;
6019  xl_dbinfo.tsId = MyDatabaseTableSpace;
6020  }
6021 
6022  /*
6023  * Dump transaction origin information. We need this during recovery to
6024  * update the replication origin progress.
6025  */
6027  {
6028  xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6029 
6032  }
6033 
6034  if (xl_xinfo.xinfo != 0)
6035  info |= XLOG_XACT_HAS_INFO;
6036 
6037  /* Then include all the collected data into the abort record. */
6038 
6039  XLogBeginInsert();
6040 
6041  XLogRegisterData((char *) (&xlrec), MinSizeOfXactAbort);
6042 
6043  if (xl_xinfo.xinfo != 0)
6044  XLogRegisterData((char *) (&xl_xinfo), sizeof(xl_xinfo));
6045 
6046  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6047  XLogRegisterData((char *) (&xl_dbinfo), sizeof(xl_dbinfo));
6048 
6049  if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6050  {
6051  XLogRegisterData((char *) (&xl_subxacts),
6053  XLogRegisterData((char *) subxacts,
6054  nsubxacts * sizeof(TransactionId));
6055  }
6056 
6057  if (xl_xinfo.xinfo & XACT_XINFO_HAS_RELFILELOCATORS)
6058  {
6059  XLogRegisterData((char *) (&xl_relfilelocators),
6061  XLogRegisterData((char *) rels,
6062  nrels * sizeof(RelFileLocator));
6063  }
6064 
6065  if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6066  {
6067  XLogRegisterData((char *) (&xl_dropped_stats),
6069  XLogRegisterData((char *) droppedstats,
6070  ndroppedstats * sizeof(xl_xact_stats_item));
6071  }
6072 
6073  if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6074  {
6075  XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase));
6076  if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6077  XLogRegisterData(unconstify(char *, twophase_gid), strlen(twophase_gid) + 1);
6078  }
6079 
6080  if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6081  XLogRegisterData((char *) (&xl_origin), sizeof(xl_xact_origin));
6082 
6083  /* Include the replication origin */
6085 
6086  return XLogInsert(RM_XACT_ID, info);
6087 }
#define unconstify(underlying_type, expr)
Definition: c.h:1232
Oid MyDatabaseTableSpace
Definition: globals.c:93
volatile uint32 CritSectionCount
Definition: globals.c:43
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:152
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 5778 of file xact.c.

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

Referenced by PushTransaction(), and StartTransaction().

◆ CurrentTransactionState

TransactionState CurrentTransactionState = &TopTransactionStateData
static

Definition at line 257 of file xact.c.

Referenced by AbortCurrentTransaction(), 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(), CommitTransactionCommand(), 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 254 of file xact.c.

Referenced by AssignTransactionId(), and StartTransaction().

◆ ParallelCurrentXids

TransactionId* ParallelCurrentXids
static

◆ prepareGID

char* prepareGID
static

Definition at line 285 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 244 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 255 of file xact.c.

Referenced by AssignTransactionId().

◆ Xact_callbacks

XactCallbackItem* Xact_callbacks = NULL
static

Definition at line 312 of file xact.c.

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

◆ xact_is_sampled

bool xact_is_sampled = false

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

Referenced by GetCurrentTransactionStopTimestamp(), and StartTransaction().

◆ XactTopFullTransactionId