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/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 state)
 
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)
 
static void SetCurrentTransactionStopTimestamp (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 (void)
 
void RestoreTransactionCharacteristics (void)
 
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, RelFileNode *rels, 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, RelFileNode *rels, 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
 
bool DefaultXactReadOnly = false
 
bool XactReadOnly
 
bool DefaultXactDeferrable = false
 
bool XactDeferrable
 
int synchronous_commit = SYNCHRONOUS_COMMIT_ON
 
TransactionId CheckXidAlive = InvalidTransactionId
 
bool bsysscan = false
 
FullTransactionId XactTopFullTransactionId = {InvalidTransactionId}
 
int nParallelCurrentXids = 0
 
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
 
static int save_XactIsoLevel
 
static bool save_XactReadOnly
 
static bool save_XactDeferrable
 

Macro Definition Documentation

◆ SerializedTransactionStateHeaderSize

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)

Definition at line 231 of file xact.c.

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

typedef enum TBlockState TBlockState

◆ TransactionState

Definition at line 213 of file xact.c.

◆ TransactionStateData

◆ TransState

typedef enum TransState TransState

◆ XactCallbackItem

Enumeration Type Documentation

◆ TBlockState

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

Definition at line 155 of file xact.c.

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

◆ TransState

enum TransState
Enumerator
TRANS_DEFAULT 
TRANS_START 
TRANS_INPROGRESS 
TRANS_COMMIT 
TRANS_ABORT 
TRANS_PREPARE 

Definition at line 139 of file xact.c.

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

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3281 of file xact.c.

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

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_rollback(), AutoVacLauncherMain(), PostgresMain(), ReorderBufferImmediateInvalidation(), ReorderBufferProcessTXN(), and SnapBuildClearExportedSnapshot().

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4650 of file xact.c.

4651 {
4653 
4654  /* Ensure we're not running in a doomed memory context */
4655  AtAbort_Memory();
4656 
4657  /*
4658  * Get out of any transaction or nested transaction
4659  */
4660  do
4661  {
4662  switch (s->blockState)
4663  {
4664  case TBLOCK_DEFAULT:
4665  if (s->state == TRANS_DEFAULT)
4666  {
4667  /* Not in a transaction, do nothing */
4668  }
4669  else
4670  {
4671  /*
4672  * We can get here after an error during transaction start
4673  * (state will be TRANS_START). Need to clean up the
4674  * incompletely started transaction. First, adjust the
4675  * low-level state to suppress warning message from
4676  * AbortTransaction.
4677  */
4678  if (s->state == TRANS_START)
4679  s->state = TRANS_INPROGRESS;
4680  AbortTransaction();
4682  }
4683  break;
4684  case TBLOCK_STARTED:
4685  case TBLOCK_BEGIN:
4686  case TBLOCK_INPROGRESS:
4689  case TBLOCK_END:
4690  case TBLOCK_ABORT_PENDING:
4691  case TBLOCK_PREPARE:
4692  /* In a transaction, so clean up */
4693  AbortTransaction();
4696  break;
4697  case TBLOCK_ABORT:
4698  case TBLOCK_ABORT_END:
4699 
4700  /*
4701  * AbortTransaction is already done, still need Cleanup.
4702  * However, if we failed partway through running ROLLBACK,
4703  * there will be an active portal running that command, which
4704  * we need to shut down before doing CleanupTransaction.
4705  */
4706  AtAbort_Portals();
4709  break;
4710 
4711  /*
4712  * In a subtransaction, so clean it up and abort parent too
4713  */
4714  case TBLOCK_SUBBEGIN:
4715  case TBLOCK_SUBINPROGRESS:
4716  case TBLOCK_SUBRELEASE:
4717  case TBLOCK_SUBCOMMIT:
4719  case TBLOCK_SUBRESTART:
4722  s = CurrentTransactionState; /* changed by pop */
4723  break;
4724 
4725  case TBLOCK_SUBABORT:
4726  case TBLOCK_SUBABORT_END:
4728  /* As above, but AbortSubTransaction already done */
4729  if (s->curTransactionOwner)
4730  {
4731  /* As in TBLOCK_ABORT, might have a live portal to zap */
4736  }
4738  s = CurrentTransactionState; /* changed by pop */
4739  break;
4740  }
4741  } while (s->blockState != TBLOCK_DEFAULT);
4742 
4743  /* Should be out of all subxacts now */
4744  Assert(s->parent == NULL);
4745 
4746  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4747  AtCleanup_Memory();
4748 }
Assert(fmt[strlen(fmt) - 1] !='\n')
void AtAbort_Portals(void)
Definition: portalmem.c:781
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:979
SubTransactionId subTransactionId
Definition: xact.c:190
struct TransactionStateData * parent
Definition: xact.c:210
ResourceOwner curTransactionOwner
Definition: xact.c:198
static void AtCleanup_Memory(void)
Definition: xact.c:1895
static void AtAbort_Memory(void)
Definition: xact.c:1805

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 do_autovacuum(), perform_work_item(), RemoveTempRelationsCallback(), and ShutdownPostgres().

◆ AbortSubTransaction()

static void AbortSubTransaction ( void  )
static

Definition at line 4996 of file xact.c.

