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/origin.h"
#include "replication/snapbuild.h"
#include "replication/syncrep.h"
#include "replication/walsender.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/catcache.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 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 232 of file xact.c.

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

typedef enum TBlockState TBlockState

◆ TransactionState

Definition at line 214 of file xact.c.

◆ TransactionStateData

◆ TransState

typedef enum TransState TransState

◆ XactCallbackItem

Enumeration Type Documentation

◆ TBlockState

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

Definition at line 156 of file xact.c.

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

◆ TransState

enum TransState
Enumerator
TRANS_DEFAULT 
TRANS_START 
TRANS_INPROGRESS 
TRANS_COMMIT 
TRANS_ABORT 
TRANS_PREPARE 

Definition at line 140 of file xact.c.

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

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3293 of file xact.c.

3294 {
3296 
3297  switch (s->blockState)
3298  {
3299  case TBLOCK_DEFAULT:
3300  if (s->state == TRANS_DEFAULT)
3301  {
3302  /* we are idle, so nothing to do */
3303  }
3304  else
3305  {
3306  /*
3307  * We can get here after an error during transaction start
3308  * (state will be TRANS_START). Need to clean up the
3309  * incompletely started transaction. First, adjust the
3310  * low-level state to suppress warning message from
3311  * AbortTransaction.
3312  */
3313  if (s->state == TRANS_START)
3314  s->state = TRANS_INPROGRESS;
3315  AbortTransaction();
3317  }
3318  break;
3319 
3320  /*
3321  * If we aren't in a transaction block, we just do the basic abort
3322  * & cleanup transaction. For this purpose, we treat an implicit
3323  * transaction block as if it were a simple statement.
3324  */
3325  case TBLOCK_STARTED:
3327  AbortTransaction();
3330  break;
3331 
3332  /*
3333  * If we are in TBLOCK_BEGIN it means something screwed up right
3334  * after reading "BEGIN TRANSACTION". We assume that the user
3335  * will interpret the error as meaning the BEGIN failed to get him
3336  * into a transaction block, so we should abort and return to idle
3337  * state.
3338  */
3339  case TBLOCK_BEGIN:
3340  AbortTransaction();
3343  break;
3344 
3345  /*
3346  * We are somewhere in a transaction block and we've gotten a
3347  * failure, so we abort the transaction and set up the persistent
3348  * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3349  */
3350  case TBLOCK_INPROGRESS:
3352  AbortTransaction();
3353  s->blockState = TBLOCK_ABORT;
3354  /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3355  break;
3356 
3357  /*
3358  * Here, we failed while trying to COMMIT. Clean up the
3359  * transaction and return to idle state (we do not want to stay in
3360  * the transaction).
3361  */
3362  case TBLOCK_END:
3363  AbortTransaction();
3366  break;
3367 
3368  /*
3369  * Here, we are already in an aborted transaction state and are
3370  * waiting for a ROLLBACK, but for some reason we failed again! So
3371  * we just remain in the abort state.
3372  */
3373  case TBLOCK_ABORT:
3374  case TBLOCK_SUBABORT:
3375  break;
3376 
3377  /*
3378  * We are in a failed transaction and we got the ROLLBACK command.
3379  * We have already aborted, we just need to cleanup and go to idle
3380  * state.
3381  */
3382  case TBLOCK_ABORT_END:
3385  break;
3386 
3387  /*
3388  * We are in a live transaction and we got a ROLLBACK command.
3389  * Abort, cleanup, go to idle state.
3390  */
3391  case TBLOCK_ABORT_PENDING:
3392  AbortTransaction();
3395  break;
3396 
3397  /*
3398  * Here, we failed while trying to PREPARE. Clean up the
3399  * transaction and return to idle state (we do not want to stay in
3400  * the transaction).
3401  */
3402  case TBLOCK_PREPARE:
3403  AbortTransaction();
3406  break;
3407 
3408  /*
3409  * We got an error inside a subtransaction. Abort just the
3410  * subtransaction, and go to the persistent SUBABORT state until
3411  * we get ROLLBACK.
3412  */
3413  case TBLOCK_SUBINPROGRESS:
3416  break;
3417 
3418  /*
3419  * If we failed while trying to create a subtransaction, clean up
3420  * the broken subtransaction and abort the parent. The same
3421  * applies if we get a failure while ending a subtransaction.
3422  */
3423  case TBLOCK_SUBBEGIN:
3424  case TBLOCK_SUBRELEASE:
3425  case TBLOCK_SUBCOMMIT:
3427  case TBLOCK_SUBRESTART:
3431  break;
3432 
3433  /*
3434  * Same as above, except the Abort() was already done.
3435  */
3436  case TBLOCK_SUBABORT_END:
3440  break;
3441  }
3442 }
TransState state
Definition: xact.c:194
TBlockState blockState
Definition: xact.c:195
static void CleanupSubTransaction(void)
Definition: xact.c:5197
static void CleanupTransaction(void)
Definition: xact.c:2876
static void AbortSubTransaction(void)
Definition: xact.c:5038
static void AbortTransaction(void)
Definition: xact.c:2685
static TransactionState CurrentTransactionState
Definition: xact.c:253
void AbortCurrentTransaction(void)
Definition: xact.c:3293

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

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

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4692 of file xact.c.

4693 {
4695 
4696  /* Ensure we're not running in a doomed memory context */
4697  AtAbort_Memory();
4698 
4699  /*
4700  * Get out of any transaction or nested transaction
4701  */
4702  do
4703  {
4704  switch (s->blockState)
4705  {
4706  case TBLOCK_DEFAULT:
4707  if (s->state == TRANS_DEFAULT)
4708  {
4709  /* Not in a transaction, do nothing */
4710  }
4711  else
4712  {
4713  /*
4714  * We can get here after an error during transaction start
4715  * (state will be TRANS_START). Need to clean up the
4716  * incompletely started transaction. First, adjust the
4717  * low-level state to suppress warning message from
4718  * AbortTransaction.
4719  */
4720  if (s->state == TRANS_START)
4721  s->state = TRANS_INPROGRESS;
4722  AbortTransaction();
4724  }
4725  break;
4726  case TBLOCK_STARTED:
4727  case TBLOCK_BEGIN:
4728  case TBLOCK_INPROGRESS:
4731  case TBLOCK_END:
4732  case TBLOCK_ABORT_PENDING:
4733  case TBLOCK_PREPARE:
4734  /* In a transaction, so clean up */
4735  AbortTransaction();
4738  break;
4739  case TBLOCK_ABORT:
4740  case TBLOCK_ABORT_END:
4741 
4742  /*
4743  * AbortTransaction is already done, still need Cleanup.
4744  * However, if we failed partway through running ROLLBACK,
4745  * there will be an active portal running that command, which
4746  * we need to shut down before doing CleanupTransaction.
4747  */
4748  AtAbort_Portals();
4751  break;
4752 
4753  /*
4754  * In a subtransaction, so clean it up and abort parent too
4755  */
4756  case TBLOCK_SUBBEGIN:
4757  case TBLOCK_SUBINPROGRESS:
4758  case TBLOCK_SUBRELEASE:
4759  case TBLOCK_SUBCOMMIT:
4761  case TBLOCK_SUBRESTART:
4764  s = CurrentTransactionState; /* changed by pop */
4765  break;
4766 
4767  case TBLOCK_SUBABORT:
4768  case TBLOCK_SUBABORT_END:
4770  /* As above, but AbortSubTransaction already done */
4771  if (s->curTransactionOwner)
4772  {
4773  /* As in TBLOCK_ABORT, might have a live portal to zap */
4778  }
4780  s = CurrentTransactionState; /* changed by pop */
4781  break;
4782  }
4783  } while (s->blockState != TBLOCK_DEFAULT);
4784 
4785  /* Should be out of all subxacts now */
4786  Assert(s->parent == NULL);
4787 
4788  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4789  AtCleanup_Memory();
4790 }
Assert(fmt[strlen(fmt) - 1] !='\n')
void AtAbort_Portals(void)
Definition: portalmem.c:782
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:980
SubTransactionId subTransactionId
Definition: xact.c:191
struct TransactionStateData * parent
Definition: xact.c:211
ResourceOwner curTransactionOwner
Definition: xact.c:199
static void AtCleanup_Memory(void)
Definition: xact.c:1911
static void AtAbort_Memory(void)
Definition: xact.c:1821

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

5039 {
5041 
5042  /* Prevent cancel/die interrupt while cleaning up */
5043  HOLD_INTERRUPTS();
5044 
5045  /* Make sure we have a valid memory context and resource owner */
5048 
5049  /*
5050  * Release any LW locks we might be holding as quickly as possible.
5051  * (Regular locks, however, must be held till we finish aborting.)
5052  * Releasing LW locks is critical since we might try to grab them again
5053  * while cleaning up!
5054  *
5055  * FIXME This may be incorrect --- Are there some locks we should keep?
5056  * Buffer locks, for example? I don't think so but I'm not sure.
5057  */
5058  LWLockReleaseAll();
5059 
5062  AbortBufferIO();
5063  UnlockBuffers();
5064 
5065  /* Reset WAL record construction state */
5067 
5068  /* Cancel condition variable sleep */
5070 
5071  /*
5072  * Also clean up any open wait for lock, since the lock manager will choke
5073  * if we try to wait for another lock before doing this.
5074  */
5075  LockErrorCleanup();
5076 
5077  /*
5078  * If any timeout events are still active, make sure the timeout interrupt
5079  * is scheduled. This covers possible loss of a timeout interrupt due to
5080  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5081  * We delay this till after LockErrorCleanup so that we don't uselessly
5082  * reschedule lock or deadlock check timeouts.
5083  */
5085 
5086  /*
5087  * Re-enable signals, in case we got here by longjmp'ing out of a signal
5088  * handler. We do this fairly early in the sequence so that the timeout
5089  * infrastructure will be functional if needed while aborting.
5090  */
5092 
5093  /*
5094  * check the current transaction state
5095  */
5096  ShowTransactionState("AbortSubTransaction");
5097 
5098  if (s->state != TRANS_INPROGRESS)
5099  elog(WARNING, "AbortSubTransaction while in %s state",
5101 
5102  s->state = TRANS_ABORT;
5103 
5104  /*
5105  * Reset user ID which might have been changed transiently. (See notes in
5106  * AbortTransaction.)
5107  */
5109 
5110  /* Forget about any active REINDEX. */
5112 
5113  /* Reset logical streaming state. */
5115 
5116  /*
5117  * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5118  * exports are not supported in subtransactions.
5119  */
5120 
5121  /* Exit from parallel mode, if necessary. */
5122  if (IsInParallelMode())
5123  {
5125  s->parallelModeLevel = 0;
5126  }
5127 
5128  /*
5129  * We can skip all this stuff if the subxact failed before creating a
5130  * ResourceOwner...
5131  */
5132  if (s->curTransactionOwner)
5133  {
5134  AfterTriggerEndSubXact(false);
5140  s->parent->subTransactionId);
5142 
5143  /* Advertise the fact that we aborted in pg_xact. */
5144  (void) RecordTransactionAbort(true);
5145 
5146  /* Post-abort cleanup */
5149 
5151  s->parent->subTransactionId);
5152 
5155  false, false);
5157  s->parent->subTransactionId);
5158  AtEOSubXact_Inval(false);
5161  false, false);
5164  false, false);
5165  AtSubAbort_smgr();
5166 
5167  AtEOXact_GUC(false, s->gucNestLevel);
5168  AtEOSubXact_SPI(false, s->subTransactionId);
5170  s->parent->subTransactionId);
5172  s->parent->subTransactionId);
5174  s->parent->subTransactionId);
5176  AtEOSubXact_PgStat(false, s->nestingLevel);
5178  }
5179 
5180  /*
5181  * Restore the upper transaction's read-only state, too. This should be
5182  * redundant with GUC's cleanup but we may as well do it for consistency
5183  * with the commit case.
5184  */
5186 
5188 }
void AtSubAbort_Notify(void)
Definition: async.c:1810
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition: parallel.c:1226
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:647
void UnlockBuffers(void)
Definition: bufmgr.c:4144
void AbortBufferIO(void)
Definition: bufmgr.c:4642
void ConditionVariableCancelSleep(void)
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1904
#define WARNING
Definition: elog.h:32
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:2932
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2197
void ResetReindexState(int nestLevel)
Definition: index.c:4108
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1085
void ResetLogicalStreamingState(void)
Definition: logical.c:1823
void LWLockReleaseAll(void)
Definition: lwlock.c:1901
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:134
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:132
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:625
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: namespace.c:4175
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:113
#define PG_SETMASK(mask)
Definition: pqsignal.h:18
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3328
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:486
@ RESOURCE_RELEASE_LOCKS
Definition: resowner.h:49
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:48
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:50
void AtSubAbort_Snapshot(int level)
Definition: snapmgr.c:989
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition: spi.c:483
void LockErrorCleanup(void)
Definition: proc.c:699
void AtSubAbort_smgr(void)
Definition: storage.c:952
int parallelModeLevel
Definition: xact.c:208
FullTransactionId fullTransactionId
Definition: xact.c:190
bool prevXactReadOnly
Definition: xact.c:205
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:16903
void reschedule_timeouts(void)
Definition: timeout.c:544
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5285
static void pgstat_report_wait_end(void)
Definition: wait_event.h:284
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3724
static void AtSubAbort_Memory(void)
Definition: xact.c:1841
static const char * TransStateAsString(TransState state)
Definition: xact.c:5563
bool XactReadOnly
Definition: xact.c:81
static void AtSubAbort_childXids(void)
Definition: xact.c:1879
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1866
static void ShowTransactionState(const char *str)
Definition: xact.c:5460
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1704
bool IsInParallelMode(void)
Definition: xact.c:1068
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:137
void XLogResetInsertion(void)
Definition: xloginsert.c:223