4997 {
4999 
5000  /* Prevent cancel/die interrupt while cleaning up */
5001  HOLD_INTERRUPTS();
5002 
5003  /* Make sure we have a valid memory context and resource owner */
5006 
5007  /*
5008  * Release any LW locks we might be holding as quickly as possible.
5009  * (Regular locks, however, must be held till we finish aborting.)
5010  * Releasing LW locks is critical since we might try to grab them again
5011  * while cleaning up!
5012  *
5013  * FIXME This may be incorrect --- Are there some locks we should keep?
5014  * Buffer locks, for example? I don't think so but I'm not sure.
5015  */
5016  LWLockReleaseAll();
5017 
5020  AbortBufferIO();
5021  UnlockBuffers();
5022 
5023  /* Reset WAL record construction state */
5025 
5026  /* Cancel condition variable sleep */
5028 
5029  /*
5030  * Also clean up any open wait for lock, since the lock manager will choke
5031  * if we try to wait for another lock before doing this.
5032  */
5033  LockErrorCleanup();
5034 
5035  /*
5036  * If any timeout events are still active, make sure the timeout interrupt
5037  * is scheduled. This covers possible loss of a timeout interrupt due to
5038  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5039  * We delay this till after LockErrorCleanup so that we don't uselessly
5040  * reschedule lock or deadlock check timeouts.
5041  */
5043 
5044  /*
5045  * Re-enable signals, in case we got here by longjmp'ing out of a signal
5046  * handler. We do this fairly early in the sequence so that the timeout
5047  * infrastructure will be functional if needed while aborting.
5048  */
5050 
5051  /*
5052  * check the current transaction state
5053  */
5054  ShowTransactionState("AbortSubTransaction");
5055 
5056  if (s->state != TRANS_INPROGRESS)
5057  elog(WARNING, "AbortSubTransaction while in %s state",
5059 
5060  s->state = TRANS_ABORT;
5061 
5062  /*
5063  * Reset user ID which might have been changed transiently. (See notes in
5064  * AbortTransaction.)
5065  */
5067 
5068  /* Forget about any active REINDEX. */
5070 
5071  /* Reset logical streaming state. */
5073 
5074  /*
5075  * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5076  * exports are not supported in subtransactions.
5077  */
5078 
5079  /* Exit from parallel mode, if necessary. */
5080  if (IsInParallelMode())
5081  {
5083  s->parallelModeLevel = 0;
5084  }
5085 
5086  /*
5087  * We can skip all this stuff if the subxact failed before creating a
5088  * ResourceOwner...
5089  */
5090  if (s->curTransactionOwner)
5091  {
5092  AfterTriggerEndSubXact(false);
5098  s->parent->subTransactionId);
5100 
5101  /* Advertise the fact that we aborted in pg_xact. */
5102  (void) RecordTransactionAbort(true);
5103 
5104  /* Post-abort cleanup */
5107 
5109  s->parent->subTransactionId);
5110 
5113  false, false);
5115  s->parent->subTransactionId);
5116  AtEOSubXact_Inval(false);
5119  false, false);
5122  false, false);
5123  AtSubAbort_smgr();
5124 
5125  AtEOXact_GUC(false, s->gucNestLevel);
5126  AtEOSubXact_SPI(false, s->subTransactionId);
5128  s->parent->subTransactionId);
5130  s->parent->subTransactionId);
5132  s->parent->subTransactionId);
5134  AtEOSubXact_PgStat(false, s->nestingLevel);
5136  }
5137 
5138  /*
5139  * Restore the upper transaction's read-only state, too. This should be
5140  * redundant with GUC's cleanup but we may as well do it for consistency
5141  * with the commit case.
5142  */
5144 
5146 }
void AtSubAbort_Notify(void)
Definition: async.c:1810
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition: parallel.c:1215
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:629
void UnlockBuffers(void)
Definition: bufmgr.c:3979
void AbortBufferIO(void)
Definition: bufmgr.c:4477
void ConditionVariableCancelSleep(void)
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1909
#define WARNING
Definition: elog.h:30
#define elog(elevel,...)
Definition: elog.h:218
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:3011
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:6256
void ResetReindexState(int nestLevel)
Definition: index.c:4052
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1084
void ResetLogicalStreamingState(void)
Definition: logical.c:1794
void LWLockReleaseAll(void)
Definition: lwlock.c:1902
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:133
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:131
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:607
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: namespace.c:4177
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat.c:2694
#define PG_SETMASK(mask)
Definition: pqsignal.h:19
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3308
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:985
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition: spi.c:390
void LockErrorCleanup(void)
Definition: proc.c:716
void AtSubAbort_smgr(void)
Definition: storage.c:914
int parallelModeLevel
Definition: xact.c:207
FullTransactionId fullTransactionId
Definition: xact.c:189
bool prevXactReadOnly
Definition: xact.c:204
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:16499
void reschedule_timeouts(void)
Definition: timeout.c:531
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:4988
static void pgstat_report_wait_end(void)
Definition: wait_event.h:278
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3687
static void AtSubAbort_Memory(void)
Definition: xact.c:1825
static const char * TransStateAsString(TransState state)
Definition: xact.c:5520
bool XactReadOnly
Definition: xact.c:80
static void AtSubAbort_childXids(void)
Definition: xact.c:1863
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1850
static void ShowTransactionState(const char *str)
Definition: xact.c:5417
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1693
bool IsInParallelMode(void)
Definition: xact.c:1064
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:131
void XLogResetInsertion(void)
Definition: xloginsert.c:209

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

2670 {
2672  TransactionId latestXid;
2673  bool is_parallel_worker;
2674 
2675  /* Prevent cancel/die interrupt while cleaning up */
2676  HOLD_INTERRUPTS();
2677 
2678  /* Make sure we have a valid memory context and resource owner */
2679  AtAbort_Memory();
2681 
2682  /*
2683  * Release any LW locks we might be holding as quickly as possible.
2684  * (Regular locks, however, must be held till we finish aborting.)
2685  * Releasing LW locks is critical since we might try to grab them again
2686  * while cleaning up!
2687  */
2688  LWLockReleaseAll();
2689 
2690  /* Clear wait information and command progress indicator */
2693 
2694  /* Clean up buffer I/O and buffer context locks, too */
2695  AbortBufferIO();
2696  UnlockBuffers();
2697 
2698  /* Reset WAL record construction state */
2700 
2701  /* Cancel condition variable sleep */
2703 
2704  /*
2705  * Also clean up any open wait for lock, since the lock manager will choke
2706  * if we try to wait for another lock before doing this.
2707  */
2708  LockErrorCleanup();
2709 
2710  /*
2711  * If any timeout events are still active, make sure the timeout interrupt
2712  * is scheduled. This covers possible loss of a timeout interrupt due to
2713  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2714  * We delay this till after LockErrorCleanup so that we don't uselessly
2715  * reschedule lock or deadlock check timeouts.
2716  */
2718 
2719  /*
2720  * Re-enable signals, in case we got here by longjmp'ing out of a signal
2721  * handler. We do this fairly early in the sequence so that the timeout
2722  * infrastructure will be functional if needed while aborting.
2723  */
2725 
2726  /*
2727  * check the current transaction state
2728  */
2729  is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2730  if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2731  elog(WARNING, "AbortTransaction while in %s state",
2733  Assert(s->parent == NULL);
2734 
2735  /*
2736  * set the current transaction state information appropriately during the
2737  * abort processing
2738  */
2739  s->state = TRANS_ABORT;
2740 
2741  /*
2742  * Reset user ID which might have been changed transiently. We need this
2743  * to clean up in case control escaped out of a SECURITY DEFINER function
2744  * or other local change of CurrentUserId; therefore, the prior value of
2745  * SecurityRestrictionContext also needs to be restored.
2746  *
2747  * (Note: it is not necessary to restore session authorization or role
2748  * settings here because those can only be changed via GUC, and GUC will
2749  * take care of rolling them back if need be.)
2750  */
2752 
2753  /* Forget about any active REINDEX. */
2755 
2756  /* Reset logical streaming state. */
2758 
2759  /* Reset snapshot export state. */
2761 
2762  /* If in parallel mode, clean up workers and exit parallel mode. */
2763  if (IsInParallelMode())
2764  {
2765  AtEOXact_Parallel(false);
2766  s->parallelModeLevel = 0;
2767  }
2768 
2769  /*
2770  * do abort processing
2771  */
2772  AfterTriggerEndXact(false); /* 'false' means it's abort */
2773  AtAbort_Portals();
2774  smgrDoPendingSyncs(false, is_parallel_worker);
2775  AtEOXact_LargeObject(false);
2776  AtAbort_Notify();
2777  AtEOXact_RelationMap(false, is_parallel_worker);
2778  AtAbort_Twophase();
2779 
2780  /*
2781  * Advertise the fact that we aborted in pg_xact (assuming that we got as
2782  * far as assigning an XID to advertise). But if we're inside a parallel
2783  * worker, skip this; the user backend must be the one to write the abort
2784  * record.
2785  */
2786  if (!is_parallel_worker)
2787  latestXid = RecordTransactionAbort(false);
2788  else
2789  {
2790  latestXid = InvalidTransactionId;
2791 
2792  /*
2793  * Since the parallel leader won't get our value of XactLastRecEnd in
2794  * this case, we nudge WAL-writer ourselves in this case. See related
2795  * comments in RecordTransactionAbort for why this matters.
2796  */
2798  }
2799 
2800  TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->lxid);
2801 
2802  /*
2803  * Let others know about no transaction in progress by me. Note that this
2804  * must be done _before_ releasing locks we hold and _after_
2805  * RecordTransactionAbort.
2806  */
2807  ProcArrayEndTransaction(MyProc, latestXid);
2808 
2809  /*
2810  * Post-abort cleanup. See notes in CommitTransaction() concerning
2811  * ordering. We can skip all of it if the transaction failed before
2812  * creating a resource owner.
2813  */
2814  if (TopTransactionResourceOwner != NULL)
2815  {
2816  if (is_parallel_worker)
2818  else
2820 
2823  false, true);
2824  AtEOXact_Buffers(false);
2825  AtEOXact_RelationCache(false);
2826  AtEOXact_Inval(false);
2830  false, true);
2833  false, true);
2834  smgrDoPendingDeletes(false);
2835 
2836  AtEOXact_GUC(false, 1);
2837  AtEOXact_SPI(false);
2838  AtEOXact_Enum();
2840  AtEOXact_Namespace(false, is_parallel_worker);
2841  AtEOXact_SMgr();
2842  AtEOXact_Files(false);
2844  AtEOXact_HashTables(false);
2845  AtEOXact_PgStat(false, is_parallel_worker);
2846  AtEOXact_ApplyLauncher(false);
2848  }
2849 
2850  /*
2851  * State remains TRANS_ABORT until CleanupTransaction().
2852  */
2854 }
void AtAbort_Notify(void)
Definition: async.c:1720
void AtEOXact_Parallel(bool isCommit)
Definition: parallel.c:1234
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition: be-fsstubs.c:583
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:2579
uint32 TransactionId
Definition: c.h:587
void AtEOXact_ComboCid(void)
Definition: combocid.c:182
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1883
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3044
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1027
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:4109
void AtEOXact_Enum(void)
Definition: pg_enum.c:609
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition: pgstat.c:2582
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:654
void AtEOXact_RelationCache(bool isCommit)
Definition: relcache.c:3156
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition: relmapper.c:476
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:148
void AtEOXact_SMgr(void)
Definition: smgr.c:678
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:710
void AtEOXact_SPI(bool isCommit)
Definition: spi.c:368
PGPROC * MyProc
Definition: proc.c:68
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:680
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:612
LocalTransactionId lxid
Definition: proc.h:146
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:16467
#define InvalidTransactionId
Definition: transam.h:31
void AfterTriggerEndXact(bool isCommit)
Definition: trigger.c:4892
void AtAbort_Twophase(void)
Definition: twophase.c:317
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1837
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3632
@ XACT_EVENT_ABORT
Definition: xact.h:117
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:118
XLogRecPtr XactLastRecEnd
Definition: xlog.c:343
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2753

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

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

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

1806 {
1807  /*
1808  * Switch into TransactionAbortContext, which should have some free space
1809  * even if nothing else does. We'll work in this context until we've
1810  * finished cleaning up.
1811  *
1812  * It is barely possible to get here when we've not been able to create
1813  * TransactionAbortContext yet; if so use TopMemoryContext.
1814  */
1815  if (TransactionAbortContext != NULL)
1817  else
1819 }
MemoryContext TopMemoryContext
Definition: mcxt.c:48
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
static MemoryContext TransactionAbortContext
Definition: xact.c:292

References MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1837 of file xact.c.

1838 {
1839  /*
1840  * Make sure we have a valid ResourceOwner, if possible (else it will be
1841  * NULL, which is OK)
1842  */
1844 }

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1528 of file xact.c.

1529 {
1530  /*
1531  * Make any pending relation map changes visible. We must do this before
1532  * processing local sinval messages, so that the map changes will get
1533  * reflected into the relcache when relcache invals are processed.
1534  */
1536 
1537  /*
1538  * Make catalog changes visible to me for the next command.
1539  */
1541 }
void CommandEndInvalidationMessages(void)
Definition: inval.c:1172
void AtCCI_RelationMap(void)
Definition: relmapper.c:439

References AtCCI_RelationMap(), and CommandEndInvalidationMessages().

Referenced by CommandCounterIncrement().

◆ AtCleanup_Memory()

static void AtCleanup_Memory ( void  )
static

Definition at line 1895 of file xact.c.

1896 {
1898 
1899  /*
1900  * Now that we're "out" of a transaction, have the system allocate things
1901  * in the top memory context instead of per-transaction contexts.
1902  */
1904 
1905  /*
1906  * Clear the special abort context for next time.
1907  */
1908  if (TransactionAbortContext != NULL)
1910 
1911  /*
1912  * Release all transaction-local memory.
1913  */
1914  if (TopTransactionContext != NULL)
1916  TopTransactionContext = NULL;
1917  CurTransactionContext = NULL;
1919 }
MemoryContext TopTransactionContext
Definition: mcxt.c:53
MemoryContext CurTransactionContext
Definition: mcxt.c:54
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:218
#define MemoryContextResetAndDeleteChildren(ctx)
Definition: memutils.h:67
MemoryContext curTransactionContext
Definition: xact.c:197

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

1548 {
1549  /*
1550  * Now that we're "out" of a transaction, have the system allocate things
1551  * in the top memory context instead of per-transaction contexts.
1552  */
1554 
1555  /*
1556  * Release all transaction-local memory.
1557  */
1558  Assert(TopTransactionContext != NULL);
1560  TopTransactionContext = NULL;
1561  CurTransactionContext = NULL;
1563 }

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

1139 {
1141 }
void AcceptInvalidationMessages(void)
Definition: inval.c:745

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1147 of file xact.c.

1148 {
1150 
1151  /*
1152  * If this is the first time through, create a private context for
1153  * AbortTransaction to work in. By reserving some space now, we can
1154  * insulate AbortTransaction from out-of-memory scenarios. Like
1155  * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1156  * size, so that space will be reserved immediately.
1157  */
1158  if (TransactionAbortContext == NULL)
1161  "TransactionAbortContext",
1162  32 * 1024,
1163  32 * 1024,
1164  32 * 1024);
1165 
1166  /*
1167  * We shouldn't have a transaction context already.
1168  */
1169  Assert(TopTransactionContext == NULL);
1170 
1171  /*
1172  * Create a toplevel context for the transaction.
1173  */
1176  "TopTransactionContext",
1178 
1179  /*
1180  * In a top-level transaction, CurTransactionContext is the same as
1181  * TopTransactionContext.
1182  */
1185 
1186  /* Make the CurTransactionContext active. */
1188 }
#define AllocSetContextCreate
Definition: memutils.h:173
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:195

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

1195 {
1197 
1198  /*
1199  * We shouldn't have a transaction resource owner already.
1200  */
1202 
1203  /*
1204  * Create a toplevel resource owner for the transaction.
1205  */
1206  s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1207 
1211 }
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 1863 of file xact.c.

1864 {
1866 
1867  /*
1868  * We keep the child-XID arrays in TopTransactionContext (see
1869  * AtSubCommit_childXids). This means we'd better free the array
1870  * explicitly at abort to avoid leakage.
1871  */
1872  if (s->childXids != NULL)
1873  pfree(s->childXids);
1874  s->childXids = NULL;
1875  s->nChildXids = 0;
1876  s->maxChildXids = 0;
1877 
1878  /*
1879  * We could prune the unreportedXids array here. But we don't bother. That
1880  * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1881  * would likely introduce more CPU time into the more common paths, so we
1882  * choose not to do that.
1883  */
1884 }
TransactionId * childXids
Definition: xact.c:199

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

Definition at line 1825 of file xact.c.

1826 {
1828 
1830 }

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1850 of file xact.c.

1851 {
1853 
1854  /* Make sure we have a valid ResourceOwner */
1856 }

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 1931 of file xact.c.

1932 {
1934 
1935  Assert(s->parent != NULL);
1936 
1937  /* Make sure we're not in an about-to-be-deleted context */
1940 
1941  /*
1942  * Clear the special abort context for next time.
1943  */
1944  if (TransactionAbortContext != NULL)
1946 
1947  /*
1948  * Delete the subxact local memory contexts. Its CurTransactionContext can
1949  * go too (note this also kills CurTransactionContexts from any children
1950  * of the subxact).
1951  */
1952  if (s->curTransactionContext)
1954  s->curTransactionContext = NULL;
1955 }

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

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