References AbortBufferIO(), AfterTriggerEndSubXact(), AtEOSubXact_Files(), AtEOSubXact_HashTables(), AtEOSubXact_Inval(), AtEOSubXact_LargeObject(), AtEOSubXact_Namespace(), AtEOSubXact_on_commit_actions(), AtEOSubXact_Parallel(), AtEOSubXact_PgStat(), AtEOSubXact_RelationCache(), AtEOSubXact_SPI(), AtEOXact_GUC(), AtSubAbort_childXids(), AtSubAbort_Memory(), AtSubAbort_Notify(), AtSubAbort_Portals(), AtSubAbort_ResourceOwner(), AtSubAbort_smgr(), AtSubAbort_Snapshot(), CallSubXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, TransactionStateData::curTransactionOwner, elog(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, IsInParallelMode(), LockErrorCleanup(), LWLockReleaseAll(), TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, PG_SETMASK, 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(), AbortOutOfAnyTransaction(), CommitTransactionCommand(), and RollbackAndReleaseCurrentSubTransaction().

◆ AbortTransaction()

static void AbortTransaction ( void  )
static

Definition at line 2685 of file xact.c.

2686 {
2688  TransactionId latestXid;
2689  bool is_parallel_worker;
2690 
2691  /* Prevent cancel/die interrupt while cleaning up */
2692  HOLD_INTERRUPTS();
2693 
2694  /* Make sure we have a valid memory context and resource owner */
2695  AtAbort_Memory();
2697 
2698  /*
2699  * Release any LW locks we might be holding as quickly as possible.
2700  * (Regular locks, however, must be held till we finish aborting.)
2701  * Releasing LW locks is critical since we might try to grab them again
2702  * while cleaning up!
2703  */
2704  LWLockReleaseAll();
2705 
2706  /* Clear wait information and command progress indicator */
2709 
2710  /* Clean up buffer I/O and buffer context locks, too */
2711  AbortBufferIO();
2712  UnlockBuffers();
2713 
2714  /* Reset WAL record construction state */
2716 
2717  /* Cancel condition variable sleep */
2719 
2720  /*
2721  * Also clean up any open wait for lock, since the lock manager will choke
2722  * if we try to wait for another lock before doing this.
2723  */
2724  LockErrorCleanup();
2725 
2726  /*
2727  * If any timeout events are still active, make sure the timeout interrupt
2728  * is scheduled. This covers possible loss of a timeout interrupt due to
2729  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2730  * We delay this till after LockErrorCleanup so that we don't uselessly
2731  * reschedule lock or deadlock check timeouts.
2732  */
2734 
2735  /*
2736  * Re-enable signals, in case we got here by longjmp'ing out of a signal
2737  * handler. We do this fairly early in the sequence so that the timeout
2738  * infrastructure will be functional if needed while aborting.
2739  */
2741 
2742  /*
2743  * check the current transaction state
2744  */
2745  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2746  if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2747  elog(WARNING, "AbortTransaction while in %s state",
2749  Assert(s->parent == NULL);
2750 
2751  /*
2752  * set the current transaction state information appropriately during the
2753  * abort processing
2754  */
2755  s->state = TRANS_ABORT;
2756 
2757  /*
2758  * Reset user ID which might have been changed transiently. We need this
2759  * to clean up in case control escaped out of a SECURITY DEFINER function
2760  * or other local change of CurrentUserId; therefore, the prior value of
2761  * SecurityRestrictionContext also needs to be restored.
2762  *
2763  * (Note: it is not necessary to restore session authorization or role
2764  * settings here because those can only be changed via GUC, and GUC will
2765  * take care of rolling them back if need be.)
2766  */
2768 
2769  /* Forget about any active REINDEX. */
2771 
2772  /* Reset logical streaming state. */
2774 
2775  /* Reset snapshot export state. */
2777 
2778  /* If in parallel mode, clean up workers and exit parallel mode. */
2779  if (IsInParallelMode())
2780  {
2781  AtEOXact_Parallel(false);
2782  s->parallelModeLevel = 0;
2783  }
2784 
2785  /*
2786  * do abort processing
2787  */
2788  AfterTriggerEndXact(false); /* 'false' means it's abort */
2789  AtAbort_Portals();
2790  smgrDoPendingSyncs(false, is_parallel_worker);
2791  AtEOXact_LargeObject(false);
2792  AtAbort_Notify();
2793  AtEOXact_RelationMap(false, is_parallel_worker);
2794  AtAbort_Twophase();
2795 
2796  /*
2797  * Advertise the fact that we aborted in pg_xact (assuming that we got as
2798  * far as assigning an XID to advertise). But if we're inside a parallel
2799  * worker, skip this; the user backend must be the one to write the abort
2800  * record.
2801  */
2802  if (!is_parallel_worker)
2803  latestXid = RecordTransactionAbort(false);
2804  else
2805  {
2806  latestXid = InvalidTransactionId;
2807 
2808  /*
2809  * Since the parallel leader won't get our value of XactLastRecEnd in
2810  * this case, we nudge WAL-writer ourselves in this case. See related
2811  * comments in RecordTransactionAbort for why this matters.
2812  */
2814  }
2815 
2816  TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2817 
2818  /*
2819  * Let others know about no transaction in progress by me. Note that this
2820  * must be done _before_ releasing locks we hold and _after_
2821  * RecordTransactionAbort.
2822  */
2823  ProcArrayEndTransaction(MyProc, latestXid);
2824 
2825  /*
2826  * Post-abort cleanup. See notes in CommitTransaction() concerning
2827  * ordering. We can skip all of it if the transaction failed before
2828  * creating a resource owner.
2829  */
2830  if (TopTransactionResourceOwner != NULL)
2831  {
2832  if (is_parallel_worker)
2834  else
2836 
2839  false, true);
2840  AtEOXact_Buffers(false);
2841  AtEOXact_RelationCache(false);
2842  AtEOXact_Inval(false);
2846  false, true);
2849  false, true);
2850  smgrDoPendingDeletes(false);
2851 
2852  AtEOXact_GUC(false, 1);
2853  AtEOXact_SPI(false);
2854  AtEOXact_Enum();
2856  AtEOXact_Namespace(false, is_parallel_worker);
2857  AtEOXact_SMgr();
2858  AtEOXact_Files(false);
2860  AtEOXact_HashTables(false);
2861  AtEOXact_PgStat(false, is_parallel_worker);
2862  AtEOXact_ApplyLauncher(false);
2864  }
2865 
2866  /*
2867  * State remains TRANS_ABORT until CleanupTransaction().
2868  */
2870 }
void AtAbort_Notify(void)
Definition: async.c:1720
void AtEOXact_Parallel(bool isCommit)
Definition: parallel.c:1245
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition: be-fsstubs.c:601
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:2594
uint32 TransactionId
Definition: c.h:588
void AtEOXact_ComboCid(void)
Definition: combocid.c:182
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1878
void AtEOXact_Files(bool isCommit)
Definition: fd.c:2965
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1028
void AtEOXact_ApplyLauncher(bool isCommit)
Definition: launcher.c:766
void AtEOXact_MultiXact(void)
Definition: multixact.c:1686
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition: namespace.c:4107
void AtEOXact_Enum(void)
Definition: pg_enum.c:638
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition: pgstat_xact.c:41
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:670
void AtEOXact_RelationCache(bool isCommit)
Definition: relcache.c:3176
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition: relmapper.c:541
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:148
void AtEOXact_SMgr(void)
Definition: smgr.c:709
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:752
void AtEOXact_SPI(bool isCommit)
Definition: spi.c:429
PGPROC * MyProc
Definition: proc.c:68
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:718
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:650
LocalTransactionId lxid
Definition: proc.h:183
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:16871
#define InvalidTransactionId
Definition: transam.h:31
void AfterTriggerEndXact(bool isCommit)
Definition: trigger.c:5189
void AtAbort_Twophase(void)
Definition: twophase.c:321
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1853
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3664
@ XACT_EVENT_ABORT
Definition: xact.h:123
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:124
XLogRecPtr XactLastRecEnd
Definition: xlog.c:257
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2357

References AbortBufferIO(), 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_MultiXact(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_Parallel(), AtEOXact_PgStat(), AtEOXact_RelationCache(), AtEOXact_RelationMap(), AtEOXact_SMgr(), AtEOXact_SPI(), TransactionStateData::blockState, CallXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, elog(), HOLD_INTERRUPTS, InvalidTransactionId, IsInParallelMode(), LockErrorCleanup(), LWLockReleaseAll(), PGPROC::lxid, MyProc, TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, PG_SETMASK, 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, TransStateAsString(), UnBlockSig, UnlockBuffers(), WARNING, XACT_EVENT_ABORT, XACT_EVENT_PARALLEL_ABORT, XactLastRecEnd, XLogResetInsertion(), and XLogSetAsyncXactLSN().

Referenced by AbortCurrentTransaction(), AbortOutOfAnyTransaction(), and CommitTransactionCommand().

◆ AssignTransactionId()

static void AssignTransactionId ( TransactionState  s)
static

Definition at line 625 of file xact.c.

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

References Assert(), CurrentResourceOwner, TransactionStateData::curTransactionOwner, TransactionStateData::didLogXid, elog(), 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 1821 of file xact.c.

1822 {
1823  /*
1824  * Switch into TransactionAbortContext, which should have some free space
1825  * even if nothing else does. We'll work in this context until we've
1826  * finished cleaning up.
1827  *
1828  * It is barely possible to get here when we've not been able to create
1829  * TransactionAbortContext yet; if so use TopMemoryContext.
1830  */
1831  if (TransactionAbortContext != NULL)
1833  else
1835 }
MemoryContext TopMemoryContext
Definition: mcxt.c:130
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:135
static MemoryContext TransactionAbortContext
Definition: xact.c:296

References MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1853 of file xact.c.

1854 {
1855  /*
1856  * Make sure we have a valid ResourceOwner, if possible (else it will be
1857  * NULL, which is OK)
1858  */
1860 }

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1539 of file xact.c.

1540 {
1541  /*
1542  * Make any pending relation map changes visible. We must do this before
1543  * processing local sinval messages, so that the map changes will get
1544  * reflected into the relcache when relcache invals are processed.
1545  */
1547 
1548  /*
1549  * Make catalog changes visible to me for the next command.
1550  */
1552 }
void CommandEndInvalidationMessages(void)
Definition: inval.c:1173
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 1911 of file xact.c.

1912 {
1914 
1915  /*
1916  * Now that we're "out" of a transaction, have the system allocate things
1917  * in the top memory context instead of per-transaction contexts.
1918  */
1920 
1921  /*
1922  * Clear the special abort context for next time.
1923  */
1924  if (TransactionAbortContext != NULL)
1926 
1927  /*
1928  * Release all transaction-local memory.
1929  */
1930  if (TopTransactionContext != NULL)
1932  TopTransactionContext = NULL;
1933  CurTransactionContext = NULL;
1935 }
MemoryContext TopTransactionContext
Definition: mcxt.c:135
MemoryContext CurTransactionContext
Definition: mcxt.c:136
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:376
#define MemoryContextResetAndDeleteChildren(ctx)
Definition: memutils.h:70
MemoryContext curTransactionContext
Definition: xact.c:198

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

Referenced by AbortOutOfAnyTransaction(), and CleanupTransaction().

◆ AtCommit_Memory()

static void AtCommit_Memory ( void  )
static

Definition at line 1558 of file xact.c.

1559 {
1560  /*
1561  * Now that we're "out" of a transaction, have the system allocate things
1562  * in the top memory context instead of per-transaction contexts.
1563  */
1565 
1566  /*
1567  * Release all transaction-local memory.
1568  */
1569  Assert(TopTransactionContext != NULL);
1571  TopTransactionContext = NULL;
1572  CurTransactionContext = NULL;
1574 }

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

1143 {
1145 }
void AcceptInvalidationMessages(void)
Definition: inval.c:746

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1151 of file xact.c.

1152 {
1154 
1155  /*
1156  * If this is the first time through, create a private context for
1157  * AbortTransaction to work in. By reserving some space now, we can
1158  * insulate AbortTransaction from out-of-memory scenarios. Like
1159  * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1160  * size, so that space will be reserved immediately.
1161  */
1162  if (TransactionAbortContext == NULL)
1165  "TransactionAbortContext",
1166  32 * 1024,
1167  32 * 1024,
1168  32 * 1024);
1169 
1170  /*
1171  * We shouldn't have a transaction context already.
1172  */
1173  Assert(TopTransactionContext == NULL);
1174 
1175  /*
1176  * Create a toplevel context for the transaction.
1177  */
1180  "TopTransactionContext",
1182 
1183  /*
1184  * In a top-level transaction, CurTransactionContext is the same as
1185  * TopTransactionContext.
1186  */
1189 
1190  /* Make the CurTransactionContext active. */
1192 }
#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 1198 of file xact.c.