1575 {
1577 
1578  Assert(s->parent != NULL);
1579 
1580  /* Return to parent transaction level's memory context. */
1583 
1584  /*
1585  * Ordinarily we cannot throw away the child's CurTransactionContext,
1586  * since the data it contains will be needed at upper commit. However, if
1587  * there isn't actually anything in it, we can throw it away. This avoids
1588  * a small memory leak in the common case of "trivial" subxacts.
1589  */
1591  {
1593  s->curTransactionContext = NULL;
1594  }
1595 }
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:458

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

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

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

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

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

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4110 of file xact.c.

4111 {
4113 
4114  /*
4115  * If we are in STARTED state (that is, no transaction block is open),
4116  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4117  * block.
4118  *
4119  * For caller convenience, we consider all other transaction states as
4120  * legal here; otherwise the caller would need its own state check, which
4121  * seems rather pointless.
4122  */
4123  if (s->blockState == TBLOCK_STARTED)
4125 }

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

Referenced by exec_simple_query().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4478 of file xact.c.

4479 {
4481 
4482  /*
4483  * Workers synchronize transaction state at the beginning of each parallel
4484  * operation, so we can't account for new subtransactions after that
4485  * point. We might be able to make an exception for the type of
4486  * subtransaction established by this function, which is typically used in
4487  * contexts where we're going to release or roll back the subtransaction
4488  * before proceeding further, so that no enduring change to the
4489  * transaction state occurs. For now, however, we prohibit this case along
4490  * with all the others.
4491  */
4492  if (IsInParallelMode())
4493  ereport(ERROR,
4494  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4495  errmsg("cannot start subtransactions during a parallel operation")));
4496 
4497  switch (s->blockState)
4498  {
4499  case TBLOCK_STARTED:
4500  case TBLOCK_INPROGRESS:
4502  case TBLOCK_END:
4503  case TBLOCK_PREPARE:
4504  case TBLOCK_SUBINPROGRESS:
4505  /* Normal subtransaction start */
4506  PushTransaction();
4507  s = CurrentTransactionState; /* changed by push */
4508 
4509  /*
4510  * Savepoint names, like the TransactionState block itself, live
4511  * in TopTransactionContext.
4512  */
4513  if (name)
4515  break;
4516 
4517  /* These cases are invalid. */
4518  case TBLOCK_DEFAULT:
4519  case TBLOCK_BEGIN:
4521  case TBLOCK_SUBBEGIN:
4522  case TBLOCK_SUBRELEASE:
4523  case TBLOCK_SUBCOMMIT:
4524  case TBLOCK_ABORT:
4525  case TBLOCK_SUBABORT:
4526  case TBLOCK_ABORT_END:
4527  case TBLOCK_SUBABORT_END:
4528  case TBLOCK_ABORT_PENDING:
4530  case TBLOCK_SUBRESTART:
4532  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4534  break;
4535  }
4536 
4539 }
#define FATAL
Definition: elog.h:35
const char * name
Definition: encode.c:561
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1286
static void PushTransaction(void)
Definition: xact.c:5188
void StartTransactionCommand(void)
Definition: xact.c:2909
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5467
void CommitTransactionCommand(void)
Definition: xact.c:3010

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

3709 {
3711 
3712  switch (s->blockState)
3713  {
3714  /*
3715  * We are not inside a transaction block, so allow one to begin.
3716  */
3717  case TBLOCK_STARTED:
3718  s->blockState = TBLOCK_BEGIN;
3719  break;
3720 
3721  /*
3722  * BEGIN converts an implicit transaction block to a regular one.
3723  * (Note that we allow this even if we've already done some
3724  * commands, which is a bit odd but matches historical practice.)
3725  */
3727  s->blockState = TBLOCK_BEGIN;
3728  break;
3729 
3730  /*
3731  * Already a transaction block in progress.
3732  */
3733  case TBLOCK_INPROGRESS:
3735  case TBLOCK_SUBINPROGRESS:
3736  case TBLOCK_ABORT:
3737  case TBLOCK_SUBABORT:
3738  ereport(WARNING,
3739  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3740  errmsg("there is already a transaction in progress")));
3741  break;
3742 
3743  /* These cases are invalid. */
3744  case TBLOCK_DEFAULT:
3745  case TBLOCK_BEGIN:
3746  case TBLOCK_SUBBEGIN:
3747  case TBLOCK_END:
3748  case TBLOCK_SUBRELEASE:
3749  case TBLOCK_SUBCOMMIT:
3750  case TBLOCK_ABORT_END:
3751  case TBLOCK_SUBABORT_END:
3752  case TBLOCK_ABORT_PENDING:
3754  case TBLOCK_SUBRESTART:
3756  case TBLOCK_PREPARE:
3757  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3759  break;
3760  }
3761 }

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

5468 {
5469  switch (blockState)
5470  {
5471  case TBLOCK_DEFAULT:
5472  return "DEFAULT";
5473  case TBLOCK_STARTED:
5474  return "STARTED";
5475  case TBLOCK_BEGIN:
5476  return "BEGIN";
5477  case TBLOCK_INPROGRESS:
5478  return "INPROGRESS";
5480  return "IMPLICIT_INPROGRESS";
5482  return "PARALLEL_INPROGRESS";
5483  case TBLOCK_END:
5484  return "END";
5485  case TBLOCK_ABORT:
5486  return "ABORT";
5487  case TBLOCK_ABORT_END:
5488  return "ABORT_END";
5489  case TBLOCK_ABORT_PENDING:
5490  return "ABORT_PENDING";
5491  case TBLOCK_PREPARE:
5492  return "PREPARE";
5493  case TBLOCK_SUBBEGIN:
5494  return "SUBBEGIN";
5495  case TBLOCK_SUBINPROGRESS:
5496  return "SUBINPROGRESS";
5497  case TBLOCK_SUBRELEASE:
5498  return "SUBRELEASE";
5499  case TBLOCK_SUBCOMMIT:
5500  return "SUBCOMMIT";
5501  case TBLOCK_SUBABORT:
5502  return "SUBABORT";
5503  case TBLOCK_SUBABORT_END:
5504  return "SUBABORT_END";
5506  return "SUBABORT_PENDING";
5507  case TBLOCK_SUBRESTART:
5508  return "SUBRESTART";
5510  return "SUBABORT_RESTART";
5511  }
5512  return "UNRECOGNIZED";
5513 }

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

3690 {
3691  SubXactCallbackItem *item;
3692 
3693  for (item = SubXact_callbacks; item; item = item->next)
3694  item->callback(event, mySubid, parentSubid, item->arg);
3695 }
struct SubXactCallbackItem * next
Definition: xact.c:311
SubXactCallback callback
Definition: xact.c:312
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:316

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

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

◆ CallXactCallbacks()

static void CallXactCallbacks ( XactEvent  event)
static

Definition at line 3632 of file xact.c.

3633 {
3634  XactCallbackItem *item;
3635 
3636  for (item = Xact_callbacks; item; item = item->next)
3637  item->callback(event, item->arg);
3638 }
struct XactCallbackItem * next
Definition: xact.c:299
void * arg
Definition: xact.c:301
XactCallback callback
Definition: xact.c:300
static XactCallbackItem * Xact_callbacks
Definition: xact.c:304

References XactCallbackItem::arg, XactCallbackItem::callback, 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 3525 of file xact.c.

3526 {
3527  /*
3528  * xact block already started?
3529  */
3530  if (IsTransactionBlock())
3531  return;
3532 
3533  /*
3534  * subtransaction?
3535  */
3536  if (IsSubTransaction())
3537  return;
3538 
3539  /*
3540  * inside a function call?
3541  */
3542  if (!isTopLevel)
3543  return;
3544 
3545  ereport(throwError ? ERROR : WARNING,
3546  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3547  /* translator: %s represents an SQL statement name */
3548  errmsg("%s can only be used in transaction blocks",
3549  stmtType)));
3550 }
bool IsSubTransaction(void)
Definition: xact.c:4827
bool IsTransactionBlock(void)
Definition: xact.c:4754

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

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5155 of file xact.c.

5156 {
5158 
5159  ShowTransactionState("CleanupSubTransaction");
5160 
5161  if (s->state != TRANS_ABORT)
5162  elog(WARNING, "CleanupSubTransaction while in %s state",
5164 
5166 
5169  if (s->curTransactionOwner)
5171  s->curTransactionOwner = NULL;
5172 
5174 
5175  s->state = TRANS_DEFAULT;
5176 
5177  PopTransaction();
5178 }
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1092
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:737
static void AtSubCleanup_Memory(void)
Definition: xact.c:1931
static void PopTransaction(void)
Definition: xact.c:5248

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

2861 {
2863 
2864  /*
2865  * State should still be TRANS_ABORT from AbortTransaction().
2866  */
2867  if (s->state != TRANS_ABORT)
2868  elog(FATAL, "CleanupTransaction: unexpected state %s",
2870 
2871  /*
2872  * do abort cleanup processing
2873  */
2874  AtCleanup_Portals(); /* now safe to release portal memory */
2875  AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2876 
2877  CurrentResourceOwner = NULL; /* and resource owner */
2880  s->curTransactionOwner = NULL;
2883 
2884  AtCleanup_Memory(); /* and transaction memory */
2885 
2888  s->nestingLevel = 0;
2889  s->gucNestLevel = 0;
2890  s->childXids = NULL;
2891  s->nChildXids = 0;
2892  s->maxChildXids = 0;
2893  s->parallelModeLevel = 0;
2894 
2897 
2898  /*
2899  * done with abort processing, set current transaction state back to
2900  * default
2901  */
2902  s->state = TRANS_DEFAULT;
2903 }
#define InvalidSubTransactionId
Definition: c.h:593
void AtCleanup_Portals(void)
Definition: portalmem.c:858
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:1021
#define InvalidFullTransactionId
Definition: transam.h:56
int nParallelCurrentXids
Definition: xact.c:124

References AtCleanup_Memory(), AtCleanup_Portals(), AtEOXact_Snapshot(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, FATAL, TransactionStateData::fullTransactionId, TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, TransactionStateData::maxChildXids, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::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 1073 of file xact.c.

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

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(), DefineQueryRewrite(), DefineRelation(), DefineVirtualRelation(), deleteOneObject(), DelRoleMems(), 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_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(), OperatorShellMake(), OperatorUpd(), pg_import_system_collations(), PortalRunMulti(), ProcedureCreate(), ProcessUtilitySlow(), recordExtensionInitPrivWorker(), reindex_index(), reindex_relation(), ReindexRelationConcurrently(), RelationSetNewRelfilenode(), 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 4887 of file xact.c.

4888 {
4890 
4891  ShowTransactionState("CommitSubTransaction");
4892 
4893  if (s->state != TRANS_INPROGRESS)
4894  elog(WARNING, "CommitSubTransaction while in %s state",
4896 
4897  /* Pre-commit processing goes here */
4898 
4900  s->parent->subTransactionId);
4901 
4902  /* If in parallel mode, clean up workers and exit parallel mode. */
4903  if (IsInParallelMode())
4904  {
4906  s->parallelModeLevel = 0;
4907  }
4908 
4909  /* Do the actual "commit", such as it is */
4910  s->state = TRANS_COMMIT;
4911 
4912  /* Must CCI to ensure commands of subtransaction are seen as done */
4914 
4915  /*
4916  * Prior to 8.4 we marked subcommit in clog at this point. We now only
4917  * perform that step, if required, as part of the atomic update of the
4918  * whole transaction tree at top level commit or abort.
4919  */
4920 
4921  /* Post-commit cleanup */
4924  AfterTriggerEndSubXact(true);
4927  s->parent->nestingLevel,
4930  s->parent->subTransactionId);
4932 
4934  s->parent->subTransactionId);
4935 
4938  true, false);
4940  s->parent->subTransactionId);
4941  AtEOSubXact_Inval(true);
4942  AtSubCommit_smgr();
4943 
4944  /*
4945  * The only lock we actually release here is the subtransaction XID lock.
4946  */
4950 
4951  /*
4952  * Other locks should get transferred to their parent resource owner.
4953  */
4956  true, false);
4959  true, false);
4960 
4961  AtEOXact_GUC(true, s->gucNestLevel);
4964  s->parent->subTransactionId);
4966  s->parent->subTransactionId);
4968  s->parent->subTransactionId);
4970  AtEOSubXact_PgStat(true, s->nestingLevel);
4972 
4973  /*
4974  * We need to restore the upper transaction's read-only state, in case the
4975  * upper is read-write while the child is read-only; GUC will incorrectly
4976  * think it should leave the child state in place.
4977  */
4979 
4983  s->curTransactionOwner = NULL;
4984 
4986 
4987  s->state = TRANS_DEFAULT;
4988 
4989  PopTransaction();
4990 }
void AtSubCommit_Notify(void)
Definition: async.c:1740
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:616
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition: portalmem.c:943
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:964
void AtSubCommit_smgr(void)
Definition: storage.c:894
static void AtSubCommit_Memory(void)
Definition: xact.c:1574
static void AtSubCommit_childXids(void)
Definition: xact.c:1603
void CommandCounterIncrement(void)
Definition: xact.c:1073
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition: xact.h:132
@ SUBXACT_EVENT_COMMIT_SUB
Definition: xact.h:130

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

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

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(), EndRestoreBlobs(), restore_toc_entry(), and RestoreArchive().

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 3010 of file xact.c.