1199 {
1201 
1202  /*
1203  * We shouldn't have a transaction resource owner already.
1204  */
1206 
1207  /*
1208  * Create a toplevel resource owner for the transaction.
1209  */
1210  s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1211 
1215 }
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:428
ResourceOwner CurTransactionResourceOwner
Definition: resowner.c:147

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

Referenced by StartTransaction().

◆ AtSubAbort_childXids()

static void AtSubAbort_childXids ( void  )
static

Definition at line 1879 of file xact.c.

1880 {
1882 
1883  /*
1884  * We keep the child-XID arrays in TopTransactionContext (see
1885  * AtSubCommit_childXids). This means we'd better free the array
1886  * explicitly at abort to avoid leakage.
1887  */
1888  if (s->childXids != NULL)
1889  pfree(s->childXids);
1890  s->childXids = NULL;
1891  s->nChildXids = 0;
1892  s->maxChildXids = 0;
1893 
1894  /*
1895  * We could prune the unreportedXids array here. But we don't bother. That
1896  * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1897  * would likely introduce more CPU time into the more common paths, so we
1898  * choose not to do that.
1899  */
1900 }
TransactionId * childXids
Definition: xact.c:200

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

Definition at line 1841 of file xact.c.

1842 {
1844 
1846 }

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1866 of file xact.c.

1867 {
1869 
1870  /* Make sure we have a valid ResourceOwner */
1872 }

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 1947 of file xact.c.

1948 {
1950 
1951  Assert(s->parent != NULL);
1952 
1953  /* Make sure we're not in an about-to-be-deleted context */
1956 
1957  /*
1958  * Clear the special abort context for next time.
1959  */
1960  if (TransactionAbortContext != NULL)
1962 
1963  /*
1964  * Delete the subxact local memory contexts. Its CurTransactionContext can
1965  * go too (note this also kills CurTransactionContexts from any children
1966  * of the subxact).
1967  */
1968  if (s->curTransactionContext)
1970  s->curTransactionContext = NULL;
1971 }

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

Referenced by CleanupSubTransaction().

◆ AtSubCommit_childXids()

static void AtSubCommit_childXids ( void  )
static

Definition at line 1614 of file xact.c.

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

1586 {
1588 
1589  Assert(s->parent != NULL);
1590 
1591  /* Return to parent transaction level's memory context. */
1594 
1595  /*
1596  * Ordinarily we cannot throw away the child's CurTransactionContext,
1597  * since the data it contains will be needed at upper commit. However, if
1598  * there isn't actually anything in it, we can throw it away. This avoids
1599  * a small memory leak in the common case of "trivial" subxacts.
1600  */
1602  {
1604  s->curTransactionContext = NULL;
1605  }
1606 }
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:625

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

1227 {
1229 
1230  Assert(CurTransactionContext != NULL);
1231 
1232  /*
1233  * Create a CurTransactionContext, which will be used to hold data that
1234  * survives subtransaction commit but disappears on subtransaction abort.
1235  * We make it a child of the immediate parent's CurTransactionContext.
1236  */
1238  "CurTransactionContext",
1241 
1242  /* Make the CurTransactionContext active. */
1244 }

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

1251 {
1253 
1254  Assert(s->parent != NULL);
1255 
1256  /*
1257  * Create a resource owner for the subtransaction. We make it a child of
1258  * the immediate parent's resource owner.
1259  */
1260  s->curTransactionOwner =
1262  "SubTransaction");
1263 
1266 }

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

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4152 of file xact.c.

4153 {
4155 
4156  /*
4157  * If we are in STARTED state (that is, no transaction block is open),
4158  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4159  * block.
4160  *
4161  * For caller convenience, we consider all other transaction states as
4162  * legal here; otherwise the caller would need its own state check, which
4163  * seems rather pointless.
4164  */
4165  if (s->blockState == TBLOCK_STARTED)
4167 }

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

Referenced by exec_simple_query().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4520 of file xact.c.

4521 {
4523 
4524  /*
4525  * Workers synchronize transaction state at the beginning of each parallel
4526  * operation, so we can't account for new subtransactions after that
4527  * point. We might be able to make an exception for the type of
4528  * subtransaction established by this function, which is typically used in
4529  * contexts where we're going to release or roll back the subtransaction
4530  * before proceeding further, so that no enduring change to the
4531  * transaction state occurs. For now, however, we prohibit this case along
4532  * with all the others.
4533  */
4534  if (IsInParallelMode())
4535  ereport(ERROR,
4536  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4537  errmsg("cannot start subtransactions during a parallel operation")));
4538 
4539  switch (s->blockState)
4540  {
4541  case TBLOCK_STARTED:
4542  case TBLOCK_INPROGRESS:
4544  case TBLOCK_END:
4545  case TBLOCK_PREPARE:
4546  case TBLOCK_SUBINPROGRESS:
4547  /* Normal subtransaction start */
4548  PushTransaction();
4549  s = CurrentTransactionState; /* changed by push */
4550 
4551  /*
4552  * Savepoint names, like the TransactionState block itself, live
4553  * in TopTransactionContext.
4554  */
4555  if (name)
4557  break;
4558 
4559  /* These cases are invalid. */
4560  case TBLOCK_DEFAULT:
4561  case TBLOCK_BEGIN:
4563  case TBLOCK_SUBBEGIN:
4564  case TBLOCK_SUBRELEASE:
4565  case TBLOCK_SUBCOMMIT:
4566  case TBLOCK_ABORT:
4567  case TBLOCK_SUBABORT:
4568  case TBLOCK_ABORT_END:
4569  case TBLOCK_SUBABORT_END:
4570  case TBLOCK_ABORT_PENDING:
4572  case TBLOCK_SUBRESTART:
4574  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4576  break;
4577  }
4578 
4581 }
#define FATAL
Definition: elog.h:37
const char * name
Definition: encode.c:561
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1470
static void PushTransaction(void)
Definition: xact.c:5230
void StartTransactionCommand(void)
Definition: xact.c:2925
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5510
void CommitTransactionCommand(void)
Definition: xact.c:3022

References TransactionStateData::blockState, BlockStateAsString(), CommitTransactionCommand(), CurrentTransactionState, elog(), ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), 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 3750 of file xact.c.

3751 {
3753 
3754  switch (s->blockState)
3755  {
3756  /*
3757  * We are not inside a transaction block, so allow one to begin.
3758  */
3759  case TBLOCK_STARTED:
3760  s->blockState = TBLOCK_BEGIN;
3761  break;
3762 
3763  /*
3764  * BEGIN converts an implicit transaction block to a regular one.
3765  * (Note that we allow this even if we've already done some
3766  * commands, which is a bit odd but matches historical practice.)
3767  */
3769  s->blockState = TBLOCK_BEGIN;
3770  break;
3771 
3772  /*
3773  * Already a transaction block in progress.
3774  */
3775  case TBLOCK_INPROGRESS:
3777  case TBLOCK_SUBINPROGRESS:
3778  case TBLOCK_ABORT:
3779  case TBLOCK_SUBABORT:
3780  ereport(WARNING,
3781  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3782  errmsg("there is already a transaction in progress")));
3783  break;
3784 
3785  /* These cases are invalid. */
3786  case TBLOCK_DEFAULT:
3787  case TBLOCK_BEGIN:
3788  case TBLOCK_SUBBEGIN:
3789  case TBLOCK_END:
3790  case TBLOCK_SUBRELEASE:
3791  case TBLOCK_SUBCOMMIT:
3792  case TBLOCK_ABORT_END:
3793  case TBLOCK_SUBABORT_END:
3794  case TBLOCK_ABORT_PENDING:
3796  case TBLOCK_SUBRESTART:
3798  case TBLOCK_PREPARE:
3799  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3801  break;
3802  }
3803 }

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(), and standard_ProcessUtility().

◆ BlockStateAsString()

static const char * BlockStateAsString ( TBlockState  blockState)
static

Definition at line 5510 of file xact.c.

5511 {
5512  switch (blockState)
5513  {
5514  case TBLOCK_DEFAULT:
5515  return "DEFAULT";
5516  case TBLOCK_STARTED:
5517  return "STARTED";
5518  case TBLOCK_BEGIN:
5519  return "BEGIN";
5520  case TBLOCK_INPROGRESS:
5521  return "INPROGRESS";
5523  return "IMPLICIT_INPROGRESS";
5525  return "PARALLEL_INPROGRESS";
5526  case TBLOCK_END:
5527  return "END";
5528  case TBLOCK_ABORT:
5529  return "ABORT";
5530  case TBLOCK_ABORT_END:
5531  return "ABORT_END";
5532  case TBLOCK_ABORT_PENDING:
5533  return "ABORT_PENDING";
5534  case TBLOCK_PREPARE:
5535  return "PREPARE";
5536  case TBLOCK_SUBBEGIN:
5537  return "SUBBEGIN";
5538  case TBLOCK_SUBINPROGRESS:
5539  return "SUBINPROGRESS";
5540  case TBLOCK_SUBRELEASE:
5541  return "SUBRELEASE";
5542  case TBLOCK_SUBCOMMIT:
5543  return "SUBCOMMIT";
5544  case TBLOCK_SUBABORT:
5545  return "SUBABORT";
5546  case TBLOCK_SUBABORT_END:
5547  return "SUBABORT_END";
5549  return "SUBABORT_PENDING";
5550  case TBLOCK_SUBRESTART:
5551  return "SUBRESTART";
5553  return "SUBABORT_RESTART";
5554  }
5555  return "UNRECOGNIZED";
5556 }

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

3727 {
3728  SubXactCallbackItem *item;
3730 
3731  for (item = SubXact_callbacks; item; item = next)
3732  {
3733  /* allow callbacks to unregister themselves when called */
3734  next = item->next;
3735  item->callback(event, mySubid, parentSubid, item->arg);
3736  }
3737 }
static int32 next
Definition: blutils.c:219
struct SubXactCallbackItem * next
Definition: xact.c:315
SubXactCallback callback
Definition: xact.c:316
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:320

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

3665 {
3666  XactCallbackItem *item;
3668 
3669  for (item = Xact_callbacks; item; item = next)
3670  {
3671  /* allow callbacks to unregister themselves when called */
3672  next = item->next;
3673  item->callback(event, item->arg);
3674  }
3675 }
struct XactCallbackItem * next
Definition: xact.c:303
void * arg
Definition: xact.c:305
XactCallback callback
Definition: xact.c:304
static XactCallbackItem * Xact_callbacks
Definition: xact.c:308

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

3547 {
3548  /*
3549  * xact block already started?
3550  */
3551  if (IsTransactionBlock())
3552  return;
3553 
3554  /*
3555  * subtransaction?
3556  */
3557  if (IsSubTransaction())
3558  return;
3559 
3560  /*
3561  * inside a function call?
3562  */
3563  if (!isTopLevel)
3564  return;
3565 
3566  ereport(throwError ? ERROR : WARNING,
3567  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3568  /* translator: %s represents an SQL statement name */
3569  errmsg("%s can only be used in transaction blocks",
3570  stmtType)));
3571 }
bool IsSubTransaction(void)
Definition: xact.c:4869
bool IsTransactionBlock(void)
Definition: xact.c:4796

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

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5197 of file xact.c.

5198 {
5200 
5201  ShowTransactionState("CleanupSubTransaction");
5202 
5203  if (s->state != TRANS_ABORT)
5204  elog(WARNING, "CleanupSubTransaction while in %s state",
5206 
5208 
5211  if (s->curTransactionOwner)
5213  s->curTransactionOwner = NULL;
5214 
5216 
5217  s->state = TRANS_DEFAULT;
5218 
5219  PopTransaction();
5220 }
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1093
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:742
static void AtSubCleanup_Memory(void)
Definition: xact.c:1947
static void PopTransaction(void)
Definition: xact.c:5290

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(), and RollbackAndReleaseCurrentSubTransaction().

◆ CleanupTransaction()

static void CleanupTransaction ( void  )
static

Definition at line 2876 of file xact.c.

2877 {
2879 
2880  /*
2881  * State should still be TRANS_ABORT from AbortTransaction().
2882  */
2883  if (s->state != TRANS_ABORT)
2884  elog(FATAL, "CleanupTransaction: unexpected state %s",
2886 
2887  /*
2888  * do abort cleanup processing
2889  */
2890  AtCleanup_Portals(); /* now safe to release portal memory */
2891  AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2892 
2893  CurrentResourceOwner = NULL; /* and resource owner */
2896  s->curTransactionOwner = NULL;
2899 
2900  AtCleanup_Memory(); /* and transaction memory */
2901 
2904  s->nestingLevel = 0;
2905  s->gucNestLevel = 0;
2906  s->childXids = NULL;
2907  s->nChildXids = 0;
2908  s->maxChildXids = 0;
2909  s->parallelModeLevel = 0;
2910 
2913 
2914  /*
2915  * done with abort processing, set current transaction state back to
2916  * default
2917  */
2918  s->state = TRANS_DEFAULT;
2919 }
#define InvalidSubTransactionId
Definition: c.h:594
void AtCleanup_Portals(void)
Definition: portalmem.c:859
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:1025
#define InvalidFullTransactionId
Definition: transam.h:56
static int nParallelCurrentXids
Definition: xact.c:125

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

Referenced by AbortCurrentTransaction(), AbortOutOfAnyTransaction(), and CommitTransactionCommand().

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 1077 of file xact.c.

1078 {
1079  /*
1080  * If the current value of the command counter hasn't been "used" to mark
1081  * tuples, we need not increment it, since there's no need to distinguish
1082  * a read-only command from others. This helps postpone command counter
1083  * overflow, and keeps no-op CommandCounterIncrement operations cheap.
1084  */
1086  {
1087  /*
1088  * Workers synchronize transaction state at the beginning of each
1089  * parallel operation, so we can't account for new commands after that
1090  * point.
1091  */
1093  elog(ERROR, "cannot start commands during a parallel operation");
1094 
1095  currentCommandId += 1;
1097  {
1098  currentCommandId -= 1;
1099  ereport(ERROR,
1100  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
1101  errmsg("cannot have more than 2^32-2 commands in a transaction")));
1102  }
1103  currentCommandIdUsed = false;
1104 
1105  /* Propagate new command ID into static snapshots */
1107 
1108  /*
1109  * Make any catalog changes done by the just-completed command visible
1110  * in the local syscache. We obviously don't need to do this after a
1111  * read-only command. (But see hacks in inval.c to make real sure we
1112  * don't think a command that queued inval messages was read-only.)
1113  */
1114  AtCCI_LocalCache();
1115  }
1116 }
#define InvalidCommandId
Definition: c.h:605
void SnapshotSetCommandId(CommandId curcid)
Definition: snapmgr.c:491
static bool currentCommandIdUsed
Definition: xact.c:261
static CommandId currentCommandId
Definition: xact.c:260
static void AtCCI_LocalCache(void)
Definition: xact.c:1539

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

Referenced by _SPI_execute_plan(), acquire_inherited_sample_rows(), addFkRecurseReferenced(), addFkRecurseReferencing(), AddRoleMems(), AlterPublicationOptions(), AlterRole(), ATAddCheckConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecCmd(), ATExecDropColumn(), ATExecDropConstraint(), ATExecDropExpression(), ATExecDropIdentity(), ATExecSetCompression(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), ATParseTransformCmd(), ATRewriteTables(), AttachPartitionEnsureIndexes(), btadjustmembers(), CloneFkReferencing(), CommitSubTransaction(), CommitTransactionCommand(), copy_table_data(), create_ctas_internal(), create_toast_table(), CreateFKCheckTrigger(), createForeignKeyActionTriggers(), CreateForeignTable(), CreatePublication(), CreateRole(), CreateSchemaCommand(), CreateTriggerFiringOn(), DefineCollation(), DefineDomain(), DefineRelation(), DefineVirtualRelation(), deleteOneObject(), DetachPartitionFinalize(), DropClonedTriggersFromPartition(), DropRole(), end_replication_step(), EventTriggerDDLCommandEnd(), EventTriggerDDLCommandStart(), EventTriggerInvoke(), EventTriggerSQLDrop(), EventTriggerTableRewrite(), exec_eval_simple_expr(), exec_execute_message(), exec_parse_message(), exec_simple_query(), ExecGrant_Database(), ExecGrant_Fdw(), ExecGrant_ForeignServer(), ExecGrant_Function(), ExecGrant_Language(), ExecGrant_Largeobject(), ExecGrant_Namespace(), ExecGrant_Parameter(), ExecGrant_Relation(), ExecGrant_Tablespace(), ExecGrant_Type(), 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(), ProcessUtilitySlow(), recordExtensionInitPrivWorker(), reindex_index(), reindex_relation(), ReindexRelationConcurrently(), RelationSetNewRelfilenumber(), RemoveRoleFromObjectPolicy(), RenumberEnumType(), replorigin_create(), replorigin_drop_guts(), ri_PerformCheck(), SetDefaultACL(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), standard_ProcessUtility(), StoreConstraints(), StorePartitionBound(), tryAttachPartitionForeignKey(), vacuum(), and validatePartitionedIndex().

◆ CommitSubTransaction()

static void CommitSubTransaction ( void  )
static

Definition at line 4929 of file xact.c.

4930 {
4932 
4933  ShowTransactionState("CommitSubTransaction");
4934 
4935  if (s->state != TRANS_INPROGRESS)
4936  elog(WARNING, "CommitSubTransaction while in %s state",
4938 
4939  /* Pre-commit processing goes here */
4940 
4942  s->parent->subTransactionId);
4943 
4944  /* If in parallel mode, clean up workers and exit parallel mode. */
4945  if (IsInParallelMode())
4946  {
4948  s->parallelModeLevel = 0;
4949  }
4950 
4951  /* Do the actual "commit", such as it is */
4952  s->state = TRANS_COMMIT;
4953 
4954  /* Must CCI to ensure commands of subtransaction are seen as done */
4956 
4957  /*
4958  * Prior to 8.4 we marked subcommit in clog at this point. We now only
4959  * perform that step, if required, as part of the atomic update of the
4960  * whole transaction tree at top level commit or abort.
4961  */
4962 
4963  /* Post-commit cleanup */
4966  AfterTriggerEndSubXact(true);
4969  s->parent->nestingLevel,
4972  s->parent->subTransactionId);
4974 
4976  s->parent->subTransactionId);
4977 
4980  true, false);
4982  s->parent->subTransactionId);
4983  AtEOSubXact_Inval(true);
4984  AtSubCommit_smgr();
4985 
4986  /*
4987  * The only lock we actually release here is the subtransaction XID lock.
4988  */
4992 
4993  /*
4994  * Other locks should get transferred to their parent resource owner.
4995  */
4998  true, false);
5001  true, false);
5002 
5003  AtEOXact_GUC(true, s->gucNestLevel);
5006  s->parent->subTransactionId);
5008  s->parent->subTransactionId);
5010  s->parent->subTransactionId);
5012  AtEOSubXact_PgStat(true, s->nestingLevel);
5014 
5015  /*
5016  * We need to restore the upper transaction's read-only state, in case the
5017  * upper is read-write while the child is read-only; GUC will incorrectly
5018  * think it should leave the child state in place.
5019  */
5021 
5025  s->curTransactionOwner = NULL;
5026 
5028 
5029  s->state = TRANS_DEFAULT;
5030 
5031  PopTransaction();
5032 }
void AtSubCommit_Notify(void)
Definition: async.c:1740
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:644
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition: portalmem.c:944
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:968
void AtSubCommit_smgr(void)
Definition: storage.c:932
static void AtSubCommit_Memory(void)
Definition: xact.c:1585
static void AtSubCommit_childXids(void)
Definition: xact.c:1614
void CommandCounterIncrement(void)
Definition: xact.c:1077
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition: xact.h:138
@ SUBXACT_EVENT_COMMIT_SUB
Definition: xact.h:136

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, IsInParallelMode(), 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 CommitTransactionCommand(), and ReleaseCurrentSubTransaction().

◆ CommitTransaction()

static void CommitTransaction ( void  )
static

Definition at line 2141 of file xact.c.