3011 {
3013 
3014  if (s->chain)
3016 
3017  switch (s->blockState)
3018  {
3019  /*
3020  * These shouldn't happen. TBLOCK_DEFAULT means the previous
3021  * StartTransactionCommand didn't set the STARTED state
3022  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3023  * by EndParallelWorkerTransaction(), not this function.
3024  */
3025  case TBLOCK_DEFAULT:
3027  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3029  break;
3030 
3031  /*
3032  * If we aren't in a transaction block, just do our usual
3033  * transaction commit, and return to the idle state.
3034  */
3035  case TBLOCK_STARTED:
3038  break;
3039 
3040  /*
3041  * We are completing a "BEGIN TRANSACTION" command, so we change
3042  * to the "transaction block in progress" state and return. (We
3043  * assume the BEGIN did nothing to the database, so we need no
3044  * CommandCounterIncrement.)
3045  */
3046  case TBLOCK_BEGIN:
3048  break;
3049 
3050  /*
3051  * This is the case when we have finished executing a command
3052  * someplace within a transaction block. We increment the command
3053  * counter and return.
3054  */
3055  case TBLOCK_INPROGRESS:
3057  case TBLOCK_SUBINPROGRESS:
3059  break;
3060 
3061  /*
3062  * We are completing a "COMMIT" command. Do it and return to the
3063  * idle state.
3064  */
3065  case TBLOCK_END:
3068  if (s->chain)
3069  {
3070  StartTransaction();
3072  s->chain = false;
3074  }
3075  break;
3076 
3077  /*
3078  * Here we are in the middle of a transaction block but one of the
3079  * commands caused an abort so we do nothing but remain in the
3080  * abort state. Eventually we will get a ROLLBACK command.
3081  */
3082  case TBLOCK_ABORT:
3083  case TBLOCK_SUBABORT:
3084  break;
3085 
3086  /*
3087  * Here we were in an aborted transaction block and we just got
3088  * the ROLLBACK command from the user, so clean up the
3089  * already-aborted transaction and return to the idle state.
3090  */
3091  case TBLOCK_ABORT_END:
3094  if (s->chain)
3095  {
3096  StartTransaction();
3098  s->chain = false;
3100  }
3101  break;
3102 
3103  /*
3104  * Here we were in a perfectly good transaction block but the user
3105  * told us to ROLLBACK anyway. We have to abort the transaction
3106  * and then clean up.
3107  */
3108  case TBLOCK_ABORT_PENDING:
3109  AbortTransaction();
3112  if (s->chain)
3113  {
3114  StartTransaction();
3116  s->chain = false;
3118  }
3119  break;
3120 
3121  /*
3122  * We are completing a "PREPARE TRANSACTION" command. Do it and
3123  * return to the idle state.
3124  */
3125  case TBLOCK_PREPARE:
3128  break;
3129 
3130  /*
3131  * We were just issued a SAVEPOINT inside a transaction block.
3132  * Start a subtransaction. (DefineSavepoint already did
3133  * PushTransaction, so as to have someplace to put the SUBBEGIN
3134  * state.)
3135  */
3136  case TBLOCK_SUBBEGIN:
3139  break;
3140 
3141  /*
3142  * We were issued a RELEASE command, so we end the current
3143  * subtransaction and return to the parent transaction. The parent
3144  * might be ended too, so repeat till we find an INPROGRESS
3145  * transaction or subtransaction.
3146  */
3147  case TBLOCK_SUBRELEASE:
3148  do
3149  {
3151  s = CurrentTransactionState; /* changed by pop */
3152  } while (s->blockState == TBLOCK_SUBRELEASE);
3153 
3156  break;
3157 
3158  /*
3159  * We were issued a COMMIT, so we end the current subtransaction
3160  * hierarchy and perform final commit. We do this by rolling up
3161  * any subtransactions into their parent, which leads to O(N^2)
3162  * operations with respect to resource owners - this isn't that
3163  * bad until we approach a thousands of savepoints but is
3164  * necessary for correctness should after triggers create new
3165  * resource owners.
3166  */
3167  case TBLOCK_SUBCOMMIT:
3168  do
3169  {
3171  s = CurrentTransactionState; /* changed by pop */
3172  } while (s->blockState == TBLOCK_SUBCOMMIT);
3173  /* If we had a COMMIT command, finish off the main xact too */
3174  if (s->blockState == TBLOCK_END)
3175  {
3176  Assert(s->parent == NULL);
3179  if (s->chain)
3180  {
3181  StartTransaction();
3183  s->chain = false;
3185  }
3186  }
3187  else if (s->blockState == TBLOCK_PREPARE)
3188  {
3189  Assert(s->parent == NULL);
3192  }
3193  else
3194  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3196  break;
3197 
3198  /*
3199  * The current already-failed subtransaction is ending due to a
3200  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3201  * examine the parent (which could be in any of several states).
3202  */
3203  case TBLOCK_SUBABORT_END:
3206  break;
3207 
3208  /*
3209  * As above, but it's not dead yet, so abort first.
3210  */
3215  break;
3216 
3217  /*
3218  * The current subtransaction is the target of a ROLLBACK TO
3219  * command. Abort and pop it, then start a new subtransaction
3220  * with the same name.
3221  */
3222  case TBLOCK_SUBRESTART:
3223  {
3224  char *name;
3225  int savepointLevel;
3226 
3227  /* save name and keep Cleanup from freeing it */
3228  name = s->name;
3229  s->name = NULL;
3230  savepointLevel = s->savepointLevel;
3231 
3234 
3235  DefineSavepoint(NULL);
3236  s = CurrentTransactionState; /* changed by push */
3237  s->name = name;
3238  s->savepointLevel = savepointLevel;
3239 
3240  /* This is the same as TBLOCK_SUBBEGIN case */
3244  }
3245  break;
3246 
3247  /*
3248  * Same as above, but the subtransaction had already failed, so we
3249  * don't need AbortSubTransaction.
3250  */
3252  {
3253  char *name;
3254  int savepointLevel;
3255 
3256  /* save name and keep Cleanup from freeing it */
3257  name = s->name;
3258  s->name = NULL;
3259  savepointLevel = s->savepointLevel;
3260 
3262 
3263  DefineSavepoint(NULL);
3264  s = CurrentTransactionState; /* changed by push */
3265  s->name = name;
3266  s->savepointLevel = savepointLevel;
3267 
3268  /* This is the same as TBLOCK_SUBBEGIN case */
3272  }
3273  break;
3274  }
3275 }
#define AssertState(condition)
Definition: c.h:807
static void StartTransaction(void)
Definition: xact.c:1966
void DefineSavepoint(const char *name)
Definition: xact.c:4157
static void CommitSubTransaction(void)
Definition: xact.c:4887
static void CommitTransaction(void)
Definition: xact.c:2125
static void PrepareTransaction(void)
Definition: xact.c:2384
void SaveTransactionCharacteristics(void)
Definition: xact.c:2990
void RestoreTransactionCharacteristics(void)
Definition: xact.c:2998
static void StartSubTransaction(void)
Definition: xact.c:4850

References AbortSubTransaction(), AbortTransaction(), Assert(), AssertState, 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(), BeginInternalSubTransaction(), BootstrapModeMain(), cluster(), DefineIndex(), 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(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), vacuum(), and vacuum_rel().

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

Definition at line 4157 of file xact.c.

4158 {
4160 
4161  /*
4162  * Workers synchronize transaction state at the beginning of each parallel
4163  * operation, so we can't account for new subtransactions after that
4164  * point. (Note that this check will certainly error out if s->blockState
4165  * is TBLOCK_PARALLEL_INPROGRESS, so we can treat that as an invalid case
4166  * below.)
4167  */
4168  if (IsInParallelMode())
4169  ereport(ERROR,
4170  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4171  errmsg("cannot define savepoints during a parallel operation")));
4172 
4173  switch (s->blockState)
4174  {
4175  case TBLOCK_INPROGRESS:
4176  case TBLOCK_SUBINPROGRESS:
4177  /* Normal subtransaction start */
4178  PushTransaction();
4179  s = CurrentTransactionState; /* changed by push */
4180 
4181  /*
4182  * Savepoint names, like the TransactionState block itself, live
4183  * in TopTransactionContext.
4184  */
4185  if (name)
4187  break;
4188 
4189  /*
4190  * We disallow savepoint commands in implicit transaction blocks.
4191  * There would be no great difficulty in allowing them so far as
4192  * this module is concerned, but a savepoint seems inconsistent
4193  * with exec_simple_query's behavior of abandoning the whole query
4194  * string upon error. Also, the point of an implicit transaction
4195  * block (as opposed to a regular one) is to automatically close
4196  * after an error, so it's hard to see how a savepoint would fit
4197  * into that.
4198  *
4199  * The error messages for this are phrased as if there were no
4200  * active transaction block at all, which is historical but
4201  * perhaps could be improved.
4202  */
4204  ereport(ERROR,
4205  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4206  /* translator: %s represents an SQL statement name */
4207  errmsg("%s can only be used in transaction blocks",
4208  "SAVEPOINT")));
4209  break;
4210 
4211  /* These cases are invalid. */
4212  case TBLOCK_DEFAULT:
4213  case TBLOCK_STARTED:
4214  case TBLOCK_BEGIN:
4216  case TBLOCK_SUBBEGIN:
4217  case TBLOCK_END:
4218  case TBLOCK_SUBRELEASE:
4219  case TBLOCK_SUBCOMMIT:
4220  case TBLOCK_ABORT:
4221  case TBLOCK_SUBABORT:
4222  case TBLOCK_ABORT_END:
4223  case TBLOCK_SUBABORT_END:
4224  case TBLOCK_ABORT_PENDING:
4226  case TBLOCK_SUBRESTART:
4228  case TBLOCK_PREPARE:
4229  elog(FATAL, "DefineSavepoint: unexpected state %s",
4231  break;
4232  }
4233 }

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