2142 {
2144  TransactionId latestXid;
2145  bool is_parallel_worker;
2146 
2147  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2148 
2149  /* Enforce parallel mode restrictions during parallel worker commit. */
2150  if (is_parallel_worker)
2152 
2153  ShowTransactionState("CommitTransaction");
2154 
2155  /*
2156  * check the current transaction state
2157  */
2158  if (s->state != TRANS_INPROGRESS)
2159  elog(WARNING, "CommitTransaction while in %s state",
2161  Assert(s->parent == NULL);
2162 
2163  /*
2164  * Do pre-commit processing that involves calling user-defined code, such
2165  * as triggers. SECURITY_RESTRICTED_OPERATION contexts must not queue an
2166  * action that would run here, because that would bypass the sandbox.
2167  * Since closing cursors could queue trigger actions, triggers could open
2168  * cursors, etc, we have to keep looping until there's nothing left to do.
2169  */
2170  for (;;)
2171  {
2172  /*
2173  * Fire all currently pending deferred triggers.
2174  */
2176 
2177  /*
2178  * Close open portals (converting holdable ones into static portals).
2179  * If there weren't any, we are done ... otherwise loop back to check
2180  * if they queued deferred triggers. Lather, rinse, repeat.
2181  */
2182  if (!PreCommit_Portals(false))
2183  break;
2184  }
2185 
2186  /*
2187  * The remaining actions cannot call any user-defined code, so it's safe
2188  * to start shutting down within-transaction services. But note that most
2189  * of this stuff could still throw an error, which would switch us into
2190  * the transaction-abort path.
2191  */
2192 
2195 
2196  /* If we might have parallel workers, clean them up now. */
2197  if (IsInParallelMode())
2198  AtEOXact_Parallel(true);
2199 
2200  /* Shut down the deferred-trigger manager */
2201  AfterTriggerEndXact(true);
2202 
2203  /*
2204  * Let ON COMMIT management do its thing (must happen after closing
2205  * cursors, to avoid dangling-reference problems)
2206  */
2208 
2209  /*
2210  * Synchronize files that are created and not WAL-logged during this
2211  * transaction. This must happen before AtEOXact_RelationMap(), so that we
2212  * don't see committed-but-broken files after a crash.
2213  */
2214  smgrDoPendingSyncs(true, is_parallel_worker);
2215 
2216  /* close large objects before lower-level cleanup */
2217  AtEOXact_LargeObject(true);
2218 
2219  /*
2220  * Insert notifications sent by NOTIFY commands into the queue. This
2221  * should be late in the pre-commit sequence to minimize time spent
2222  * holding the notify-insertion lock. However, this could result in
2223  * creating a snapshot, so we must do it before serializable cleanup.
2224  */
2225  PreCommit_Notify();
2226 
2227  /*
2228  * Mark serializable transaction as complete for predicate locking
2229  * purposes. This should be done as late as we can put it and still allow
2230  * errors to be raised for failure patterns found at commit. This is not
2231  * appropriate in a parallel worker however, because we aren't committing
2232  * the leader's transaction and its serializable state will live on.
2233  */
2234  if (!is_parallel_worker)
2236 
2237  /* Prevent cancel/die interrupt while cleaning up */
2238  HOLD_INTERRUPTS();
2239 
2240  /* Commit updates to the relation map --- do this as late as possible */
2241  AtEOXact_RelationMap(true, is_parallel_worker);
2242 
2243  /*
2244  * set the current transaction state information appropriately during
2245  * commit processing
2246  */
2247  s->state = TRANS_COMMIT;
2248  s->parallelModeLevel = 0;
2249 
2250  if (!is_parallel_worker)
2251  {
2252  /*
2253  * We need to mark our XIDs as committed in pg_xact. This is where we
2254  * durably commit.
2255  */
2256  latestXid = RecordTransactionCommit();
2257  }
2258  else
2259  {
2260  /*
2261  * We must not mark our XID committed; the parallel leader is
2262  * responsible for that.
2263  */
2264  latestXid = InvalidTransactionId;
2265 
2266  /*
2267  * Make sure the leader will know about any WAL we wrote before it
2268  * commits.
2269  */
2271  }
2272 
2273  TRACE_POSTGRESQL_TRANSACTION_COMMIT(MyProc->lxid);
2274 
2275  /*
2276  * Let others know about no transaction in progress by me. Note that this
2277  * must be done _before_ releasing locks we hold and _after_
2278  * RecordTransactionCommit.
2279  */
2280  ProcArrayEndTransaction(MyProc, latestXid);
2281 
2282  /*
2283  * This is all post-commit cleanup. Note that if an error is raised here,
2284  * it's too late to abort the transaction. This should be just
2285  * noncritical resource releasing.
2286  *
2287  * The ordering of operations is not entirely random. The idea is:
2288  * release resources visible to other backends (eg, files, buffer pins);
2289  * then release locks; then release backend-local resources. We want to
2290  * release locks at the point where any backend waiting for us will see
2291  * our transaction as being fully cleaned up.
2292  *
2293  * Resources that can be associated with individual queries are handled by
2294  * the ResourceOwner mechanism. The other calls here are for backend-wide
2295  * state.
2296  */
2297 
2298  CallXactCallbacks(is_parallel_worker ? XACT_EVENT_PARALLEL_COMMIT
2299  : XACT_EVENT_COMMIT);
2300 
2303  true, true);
2304 
2305  /* Check we've released all buffer pins */
2306  AtEOXact_Buffers(true);
2307 
2308  /* Clean up the relation cache */
2309  AtEOXact_RelationCache(true);
2310 
2311  /*
2312  * Make catalog changes visible to all backends. This has to happen after
2313  * relcache references are dropped (see comments for
2314  * AtEOXact_RelationCache), but before locks are released (if anyone is
2315  * waiting for lock on a relation we've modified, we want them to know
2316  * about the catalog change before they start using the relation).
2317  */
2318  AtEOXact_Inval(true);
2319 
2321 
2324  true, true);
2327  true, true);
2328 
2329  /*
2330  * Likewise, dropping of files deleted during the transaction is best done
2331  * after releasing relcache and buffer pins. (This is not strictly
2332  * necessary during commit, since such pins should have been released
2333  * already, but this ordering is definitely critical during abort.) Since
2334  * this may take many seconds, also delay until after releasing locks.
2335  * Other backends will observe the attendant catalog changes and not
2336  * attempt to access affected files.
2337  */
2338  smgrDoPendingDeletes(true);
2339 
2340  /*
2341  * Send out notification signals to other backends (and do other
2342  * post-commit NOTIFY cleanup). This must not happen until after our
2343  * transaction is fully done from the viewpoint of other backends.
2344  */
2345  AtCommit_Notify();
2346 
2347  /*
2348  * Everything after this should be purely internal-to-this-backend
2349  * cleanup.
2350  */
2351  AtEOXact_GUC(true, 1);
2352  AtEOXact_SPI(true);
2353  AtEOXact_Enum();
2355  AtEOXact_Namespace(true, is_parallel_worker);
2356  AtEOXact_SMgr();
2357  AtEOXact_Files(true);
2359  AtEOXact_HashTables(true);
2360  AtEOXact_PgStat(true, is_parallel_worker);
2361  AtEOXact_Snapshot(true, false);
2362  AtEOXact_ApplyLauncher(true);
2364 
2365  CurrentResourceOwner = NULL;
2367  s->curTransactionOwner = NULL;
2370 
2371  AtCommit_Memory();
2372 
2375  s->nestingLevel = 0;
2376  s->gucNestLevel = 0;
2377  s->childXids = NULL;
2378  s->nChildXids = 0;
2379  s->maxChildXids = 0;
2380 
2383 
2384  /*
2385  * done with commit processing, set current transaction state back to
2386  * default
2387  */
2388  s->state = TRANS_DEFAULT;
2389 
2391 }
void AtCommit_Notify(void)
Definition: async.c:1002
void PreCommit_Notify(void)
Definition: async.c:895
void ParallelWorkerReportLastRecEnd(XLogRecPtr last_xlog_end)
Definition: parallel.c:1543
bool PreCommit_Portals(bool isPrepare)
Definition: portalmem.c:678
void PreCommit_CheckForSerializationFailure(void)
Definition: predicate.c:4826
void PreCommit_on_commit_actions(void)
Definition: tablecmds.c:16772
void AfterTriggerFireDeferred(void)
Definition: trigger.c:5133
void EnterParallelMode(void)
Definition: xact.c:1035
static TransactionId RecordTransactionCommit(void)
Definition: xact.c:1282
static void AtCommit_Memory(void)
Definition: xact.c:1558
@ XACT_EVENT_COMMIT
Definition: xact.h:121
@ XACT_EVENT_PARALLEL_PRE_COMMIT
Definition: xact.h:127
@ XACT_EVENT_PARALLEL_COMMIT
Definition: xact.h:122
@ XACT_EVENT_PRE_COMMIT
Definition: xact.h:126

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_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, elog(), EnterParallelMode(), TransactionStateData::fullTransactionId, TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, InvalidFullTransactionId, InvalidSubTransactionId, InvalidTransactionId, IsInParallelMode(), PGPROC::lxid, TransactionStateData::maxChildXids, MyProc, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, 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, TransStateAsString(), WARNING, XACT_EVENT_COMMIT, XACT_EVENT_PARALLEL_COMMIT, XACT_EVENT_PARALLEL_PRE_COMMIT, XACT_EVENT_PRE_COMMIT, XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommand(), EndParallelWorkerTransaction(), EndRestoreLOs(), restore_toc_entry(), and RestoreArchive().

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 3022 of file xact.c.