4136 {
4138 
4139  /*
4140  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4141  * allowing CommitTransactionCommand to commit whatever happened during
4142  * the implicit transaction block as though it were a single statement.
4143  *
4144  * For caller convenience, we consider all other transaction states as
4145  * legal here; otherwise the caller would need its own state check, which
4146  * seems rather pointless.
4147  */
4150 }

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

Referenced by exec_simple_query().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 3828 of file xact.c.

3829 {
3831  bool result = false;
3832 
3833  switch (s->blockState)
3834  {
3835  /*
3836  * We are in a transaction block, so tell CommitTransactionCommand
3837  * to COMMIT.
3838  */
3839  case TBLOCK_INPROGRESS:
3840  s->blockState = TBLOCK_END;
3841  result = true;
3842  break;
3843 
3844  /*
3845  * We are in an implicit transaction block. If AND CHAIN was
3846  * specified, error. Otherwise commit, but issue a warning
3847  * because there was no explicit BEGIN before this.
3848  */
3850  if (chain)
3851  ereport(ERROR,
3852  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3853  /* translator: %s represents an SQL statement name */
3854  errmsg("%s can only be used in transaction blocks",
3855  "COMMIT AND CHAIN")));
3856  else
3857  ereport(WARNING,
3858  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3859  errmsg("there is no transaction in progress")));
3860  s->blockState = TBLOCK_END;
3861  result = true;
3862  break;
3863 
3864  /*
3865  * We are in a failed transaction block. Tell
3866  * CommitTransactionCommand it's time to exit the block.
3867  */
3868  case TBLOCK_ABORT:
3870  break;
3871 
3872  /*
3873  * We are in a live subtransaction block. Set up to subcommit all
3874  * open subtransactions and then commit the main transaction.
3875  */
3876  case TBLOCK_SUBINPROGRESS:
3877  while (s->parent != NULL)
3878  {
3879  if (s->blockState == TBLOCK_SUBINPROGRESS)
3881  else
3882  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3884  s = s->parent;
3885  }
3886  if (s->blockState == TBLOCK_INPROGRESS)
3887  s->blockState = TBLOCK_END;
3888  else
3889  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3891  result = true;
3892  break;
3893 
3894  /*
3895  * Here we are inside an aborted subtransaction. Treat the COMMIT
3896  * as ROLLBACK: set up to abort everything and exit the main
3897  * transaction.
3898  */
3899  case TBLOCK_SUBABORT:
3900  while (s->parent != NULL)
3901  {
3902  if (s->blockState == TBLOCK_SUBINPROGRESS)
3904  else if (s->blockState == TBLOCK_SUBABORT)
3906  else
3907  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3909  s = s->parent;
3910  }
3911  if (s->blockState == TBLOCK_INPROGRESS)
3913  else if (s->blockState == TBLOCK_ABORT)
3915  else
3916  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3918  break;
3919 
3920  /*
3921  * The user issued COMMIT when not inside a transaction. For
3922  * COMMIT without CHAIN, issue a WARNING, staying in
3923  * TBLOCK_STARTED state. The upcoming call to
3924  * CommitTransactionCommand() will then close the transaction and
3925  * put us back into the default state. For COMMIT AND CHAIN,
3926  * error.
3927  */
3928  case TBLOCK_STARTED:
3929  if (chain)
3930  ereport(ERROR,
3931  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3932  /* translator: %s represents an SQL statement name */
3933  errmsg("%s can only be used in transaction blocks",
3934  "COMMIT AND CHAIN")));
3935  else
3936  ereport(WARNING,
3937  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3938  errmsg("there is no transaction in progress")));
3939  result = true;
3940  break;
3941 
3942  /*
3943  * The user issued a COMMIT that somehow ran inside a parallel
3944  * worker. We can't cope with that.
3945  */
3947  ereport(FATAL,
3948  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
3949  errmsg("cannot commit during a parallel operation")));
3950  break;
3951 
3952  /* These cases are invalid. */
3953  case TBLOCK_DEFAULT:
3954  case TBLOCK_BEGIN:
3955  case TBLOCK_SUBBEGIN:
3956  case TBLOCK_END:
3957  case TBLOCK_SUBRELEASE:
3958  case TBLOCK_SUBCOMMIT:
3959  case TBLOCK_ABORT_END:
3960  case TBLOCK_SUBABORT_END:
3961  case TBLOCK_ABORT_PENDING:
3963  case TBLOCK_SUBRESTART:
3965  case TBLOCK_PREPARE:
3966  elog(FATAL, "EndTransactionBlock: unexpected state %s",
3968  break;
3969  }
3970 
3972  s->blockState == TBLOCK_END ||
3973  s->blockState == TBLOCK_ABORT_END ||
3975 
3976  s->chain = chain;
3977 
3978  return result;
3979 }

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

5283 {
5284  TransactionState s;
5285  Size nxids = 0;
5287 
5288  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5289  {
5291  nxids = add_size(nxids, 1);
5292  nxids = add_size(nxids, s->nChildXids);
5293  }
5294 
5295  return add_size(size, mul_size(sizeof(TransactionId), nxids));
5296 }
size_t Size
Definition: c.h:540
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:231

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

1124 {
1125  forceSyncCommit = true;
1126 }
static bool forceSyncCommit
Definition: xact.c:282

References forceSyncCommit.

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 813 of file xact.c.

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

References Assert(), currentCommandId, currentCommandIdUsed, and IsParallelWorker.

Referenced by ATRewriteTable(), CatalogTuplesMultiInsertWithInfo(), CopyFrom(), create_edata_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 516 of file xact.c.

517 {
519 }

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 859 of file xact.c.