3023 {
3026 
3028 
3029  switch (s->blockState)
3030  {
3031  /*
3032  * These shouldn't happen. TBLOCK_DEFAULT means the previous
3033  * StartTransactionCommand didn't set the STARTED state
3034  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3035  * by EndParallelWorkerTransaction(), not this function.
3036  */
3037  case TBLOCK_DEFAULT:
3039  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3041  break;
3042 
3043  /*
3044  * If we aren't in a transaction block, just do our usual
3045  * transaction commit, and return to the idle state.
3046  */
3047  case TBLOCK_STARTED:
3050  break;
3051 
3052  /*
3053  * We are completing a "BEGIN TRANSACTION" command, so we change
3054  * to the "transaction block in progress" state and return. (We
3055  * assume the BEGIN did nothing to the database, so we need no
3056  * CommandCounterIncrement.)
3057  */
3058  case TBLOCK_BEGIN:
3060  break;
3061 
3062  /*
3063  * This is the case when we have finished executing a command
3064  * someplace within a transaction block. We increment the command
3065  * counter and return.
3066  */
3067  case TBLOCK_INPROGRESS:
3069  case TBLOCK_SUBINPROGRESS:
3071  break;
3072 
3073  /*
3074  * We are completing a "COMMIT" command. Do it and return to the
3075  * idle state.
3076  */
3077  case TBLOCK_END:
3080  if (s->chain)
3081  {
3082  StartTransaction();
3084  s->chain = false;
3086  }
3087  break;
3088 
3089  /*
3090  * Here we are in the middle of a transaction block but one of the
3091  * commands caused an abort so we do nothing but remain in the
3092  * abort state. Eventually we will get a ROLLBACK command.
3093  */
3094  case TBLOCK_ABORT:
3095  case TBLOCK_SUBABORT:
3096  break;
3097 
3098  /*
3099  * Here we were in an aborted transaction block and we just got
3100  * the ROLLBACK command from the user, so clean up the
3101  * already-aborted transaction and return to the idle state.
3102  */
3103  case TBLOCK_ABORT_END:
3106  if (s->chain)
3107  {
3108  StartTransaction();
3110  s->chain = false;
3112  }
3113  break;
3114 
3115  /*
3116  * Here we were in a perfectly good transaction block but the user
3117  * told us to ROLLBACK anyway. We have to abort the transaction
3118  * and then clean up.
3119  */
3120  case TBLOCK_ABORT_PENDING:
3121  AbortTransaction();
3124  if (s->chain)
3125  {
3126  StartTransaction();
3128  s->chain = false;
3130  }
3131  break;
3132 
3133  /*
3134  * We are completing a "PREPARE TRANSACTION" command. Do it and
3135  * return to the idle state.
3136  */
3137  case TBLOCK_PREPARE:
3140  break;
3141 
3142  /*
3143  * The user issued a SAVEPOINT inside a transaction block.
3144  * Start a subtransaction. (DefineSavepoint already did
3145  * PushTransaction, so as to have someplace to put the SUBBEGIN
3146  * state.)
3147  */
3148  case TBLOCK_SUBBEGIN:
3151  break;
3152 
3153  /*
3154  * The user issued a RELEASE command, so we end the current
3155  * subtransaction and return to the parent transaction. The parent
3156  * might be ended too, so repeat till we find an INPROGRESS
3157  * transaction or subtransaction.
3158  */
3159  case TBLOCK_SUBRELEASE:
3160  do
3161  {
3163  s = CurrentTransactionState; /* changed by pop */
3164  } while (s->blockState == TBLOCK_SUBRELEASE);
3165 
3168  break;
3169 
3170  /*
3171  * The user issued a COMMIT, so we end the current subtransaction
3172  * hierarchy and perform final commit. We do this by rolling up
3173  * any subtransactions into their parent, which leads to O(N^2)
3174  * operations with respect to resource owners - this isn't that
3175  * bad until we approach a thousands of savepoints but is
3176  * necessary for correctness should after triggers create new
3177  * resource owners.
3178  */
3179  case TBLOCK_SUBCOMMIT:
3180  do
3181  {
3183  s = CurrentTransactionState; /* changed by pop */
3184  } while (s->blockState == TBLOCK_SUBCOMMIT);
3185  /* If we had a COMMIT command, finish off the main xact too */
3186  if (s->blockState == TBLOCK_END)
3187  {
3188  Assert(s->parent == NULL);
3191  if (s->chain)
3192  {
3193  StartTransaction();
3195  s->chain = false;
3197  }
3198  }
3199  else if (s->blockState == TBLOCK_PREPARE)
3200  {
3201  Assert(s->parent == NULL);
3204  }
3205  else
3206  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3208  break;
3209 
3210  /*
3211  * The current already-failed subtransaction is ending due to a
3212  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3213  * examine the parent (which could be in any of several states).
3214  */
3215  case TBLOCK_SUBABORT_END:
3218  break;
3219 
3220  /*
3221  * As above, but it's not dead yet, so abort first.
3222  */
3227  break;
3228 
3229  /*
3230  * The current subtransaction is the target of a ROLLBACK TO
3231  * command. Abort and pop it, then start a new subtransaction
3232  * with the same name.
3233  */
3234  case TBLOCK_SUBRESTART:
3235  {
3236  char *name;
3237  int savepointLevel;
3238 
3239  /* save name and keep Cleanup from freeing it */
3240  name = s->name;
3241  s->name = NULL;
3242  savepointLevel = s->savepointLevel;
3243 
3246 
3247  DefineSavepoint(NULL);
3248  s = CurrentTransactionState; /* changed by push */
3249  s->name = name;
3250  s->savepointLevel = savepointLevel;
3251 
3252  /* This is the same as TBLOCK_SUBBEGIN case */
3256  }
3257  break;
3258 
3259  /*
3260  * Same as above, but the subtransaction had already failed, so we
3261  * don't need AbortSubTransaction.
3262  */
3264  {
3265  char *name;
3266  int savepointLevel;
3267 
3268  /* save name and keep Cleanup from freeing it */
3269  name = s->name;
3270  s->name = NULL;
3271  savepointLevel = s->savepointLevel;
3272 
3274 
3275  DefineSavepoint(NULL);
3276  s = CurrentTransactionState; /* changed by push */
3277  s->name = name;
3278  s->savepointLevel = savepointLevel;
3279 
3280  /* This is the same as TBLOCK_SUBBEGIN case */
3284  }
3285  break;
3286  }
3287 }
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3002
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3010
static void StartTransaction(void)
Definition: xact.c:1982
void DefineSavepoint(const char *name)
Definition: xact.c:4199
static void CommitSubTransaction(void)
Definition: xact.c:4929
static void CommitTransaction(void)
Definition: xact.c:2141
static void PrepareTransaction(void)
Definition: xact.c:2400
static void StartSubTransaction(void)
Definition: xact.c:4892

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 _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_abort(), apply_handle_stream_prepare(), apply_handle_stream_stop(), ApplyWorkerMain(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), BeginInternalSubTransaction(), BootstrapModeMain(), clear_subscription_skip_lsn(), cluster_multiple_rels(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), exec_replication_command(), finish_xact_command(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitPostgres(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), ParallelWorkerMain(), pg_attribute_noreturn(), process_syncing_tables_for_apply(), process_syncing_tables_for_sync(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), shell_check_detail(), vacuum(), and vacuum_rel().

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

Definition at line 4199 of file xact.c.

4200 {
4202 
4203  /*
4204  * Workers synchronize transaction state at the beginning of each parallel
4205  * operation, so we can't account for new subtransactions after that
4206  * point. (Note that this check will certainly error out if s->blockState
4207  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4208  * below.)
4209  */
4210  if (IsInParallelMode())
4211  ereport(ERROR,
4212  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4213  errmsg("cannot define savepoints during a parallel operation")));
4214 
4215  switch (s->blockState)
4216  {
4217  case TBLOCK_INPROGRESS:
4218  case TBLOCK_SUBINPROGRESS:
4219  /* Normal subtransaction start */
4220  PushTransaction();
4221  s = CurrentTransactionState; /* changed by push */
4222 
4223  /*
4224  * Savepoint names, like the TransactionState block itself, live
4225  * in TopTransactionContext.
4226  */
4227  if (name)
4229  break;
4230 
4231  /*
4232  * We disallow savepoint commands in implicit transaction blocks.
4233  * There would be no great difficulty in allowing them so far as
4234  * this module is concerned, but a savepoint seems inconsistent
4235  * with exec_simple_query's behavior of abandoning the whole query
4236  * string upon error. Also, the point of an implicit transaction
4237  * block (as opposed to a regular one) is to automatically close
4238  * after an error, so it's hard to see how a savepoint would fit
4239  * into that.
4240  *
4241  * The error messages for this are phrased as if there were no
4242  * active transaction block at all, which is historical but
4243  * perhaps could be improved.
4244  */
4246  ereport(ERROR,
4247  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4248  /* translator: %s represents an SQL statement name */
4249  errmsg("%s can only be used in transaction blocks",
4250  "SAVEPOINT")));
4251  break;
4252 
4253  /* These cases are invalid. */
4254  case TBLOCK_DEFAULT:
4255  case TBLOCK_STARTED:
4256  case TBLOCK_BEGIN:
4258  case TBLOCK_SUBBEGIN:
4259  case TBLOCK_END:
4260  case TBLOCK_SUBRELEASE:
4261  case TBLOCK_SUBCOMMIT:
4262  case TBLOCK_ABORT:
4263  case TBLOCK_SUBABORT:
4264  case TBLOCK_ABORT_END:
4265  case TBLOCK_SUBABORT_END:
4266  case TBLOCK_ABORT_PENDING:
4268  case TBLOCK_SUBRESTART:
4270  case TBLOCK_PREPARE:
4271  elog(FATAL, "DefineSavepoint: unexpected state %s",
4273  break;
4274  }
4275 }

References TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, elog(), ereport, errcode(), errmsg(), ERROR, FATAL, IsInParallelMode(), 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 CommitTransactionCommand(), and standard_ProcessUtility().

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 4177 of file xact.c.

4178 {
4180 
4181  /*
4182  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4183  * allowing CommitTransactionCommand to commit whatever happened during
4184  * the implicit transaction block as though it were a single statement.
4185  *
4186  * For caller convenience, we consider all other transaction states as
4187  * legal here; otherwise the caller would need its own state check, which
4188  * seems rather pointless.
4189  */
4192 }

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

Referenced by exec_simple_query().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 3870 of file xact.c.

3871 {
3873  bool result = false;
3874 
3875  switch (s->blockState)
3876  {
3877  /*
3878  * We are in a transaction block, so tell CommitTransactionCommand
3879  * to COMMIT.
3880  */
3881  case TBLOCK_INPROGRESS:
3882  s->blockState = TBLOCK_END;
3883  result = true;
3884  break;
3885 
3886  /*
3887  * We are in an implicit transaction block. If AND CHAIN was
3888  * specified, error. Otherwise commit, but issue a warning
3889  * because there was no explicit BEGIN before this.
3890  */
3892  if (chain)
3893  ereport(ERROR,
3894  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3895  /* translator: %s represents an SQL statement name */
3896  errmsg("%s can only be used in transaction blocks",
3897  "COMMIT AND CHAIN")));
3898  else
3899  ereport(WARNING,
3900  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3901  errmsg("there is no transaction in progress")));
3902  s->blockState = TBLOCK_END;
3903  result = true;
3904  break;
3905 
3906  /*
3907  * We are in a failed transaction block. Tell
3908  * CommitTransactionCommand it's time to exit the block.
3909  */
3910  case TBLOCK_ABORT:
3912  break;
3913 
3914  /*
3915  * We are in a live subtransaction block. Set up to subcommit all
3916  * open subtransactions and then commit the main transaction.
3917  */
3918  case TBLOCK_SUBINPROGRESS:
3919  while (s->parent != NULL)
3920  {
3921  if (s->blockState == TBLOCK_SUBINPROGRESS)
3923  else
3924  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3926  s = s->parent;
3927  }
3928  if (s->blockState == TBLOCK_INPROGRESS)
3929  s->blockState = TBLOCK_END;
3930  else
3931  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3933  result = true;
3934  break;
3935 
3936  /*
3937  * Here we are inside an aborted subtransaction. Treat the COMMIT
3938  * as ROLLBACK: set up to abort everything and exit the main
3939  * transaction.
3940  */
3941  case TBLOCK_SUBABORT:
3942  while (s->parent != NULL)
3943  {
3944  if (s->blockState == TBLOCK_SUBINPROGRESS)
3946  else if (s->blockState == TBLOCK_SUBABORT)
3948  else
3949  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3951  s = s->parent;
3952  }
3953  if (s->blockState == TBLOCK_INPROGRESS)
3955  else if (s->blockState == TBLOCK_ABORT)
3957  else
3958  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3960  break;
3961 
3962  /*
3963  * The user issued COMMIT when not inside a transaction. For
3964  * COMMIT without CHAIN, issue a WARNING, staying in
3965  * TBLOCK_STARTED state. The upcoming call to
3966  * CommitTransactionCommand() will then close the transaction and
3967  * put us back into the default state. For COMMIT AND CHAIN,
3968  * error.
3969  */
3970  case TBLOCK_STARTED:
3971  if (chain)
3972  ereport(ERROR,
3973  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3974  /* translator: %s represents an SQL statement name */
3975  errmsg("%s can only be used in transaction blocks",
3976  "COMMIT AND CHAIN")));
3977  else
3978  ereport(WARNING,
3979  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3980  errmsg("there is no transaction in progress")));
3981  result = true;
3982  break;
3983 
3984  /*
3985  * The user issued a COMMIT that somehow ran inside a parallel
3986  * worker. We can't cope with that.
3987  */
3989  ereport(FATAL,
3990  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3991  errmsg("cannot commit during a parallel operation")));
3992  break;
3993 
3994  /* These cases are invalid. */
3995  case TBLOCK_DEFAULT:
3996  case TBLOCK_BEGIN:
3997  case TBLOCK_SUBBEGIN:
3998  case TBLOCK_END:
3999  case TBLOCK_SUBRELEASE:
4000  case TBLOCK_SUBCOMMIT:
4001  case TBLOCK_ABORT_END:
4002  case TBLOCK_SUBABORT_END:
4003  case TBLOCK_ABORT_PENDING:
4005  case TBLOCK_SUBRESTART:
4007  case TBLOCK_PREPARE:
4008  elog(FATAL, "EndTransactionBlock: unexpected state %s",
4010  break;
4011  }
4012 
4014  s->blockState == TBLOCK_END ||
4015  s->blockState == TBLOCK_ABORT_END ||
4017 
4018  s->chain = chain;
4019 
4020  return result;
4021 }

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 PrepareTransactionBlock(), and standard_ProcessUtility().

◆ EnterParallelMode()

void EnterParallelMode ( void  )

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 5324 of file xact.c.

5325 {
5326  TransactionState s;
5327  Size nxids = 0;
5329 
5330  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5331  {
5333  nxids = add_size(nxids, 1);
5334  nxids = add_size(nxids, s->nChildXids);
5335  }
5336 
5337  return add_size(size, mul_size(sizeof(TransactionId), nxids));
5338 }
size_t Size
Definition: c.h:541
Size add_size(Size s1, Size s2)
Definition: shmem.c:502
Size mul_size(Size s1, Size s2)
Definition: shmem.c:519
#define SerializedTransactionStateHeaderSize
Definition: xact.c:232

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

Referenced by InitializeParallelDSM().

◆ ExitParallelMode()

void ExitParallelMode ( void  )

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 1127 of file xact.c.

1128 {
1129  forceSyncCommit = true;
1130 }
static bool forceSyncCommit
Definition: xact.c:286

References forceSyncCommit.

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 817 of file xact.c.

818 {
819  /* this is global to a transaction, not subtransaction-local */
820  if (used)
821  {
822  /*
823  * Forbid setting currentCommandIdUsed in a parallel worker, because
824  * we have no provision for communicating this back to the leader. We
825  * could relax this restriction when currentCommandIdUsed was already
826  * true at the start of the parallel operation.
827  */
829  currentCommandIdUsed = true;
830  }
831  return currentCommandId;
832 }

References Assert(), currentCommandId, currentCommandIdUsed, 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 520 of file xact.c.

521 {
523 }

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 863 of file xact.c.

864 {
865  return stmtStartTimestamp;
866 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:274

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

855 {
856  return xactStartTimestamp;
857 }
static TimestampTz xactStartTimestamp
Definition: xact.c:273

References xactStartTimestamp.

Referenced by current_timestamp(), GetCurrentTimeUsec(), InitializeParallelDSM(), now(), pg_timezone_abbrevs(), sql_localtimestamp(), and timetz_zone().

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 875 of file xact.c.

876 {
878 
879  /* should only be called after commit / abort processing */
880  Assert(s->state == TRANS_DEFAULT ||
881  s->state == TRANS_COMMIT ||
882  s->state == TRANS_ABORT ||
883  s->state == TRANS_PREPARE);
884 
885  if (xactStopTimestamp == 0)
887 
888  return xactStopTimestamp;
889 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1573
#define PG_USED_FOR_ASSERTS_ONLY
Definition: c.h:166
static TimestampTz xactStopTimestamp
Definition: xact.c:275

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

598 {
600  static TransactionId stablexid = InvalidTransactionId;
601 
602  if (lxid != MyProc->lxid)
603  {
604  lxid = MyProc->lxid;
605  stablexid = GetTopTransactionIdIfAny();
606  if (!TransactionIdIsValid(stablexid))
607  stablexid = ReadNextTransactionId();
608  }
609 
610  Assert(TransactionIdIsValid(stablexid));
611 
612  return stablexid;
613 }
uint32 LocalTransactionId
Definition: c.h:590
#define InvalidLocalTransactionId
Definition: lock.h:70
static TransactionId ReadNextTransactionId(void)
Definition: transam.h:315
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:431

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

Referenced by xid_age().

◆ GetTopFullTransactionId()

◆ GetTopFullTransactionIdIfAny()

FullTransactionId GetTopFullTransactionIdIfAny ( void  )

Definition at line 489 of file xact.c.

490 {
492 }

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3588 of file xact.c.

3589 {
3590  /*
3591  * Return true on same conditions that would make
3592  * PreventInTransactionBlock error out
3593  */
3594  if (IsTransactionBlock())
3595  return true;
3596 
3597  if (IsSubTransaction())
3598  return true;
3599 
3600  if (!isTopLevel)
3601  return true;
3602 
3605  return true;
3606 
3607  /*
3608  * If we tell the caller we're not in a transaction block, then inform
3609  * postgres.c that it had better commit when the statement is done.
3610  * Otherwise our report could be a lie.
3611  */
3613 
3614  return false;
3615 }
int MyXactFlags
Definition: xact.c:135
#define XACT_FLAGS_NEEDIMMEDIATECOMMIT
Definition: xact.h:114

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

Referenced by vacuum().

◆ IsSubTransaction()

◆ IsSubxactTopXidLogPending()

bool IsSubxactTopXidLogPending ( void  )

Definition at line 549 of file xact.c.

550 {
551  /* check whether it is already logged */
553  return false;
554 
555  /* wal_level has to be logical */
556  if (!XLogLogicalInfoActive())
557  return false;
558 
559  /* we need to be in a transaction state */
560  if (!IsTransactionState())
561  return false;
562 
563  /* it has to be a subtransaction */
564  if (!IsSubTransaction())
565  return false;
566 
567  /* the subtransaction has to have a XID assigned */
569  return false;
570 
571  return true;
572 }
bool IsTransactionState(void)
Definition: xact.c:377
TransactionId GetCurrentTransactionIdIfAny(void)
Definition: xact.c:461

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

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

bool IsTransactionBlock ( void  )

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 377 of file xact.c.

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

References CurrentTransactionState, TransactionStateData::state, and TRANS_INPROGRESS.

Referenced by apply_handle_commit_internal(), apply_handle_origin(), apply_handle_stream_stop(), 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(), FetchTableStates(), InitializeClientEncoding(), IsSubxactTopXidLogPending(), LogicalRepApplyLoop(), LogLogicalMessage(), maybe_reread_subscription(), 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(), and SocketBackend().

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

◆ MarkSubxactTopXidLogged()

void MarkSubxactTopXidLogged ( void  )

Definition at line 581 of file xact.c.

582 {
584 
586 }
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:549

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

Referenced by XLogInsertRecord().

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5290 of file xact.c.

5291 {
5293 
5294  if (s->state != TRANS_DEFAULT)
5295  elog(WARNING, "PopTransaction while in %s state",
5297 
5298  if (s->parent == NULL)
5299  elog(FATAL, "PopTransaction with no parent");
5300 
5302 
5303  /* Let's just make sure CurTransactionContext is good */
5306 
5307  /* Ditto for ResourceOwner links */
5310 
5311  /* Free the old child structure */
5312  if (s->name)
5313  pfree(s->name);
5314  pfree(s);
5315 }

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

2401 {
2404  GlobalTransaction gxact;
2405  TimestampTz prepared_at;
2406 
2408 
2409  ShowTransactionState("PrepareTransaction");
2410 
2411  /*
2412  * check the current transaction state
2413  */
2414  if (s->state != TRANS_INPROGRESS)
2415  elog(WARNING, "PrepareTransaction while in %s state",
2417  Assert(s->parent == NULL);
2418 
2419  /*
2420  * Do pre-commit processing that involves calling user-defined code, such
2421  * as triggers. Since closing cursors could queue trigger actions,
2422  * triggers could open cursors, etc, we have to keep looping until there's
2423  * nothing left to do.
2424  */
2425  for (;;)
2426  {
2427  /*
2428  * Fire all currently pending deferred triggers.
2429  */
2431 
2432  /*
2433  * Close open portals (converting holdable ones into static portals).
2434  * If there weren't any, we are done ... otherwise loop back to check
2435  * if they queued deferred triggers. Lather, rinse, repeat.
2436  */
2437  if (!PreCommit_Portals(true))
2438  break;
2439  }
2440 
2442 
2443  /*
2444  * The remaining actions cannot call any user-defined code, so it's safe
2445  * to start shutting down within-transaction services. But note that most
2446  * of this stuff could still throw an error, which would switch us into
2447  * the transaction-abort path.
2448  */
2449 
2450  /* Shut down the deferred-trigger manager */
2451  AfterTriggerEndXact(true);
2452 
2453  /*
2454  * Let ON COMMIT management do its thing (must happen after closing
2455  * cursors, to avoid dangling-reference problems)
2456  */
2458 
2459  /*
2460  * Synchronize files that are created and not WAL-logged during this
2461  * transaction. This must happen before EndPrepare(), so that we don't see
2462  * committed-but-broken files after a crash and COMMIT PREPARED.
2463  */
2464  smgrDoPendingSyncs(true, false);
2465 
2466  /* close large objects before lower-level cleanup */
2467  AtEOXact_LargeObject(true);
2468 
2469  /* NOTIFY requires no work at this point */
2470 
2471  /*
2472  * Mark serializable transaction as complete for predicate locking
2473  * purposes. This should be done as late as we can put it and still allow
2474  * errors to be raised for failure patterns found at commit.
2475  */
2477 
2478  /*
2479  * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2480  * this transaction. Having the prepared xact hold locks on another
2481  * backend's temp table seems a bad idea --- for instance it would prevent
2482  * the backend from exiting. There are other problems too, such as how to
2483  * clean up the source backend's local buffers and ON COMMIT state if the
2484  * prepared xact includes a DROP of a temp table.
2485  *
2486  * Other objects types, like functions, operators or extensions, share the
2487  * same restriction as they should not be created, locked or dropped as
2488  * this can mess up with this session or even a follow-up session trying
2489  * to use the same temporary namespace.
2490  *
2491  * We must check this after executing any ON COMMIT actions, because they
2492  * might still access a temp relation.
2493  *
2494  * XXX In principle this could be relaxed to allow some useful special
2495  * cases, such as a temp table created and dropped all within the
2496  * transaction. That seems to require much more bookkeeping though.
2497  */
2499  ereport(ERROR,
2500  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2501  errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2502 
2503  /*
2504  * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2505  * supported if we added cleanup logic to twophase.c, but for now it
2506  * doesn't seem worth the trouble.
2507  */
2509  ereport(ERROR,
2510  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2511  errmsg("cannot PREPARE a transaction that has exported snapshots")));
2512 
2513  /* Prevent cancel/die interrupt while cleaning up */
2514  HOLD_INTERRUPTS();
2515 
2516  /*
2517  * set the current transaction state information appropriately during
2518  * prepare processing
2519  */
2520  s->state = TRANS_PREPARE;
2521 
2522  prepared_at = GetCurrentTimestamp();
2523 
2524  /* Tell bufmgr and smgr to prepare for commit */
2525  BufmgrCommit();
2526 
2527  /*
2528  * Reserve the GID for this transaction. This could fail if the requested
2529  * GID is invalid or already in use.
2530  */
2531  gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2532  GetUserId(), MyDatabaseId);
2533  prepareGID = NULL;
2534 
2535  /*
2536  * Collect data for the 2PC state file. Note that in general, no actual
2537  * state change should happen in the called modules during this step,
2538  * since it's still possible to fail before commit, and in that case we
2539  * want transaction abort to be able to clean up. (In particular, the
2540  * AtPrepare routines may error out if they find cases they cannot
2541  * handle.) State cleanup should happen in the PostPrepare routines
2542  * below. However, some modules can go ahead and clear state here because
2543  * they wouldn't do anything with it during abort anyway.
2544  *
2545  * Note: because the 2PC state file records will be replayed in the same
2546  * order they are made, the order of these calls has to match the order in
2547  * which we want things to happen during COMMIT PREPARED or ROLLBACK
2548  * PREPARED; in particular, pay attention to whether things should happen
2549  * before or after releasing the transaction's locks.
2550  */
2551  StartPrepare(gxact);
2552 
2553  AtPrepare_Notify();
2554  AtPrepare_Locks();
2556  AtPrepare_PgStat();
2559 
2560  /*
2561  * Here is where we really truly prepare.
2562  *
2563  * We have to record transaction prepares even if we didn't make any
2564  * updates, because the transaction manager might get confused if we lose
2565  * a global transaction.
2566  */
2567  EndPrepare(gxact);
2568 
2569  /*
2570  * Now we clean up backend-internal state and release internal resources.
2571  */
2572 
2573  /* Reset XactLastRecEnd until the next transaction writes something */
2574  XactLastRecEnd = 0;
2575 
2576  /*
2577  * Transfer our locks to a dummy PGPROC. This has to be done before
2578  * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2579  * conclude "xact already committed or aborted" for our locks.
2580  */
2581  PostPrepare_Locks(xid);
2582 
2583  /*
2584  * Let others know about no transaction in progress by me. This has to be
2585  * done *after* the prepared transaction has been marked valid, else
2586  * someone may think it is unlocked and recyclable.
2587  */
2589 
2590  /*
2591  * In normal commit-processing, this is all non-critical post-transaction
2592  * cleanup. When the transaction is prepared, however, it's important
2593  * that the locks and other per-backend resources are transferred to the
2594  * prepared transaction's PGPROC entry. Note that if an error is raised
2595  * here, it's too late to abort the transaction. XXX: This probably should
2596  * be in a critical section, to force a PANIC if any of this fails, but
2597  * that cure could be worse than the disease.
2598  */
2599 
2601 
2604  true, true);
2605 
2606  /* Check we've released all buffer pins */
2607  AtEOXact_Buffers(true);
2608 
2609  /* Clean up the relation cache */
2610  AtEOXact_RelationCache(true);
2611 
2612  /* notify doesn't need a postprepare call */
2613 
2615 
2617 
2618  PostPrepare_smgr();
2619 
2620  PostPrepare_MultiXact(xid);
2621 
2623 
2626  true, true);
2629  true, true);
2630 
2631  /*
2632  * Allow another backend to finish the transaction. After
2633  * PostPrepare_Twophase(), the transaction is completely detached from our
2634  * backend. The rest is just non-critical cleanup of backend-local state.
2635  */
2637 
2638  /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2639  AtEOXact_GUC(true, 1);
2640  AtEOXact_SPI(true);
2641  AtEOXact_Enum();
2643  AtEOXact_Namespace(true, false);
2644  AtEOXact_SMgr();
2645  AtEOXact_Files(true);
2647  AtEOXact_HashTables(true);
2648  /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2649  AtEOXact_Snapshot(true, true);
2651 
2652  CurrentResourceOwner = NULL;
2654  s->curTransactionOwner = NULL;
2657 
2658  AtCommit_Memory();
2659 
2662  s->nestingLevel = 0;
2663  s->gucNestLevel = 0;
2664  s->childXids = NULL;
2665  s->nChildXids = 0;
2666  s->maxChildXids = 0;
2667 
2670 
2671  /*
2672  * done with 1st phase commit processing, set current transaction state
2673  * back to default
2674  */
2675  s->state = TRANS_DEFAULT;
2676 
2678 }
void AtPrepare_Notify(void)
Definition: async.c:870
void BufmgrCommit(void)
Definition: bufmgr.c:2749
int64 TimestampTz
Definition: timestamp.h:39
Oid MyDatabaseId
Definition: globals.c:89
void PostPrepare_Inval(void)
Definition: inval.c:865
void AtPrepare_Locks(void)
Definition: lock.c:3321
void PostPrepare_Locks(TransactionId xid)
Definition: lock.c:3417
Oid GetUserId(void)
Definition: miscinit.c:497
void AtPrepare_MultiXact(void)
Definition: multixact.c:1714
void PostPrepare_MultiXact(TransactionId xid)
Definition: multixact.c:1728
void AtPrepare_PgStat(void)
Definition: pgstat_xact.c:190
void PostPrepare_PgStat(void)
Definition: pgstat_xact.c:210
void AtPrepare_PredicateLocks(void)
Definition: predicate.c:4920
void PostPrepare_PredicateLocks(TransactionId xid)
Definition: predicate.c:4996
void ProcArrayClearTransaction(PGPROC *proc)
Definition: procarray.c:909
void AtPrepare_RelationMap(void)
Definition: relmapper.c:588
bool XactHasExportedSnapshots(void)
Definition: snapmgr.c:1571
void PostPrepare_smgr(void)
Definition: storage.c:911
void EndPrepare(GlobalTransaction gxact)
Definition: twophase.c:1135
void StartPrepare(GlobalTransaction gxact)
Definition: twophase.c:1042
void PostPrepare_Twophase(void)
Definition: twophase.c:361
GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition: twophase.c:376
static char * prepareGID
Definition: xact.c:281
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:444
@ XACT_EVENT_PRE_PREPARE
Definition: xact.h:128
@ XACT_EVENT_PREPARE
Definition: xact.h:125
#define XACT_FLAGS_ACCESSEDTEMPNAMESPACE
Definition: xact.h:102