860 {
861  return stmtStartTimestamp;
862 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:270

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

851 {
852  return xactStartTimestamp;
853 }
static TimestampTz xactStartTimestamp
Definition: xact.c:269

References xactStartTimestamp.

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

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 871 of file xact.c.

872 {
873  if (xactStopTimestamp != 0)
874  return xactStopTimestamp;
875  return GetCurrentTimestamp();
876 }
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1580
static TimestampTz xactStopTimestamp
Definition: xact.c:271

References GetCurrentTimestamp(), and xactStopTimestamp.

Referenced by pgstat_report_stat().

◆ GetStableLatestTransactionId()

TransactionId GetStableLatestTransactionId ( void  )

Definition at line 593 of file xact.c.

594 {
596  static TransactionId stablexid = InvalidTransactionId;
597 
598  if (lxid != MyProc->lxid)
599  {
600  lxid = MyProc->lxid;
601  stablexid = GetTopTransactionIdIfAny();
602  if (!TransactionIdIsValid(stablexid))
603  stablexid = ReadNextTransactionId();
604  }
605 
606  Assert(TransactionIdIsValid(stablexid));
607 
608  return stablexid;
609 }
uint32 LocalTransactionId
Definition: c.h:589
#define InvalidLocalTransactionId
Definition: lock.h:70
static TransactionId ReadNextTransactionId(void)
Definition: transam.h:316
TransactionId GetTopTransactionIdIfAny(void)
Definition: xact.c:427

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

Referenced by xid_age().

◆ GetTopFullTransactionId()

◆ GetTopFullTransactionIdIfAny()

FullTransactionId GetTopFullTransactionIdIfAny ( void  )

Definition at line 485 of file xact.c.

486 {
488 }

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3563 of file xact.c.

3564 {
3565  /*
3566  * Return true on same conditions that would make
3567  * PreventInTransactionBlock error out
3568  */
3569  if (IsTransactionBlock())
3570  return true;
3571 
3572  if (IsSubTransaction())
3573  return true;
3574 
3575  if (!isTopLevel)
3576  return true;
3577 
3580  return true;
3581 
3582  return false;
3583 }

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

Referenced by vacuum().

◆ IsSubTransaction()

◆ IsSubxactTopXidLogPending()

bool IsSubxactTopXidLogPending ( void  )

Definition at line 545 of file xact.c.

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

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

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

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_role(), check_session_authorization(), check_temp_tablespaces(), check_transaction_read_only(), check_TSCurrentConfig(), check_XactIsoLevel(), CreateInitDecodingContext(), FetchTableStates(), InitializeClientEncoding(), IsSubxactTopXidLogPending(), 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 577 of file xact.c.

578 {
580 
582 }
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:545

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

Referenced by XLogInsertRecord().

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5248 of file xact.c.

5249 {
5251 
5252  if (s->state != TRANS_DEFAULT)
5253  elog(WARNING, "PopTransaction while in %s state",
5255 
5256  if (s->parent == NULL)
5257  elog(FATAL, "PopTransaction with no parent");
5258 
5260 
5261  /* Let's just make sure CurTransactionContext is good */
5264 
5265  /* Ditto for ResourceOwner links */
5268 
5269  /* Free the old child structure */
5270  if (s->name)
5271  pfree(s->name);
5272  pfree(s);
5273 }

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

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

3777 {
3778  TransactionState s;
3779  bool result;
3780 
3781  /* Set up to commit the current transaction */
3782  result = EndTransactionBlock(false);
3783 
3784  /* If successful, change outer tblock state to PREPARE */
3785  if (result)
3786  {
3788 
3789  while (s->parent != NULL)
3790  s = s->parent;
3791 
3792  if (s->blockState == TBLOCK_END)
3793  {
3794  /* Save GID where PrepareTransaction can find it again */
3796 
3798  }
3799  else
3800  {
3801  /*
3802  * ignore case where we are not in a transaction;
3803  * EndTransactionBlock already issued a warning.
3804  */
3807  /* Don't send back a PREPARE result tag... */
3808  result = false;
3809  }
3810  }
3811 
3812  return result;
3813 }
bool EndTransactionBlock(bool chain)
Definition: xact.c:3828

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

3451 {
3452  /*
3453  * xact block already started?
3454  */
3455  if (IsTransactionBlock())
3456  ereport(ERROR,
3457  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3458  /* translator: %s represents an SQL statement name */
3459  errmsg("%s cannot run inside a transaction block",
3460  stmtType)));
3461 
3462  /*
3463  * subtransaction?
3464  */
3465  if (IsSubTransaction())
3466  ereport(ERROR,
3467  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3468  /* translator: %s represents an SQL statement name */
3469  errmsg("%s cannot run inside a subtransaction",
3470  stmtType)));
3471 
3472  /*
3473  * inside a function call?
3474  */
3475  if (!isTopLevel)
3476  ereport(ERROR,
3477  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3478  /* translator: %s represents an SQL statement name */
3479  errmsg("%s cannot be executed from a function", stmtType)));
3480 
3481  /* If we got past IsTransactionBlock test, should be in default state */
3484  elog(FATAL, "cannot prevent transaction chain");
3485  /* all okay */
3486 }

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

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

5189 {
5191  TransactionState s;
5192 
5193  /*
5194  * We keep subtransaction state nodes in TopTransactionContext.
5195  */
5196  s = (TransactionState)
5198  sizeof(TransactionStateData));
5199 
5200  /*
5201  * Assign a subtransaction ID, watching out for counter wraparound.
5202  */
5205  {
5207  pfree(s);
5208  ereport(ERROR,
5209  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5210  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5211  }
5212 
5213  /*
5214  * We can now stack a minimally valid subtransaction without fear of
5215  * failure.
5216  */
5217  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5219  s->parent = p;
5220  s->nestingLevel = p->nestingLevel + 1;
5223  s->state = TRANS_DEFAULT;
5227  s->parallelModeLevel = 0;
5228  s->topXidLogged = false;
5229 
5231 
5232  /*
5233  * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5234  * with the subtransaction from here on out; in particular they should not
5235  * assume that it necessarily has a transaction context, resource owner,
5236  * or XID.
5237  */
5238 }
int NewGUCNestLevel(void)
Definition: guc.c:6242
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:906
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:600
TransactionStateData * TransactionState
Definition: xact.c:213
static SubTransactionId currentSubTransactionId
Definition: xact.c:258

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

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

References elog, END_CRIT_SECTION, GetCurrentTimestamp(), GetCurrentTransactionIdIfAny(), InvalidTransactionId, MyXactFlags, PANIC, pfree(), SetCurrentTransactionStopTimestamp(), smgrGetPendingDeletes(), START_CRIT_SECTION, TransactionIdAbortTree(), TransactionIdDidCommit(), TransactionIdIsValid, TransactionIdLatest(), xactGetCommittedChildren(), XactLastRecEnd, XactLogAbortRecord(), xactStopTimestamp, XidCacheRemoveRunningXids(), and XLogSetAsyncXactLSN().

Referenced by AbortSubTransaction(), and AbortTransaction().

◆ RecordTransactionCommit()

static TransactionId RecordTransactionCommit ( void  )
static

Definition at line 1278 of file xact.c.

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

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

Referenced by CommitTransaction().

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3653 of file xact.c.

3654 {
3655  SubXactCallbackItem *item;
3656 
3657  item = (SubXactCallbackItem *)
3659  item->callback = callback;
3660  item->arg = arg;
3661  item->next = SubXact_callbacks;
3662  SubXact_callbacks = item;
3663 }
void * arg
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48

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

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

◆ RegisterXactCallback()

void RegisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3598 of file xact.c.

3599 {
3600  XactCallbackItem *item;
3601 
3602  item = (XactCallbackItem *)
3604  item->callback = callback;
3605  item->arg = arg;
3606  item->next = Xact_callbacks;
3607  Xact_callbacks = item;
3608 }

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

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

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

Definition at line 4549 of file xact.c.

4550 {
4552 
4553  /*
4554  * Workers synchronize transaction state at the beginning of each parallel
4555  * operation, so we can't account for commit of subtransactions after that
4556  * point. This should not happen anyway. Code calling this would
4557  * typically have called BeginInternalSubTransaction() first, failing
4558  * there.
4559  */
4560  if (IsInParallelMode())
4561  ereport(ERROR,
4562  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4563  errmsg("cannot commit subtransactions during a parallel operation")));
4564 
4565  if (s->blockState != TBLOCK_SUBINPROGRESS)
4566  elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4568  Assert(s->state == TRANS_INPROGRESS);
4571  s = CurrentTransactionState; /* changed by pop */
4572  Assert(s->state == TRANS_INPROGRESS);
4573 }

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

Referenced by