References AfterTriggerEndXact(), AfterTriggerFireDeferred(), Assert(), AtCommit_Memory(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_LargeObject(), 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(), BufmgrCommit(), CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, 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, TransStateAsString(), WARNING, XACT_EVENT_PRE_PREPARE, XACT_EVENT_PREPARE, XACT_FLAGS_ACCESSEDTEMPNAMESPACE, XactHasExportedSnapshots(), XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommand().

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char *  gid)

Definition at line 3818 of file xact.c.

3819 {
3820  TransactionState s;
3821  bool result;
3822 
3823  /* Set up to commit the current transaction */
3824  result = EndTransactionBlock(false);
3825 
3826  /* If successful, change outer tblock state to PREPARE */
3827  if (result)
3828  {
3830 
3831  while (s->parent != NULL)
3832  s = s->parent;
3833 
3834  if (s->blockState == TBLOCK_END)
3835  {
3836  /* Save GID where PrepareTransaction can find it again */
3838 
3840  }
3841  else
3842  {
3843  /*
3844  * ignore case where we are not in a transaction;
3845  * EndTransactionBlock already issued a warning.
3846  */
3849  /* Don't send back a PREPARE result tag... */
3850  result = false;
3851  }
3852  }
3853 
3854  return result;
3855 }
bool EndTransactionBlock(bool chain)
Definition: xact.c:3870

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

3470 {
3471  /*
3472  * xact block already started?
3473  */
3474  if (IsTransactionBlock())
3475  ereport(ERROR,
3476  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3477  /* translator: %s represents an SQL statement name */
3478  errmsg("%s cannot run inside a transaction block",
3479  stmtType)));
3480 
3481  /*
3482  * subtransaction?
3483  */
3484  if (IsSubTransaction())
3485  ereport(ERROR,
3486  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3487  /* translator: %s represents an SQL statement name */
3488  errmsg("%s cannot run inside a subtransaction",
3489  stmtType)));
3490 
3491  /*
3492  * inside a function call?
3493  */
3494  if (!isTopLevel)
3495  ereport(ERROR,
3496  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3497  /* translator: %s represents an SQL statement name */
3498  errmsg("%s cannot be executed from a function", stmtType)));
3499 
3500  /* If we got past IsTransactionBlock test, should be in default state */
3503  elog(FATAL, "cannot prevent transaction chain");
3504 
3505  /* All okay. Set the flag to make sure the right thing happens later. */
3507 }

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

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

5231 {
5233  TransactionState s;
5234 
5235  /*
5236  * We keep subtransaction state nodes in TopTransactionContext.
5237  */
5238  s = (TransactionState)
5240  sizeof(TransactionStateData));
5241 
5242  /*
5243  * Assign a subtransaction ID, watching out for counter wraparound.
5244  */
5247  {
5249  pfree(s);
5250  ereport(ERROR,
5251  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5252  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5253  }
5254 
5255  /*
5256  * We can now stack a minimally valid subtransaction without fear of
5257  * failure.
5258  */
5259  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5261  s->parent = p;
5262  s->nestingLevel = p->nestingLevel + 1;
5265  s->state = TRANS_DEFAULT;
5269  s->parallelModeLevel = 0;
5270  s->topXidLogged = false;
5271 
5273 
5274  /*
5275  * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5276  * with the subtransaction from here on out; in particular they should not
5277  * assume that it necessarily has a transaction context, resource owner,
5278  * or XID.
5279  */
5280 }
int NewGUCNestLevel(void)
Definition: guc.c:2183
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1037
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:618
TransactionStateData * TransactionState
Definition: xact.c:214
static SubTransactionId currentSubTransactionId
Definition: xact.c:259

References TransactionStateData::blockState, currentSubTransactionId, CurrentTransactionState, ereport, errcode(), errmsg(), ERROR, TransactionStateData::fullTransactionId, GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, MemoryContextAllocZero(), TransactionStateData::nestingLevel, NewGUCNestLevel(), TransactionStateData::parallelModeLevel, TransactionStateData::parent, pfree(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, TransactionStateData::prevXactReadOnly, TransactionStateData::savepointLevel, 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 1704 of file xact.c.

1705 {
1707  TransactionId latestXid;
1708  int nrels;
1709  RelFileLocator *rels;
1710  int ndroppedstats = 0;
1711  xl_xact_stats_item *droppedstats = NULL;
1712  int nchildren;
1713  TransactionId *children;
1714  TimestampTz xact_time;
1715 
1716  /*
1717  * If we haven't been assigned an XID, nobody will care whether we aborted
1718  * or not. Hence, we're done in that case. It does not matter if we have
1719  * rels to delete (note that this routine is not responsible for actually
1720  * deleting 'em). We cannot have any child XIDs, either.
1721  */
1722  if (!TransactionIdIsValid(xid))
1723  {
1724  /* Reset XactLastRecEnd until the next transaction writes something */
1725  if (!isSubXact)
1726  XactLastRecEnd = 0;
1727  return InvalidTransactionId;
1728  }
1729 
1730  /*
1731  * We have a valid XID, so we should write an ABORT record for it.
1732  *
1733  * We do not flush XLOG to disk here, since the default assumption after a
1734  * crash would be that we aborted, anyway. For the same reason, we don't
1735  * need to worry about interlocking against checkpoint start.
1736  */
1737 
1738  /*
1739  * Check that we haven't aborted halfway through RecordTransactionCommit.
1740  */
1741  if (TransactionIdDidCommit(xid))
1742  elog(PANIC, "cannot abort transaction %u, it was already committed",
1743  xid);
1744 
1745  /* Fetch the data we need for the abort record */
1746  nrels = smgrGetPendingDeletes(false, &rels);
1747  nchildren = xactGetCommittedChildren(&children);
1748  ndroppedstats = pgstat_get_transactional_drops(false, &droppedstats);
1749 
1750  /* XXX do we really need a critical section here? */
1752 
1753  /* Write the ABORT record */
1754  if (isSubXact)
1755  xact_time = GetCurrentTimestamp();
1756  else
1757  {
1758  xact_time = GetCurrentTransactionStopTimestamp();
1759  }
1760 
1761  XactLogAbortRecord(xact_time,
1762  nchildren, children,
1763  nrels, rels,
1764  ndroppedstats, droppedstats,
1766  NULL);
1767 
1768  /*
1769  * Report the latest async abort LSN, so that the WAL writer knows to
1770  * flush this abort. There's nothing to be gained by delaying this, since
1771  * WALWriter may as well do this when it can. This is important with
1772  * streaming replication because if we don't flush WAL regularly we will
1773  * find that large aborts leave us with a long backlog for when commits
1774  * occur after the abort, increasing our window of data loss should
1775  * problems occur at that point.
1776  */
1777  if (!isSubXact)
1779 
1780  /*
1781  * Mark the transaction aborted in clog. This is not absolutely necessary
1782  * but we may as well do it while we are here; also, in the subxact case
1783  * it is helpful because XactLockTableWait makes use of it to avoid
1784  * waiting for already-aborted subtransactions. It is OK to do it without
1785  * having flushed the ABORT record to disk, because in event of a crash
1786  * we'd be assumed to have aborted anyway.
1787  */
1788  TransactionIdAbortTree(xid, nchildren, children);
1789 
1790  END_CRIT_SECTION();
1791 
1792  /* Compute latestXid while we have the child XIDs handy */
1793  latestXid = TransactionIdLatest(xid, nchildren, children);
1794 
1795  /*
1796  * If we're aborting a subtransaction, we can immediately remove failed
1797  * XIDs from PGPROC's cache of running child XIDs. We do that here for
1798  * subxacts, because we already have the child XID array at hand. For
1799  * main xacts, the equivalent happens just after this function returns.
1800  */
1801  if (isSubXact)
1802  XidCacheRemoveRunningXids(xid, nchildren, children, latestXid);
1803 
1804  /* Reset XactLastRecEnd until the next transaction writes something */
1805  if (!isSubXact)
1806  XactLastRecEnd = 0;
1807 
1808  /* And clean up local data */
1809  if (rels)
1810  pfree(rels);
1811  if (ndroppedstats)
1812  pfree(droppedstats);
1813 
1814  return latestXid;
1815 }
#define PANIC
Definition: elog.h:38
#define START_CRIT_SECTION()
Definition: miscadmin.h:148
#define END_CRIT_SECTION()
Definition: miscadmin.h:150
int pgstat_get_transactional_drops(bool isCommit, xl_xact_stats_item **items)
Definition: pgstat_xact.c:271
void XidCacheRemoveRunningXids(TransactionId xid, int nxids, const TransactionId *xids, TransactionId latestXid)
Definition: procarray.c:3950
int smgrGetPendingDeletes(bool forCommit, RelFileLocator **ptr)
Definition: storage.c:870
TransactionId TransactionIdLatest(TransactionId mainxid, int nxids, const TransactionId *xids)
Definition: transam.c:338
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
void TransactionIdAbortTree(TransactionId xid, int nxids, TransactionId *xids)
Definition: transam.c:263
int xactGetCommittedChildren(TransactionId **ptr)
Definition: xact.c:5593
TimestampTz GetCurrentTransactionStopTimestamp(void)
Definition: xact.c:875
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:5789

References elog(), END_CRIT_SECTION, GetCurrentTimestamp(), GetCurrentTransactionIdIfAny(), GetCurrentTransactionStopTimestamp(), InvalidTransactionId, MyXactFlags, PANIC, pfree(), pgstat_get_transactional_drops(), 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 1282 of file xact.c.

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

References Assert(), BufmgrCommit(), 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 3690 of file xact.c.

3691 {
3692  SubXactCallbackItem *item;
3693 
3694  item = (SubXactCallbackItem *)
3696  item->callback = callback;
3697  item->arg = arg;