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

Go to the source code of this file.

Data Structures

struct  TransactionStateData
 
struct  SerializedTransactionState
 
struct  XactCallbackItem
 
struct  SubXactCallbackItem
 

Macros

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)
 

Typedefs

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

Enumerations

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

Functions

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

Variables

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

Macro Definition Documentation

◆ SerializedTransactionStateHeaderSize

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)

Definition at line 233 of file xact.c.

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

typedef enum TBlockState TBlockState

◆ TransactionState

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

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

◆ TransState

enum TransState
Enumerator
TRANS_DEFAULT 
TRANS_START 
TRANS_INPROGRESS 
TRANS_COMMIT 
TRANS_ABORT 
TRANS_PREPARE 

Definition at line 141 of file xact.c.

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

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3305 of file xact.c.

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

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

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

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4712 of file xact.c.

4713 {
4715 
4716  /* Ensure we're not running in a doomed memory context */
4717  AtAbort_Memory();
4718 
4719  /*
4720  * Get out of any transaction or nested transaction
4721  */
4722  do
4723  {
4724  switch (s->blockState)
4725  {
4726  case TBLOCK_DEFAULT:
4727  if (s->state == TRANS_DEFAULT)
4728  {
4729  /* Not in a transaction, do nothing */
4730  }
4731  else
4732  {
4733  /*
4734  * We can get here after an error during transaction start
4735  * (state will be TRANS_START). Need to clean up the
4736  * incompletely started transaction. First, adjust the
4737  * low-level state to suppress warning message from
4738  * AbortTransaction.
4739  */
4740  if (s->state == TRANS_START)
4741  s->state = TRANS_INPROGRESS;
4742  AbortTransaction();
4744  }
4745  break;
4746  case TBLOCK_STARTED:
4747  case TBLOCK_BEGIN:
4748  case TBLOCK_INPROGRESS:
4751  case TBLOCK_END:
4752  case TBLOCK_ABORT_PENDING:
4753  case TBLOCK_PREPARE:
4754  /* In a transaction, so clean up */
4755  AbortTransaction();
4758  break;
4759  case TBLOCK_ABORT:
4760  case TBLOCK_ABORT_END:
4761 
4762  /*
4763  * AbortTransaction is already done, still need Cleanup.
4764  * However, if we failed partway through running ROLLBACK,
4765  * there will be an active portal running that command, which
4766  * we need to shut down before doing CleanupTransaction.
4767  */
4768  AtAbort_Portals();
4771  break;
4772 
4773  /*
4774  * In a subtransaction, so clean it up and abort parent too
4775  */
4776  case TBLOCK_SUBBEGIN:
4777  case TBLOCK_SUBINPROGRESS:
4778  case TBLOCK_SUBRELEASE:
4779  case TBLOCK_SUBCOMMIT:
4781  case TBLOCK_SUBRESTART:
4784  s = CurrentTransactionState; /* changed by pop */
4785  break;
4786 
4787  case TBLOCK_SUBABORT:
4788  case TBLOCK_SUBABORT_END:
4790  /* As above, but AbortSubTransaction already done */
4791  if (s->curTransactionOwner)
4792  {
4793  /* As in TBLOCK_ABORT, might have a live portal to zap */
4798  }
4800  s = CurrentTransactionState; /* changed by pop */
4801  break;
4802  }
4803  } while (s->blockState != TBLOCK_DEFAULT);
4804 
4805  /* Should be out of all subxacts now */
4806  Assert(s->parent == NULL);
4807 
4808  /* If we didn't actually have anything to do, revert to TopMemoryContext */
4809  AtCleanup_Memory();
4810 }
Assert(fmt[strlen(fmt) - 1] !='\n')
void AtAbort_Portals(void)
Definition: portalmem.c:782
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:980
SubTransactionId subTransactionId
Definition: xact.c:192
struct TransactionStateData * parent
Definition: xact.c:212
ResourceOwner curTransactionOwner
Definition: xact.c:200
static void AtCleanup_Memory(void)
Definition: xact.c:1922
static void AtAbort_Memory(void)
Definition: xact.c:1832

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

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

◆ AbortSubTransaction()

static void AbortSubTransaction ( void  )
static

Definition at line 5058 of file xact.c.

5059 {
5061 
5062  /* Prevent cancel/die interrupt while cleaning up */
5063  HOLD_INTERRUPTS();
5064 
5065  /* Make sure we have a valid memory context and resource owner */
5068 
5069  /*
5070  * Release any LW locks we might be holding as quickly as possible.
5071  * (Regular locks, however, must be held till we finish aborting.)
5072  * Releasing LW locks is critical since we might try to grab them again
5073  * while cleaning up!
5074  *
5075  * FIXME This may be incorrect --- Are there some locks we should keep?
5076  * Buffer locks, for example? I don't think so but I'm not sure.
5077  */
5078  LWLockReleaseAll();
5079 
5082  UnlockBuffers();
5083 
5084  /* Reset WAL record construction state */
5086 
5087  /* Cancel condition variable sleep */
5089 
5090  /*
5091  * Also clean up any open wait for lock, since the lock manager will choke
5092  * if we try to wait for another lock before doing this.
5093  */
5094  LockErrorCleanup();
5095 
5096  /*
5097  * If any timeout events are still active, make sure the timeout interrupt
5098  * is scheduled. This covers possible loss of a timeout interrupt due to
5099  * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5100  * We delay this till after LockErrorCleanup so that we don't uselessly
5101  * reschedule lock or deadlock check timeouts.
5102  */
5104 
5105  /*
5106  * Re-enable signals, in case we got here by longjmp'ing out of a signal
5107  * handler. We do this fairly early in the sequence so that the timeout
5108  * infrastructure will be functional if needed while aborting.
5109  */
5110  sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5111 
5112  /*
5113  * check the current transaction state
5114  */
5115  ShowTransactionState("AbortSubTransaction");
5116 
5117  if (s->state != TRANS_INPROGRESS)
5118  elog(WARNING, "AbortSubTransaction while in %s state",
5120 
5121  s->state = TRANS_ABORT;
5122 
5123  /*
5124  * Reset user ID which might have been changed transiently. (See notes in
5125  * AbortTransaction.)
5126  */
5128 
5129  /* Forget about any active REINDEX. */
5131 
5132  /* Reset logical streaming state. */
5134 
5135  /*
5136  * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5137  * exports are not supported in subtransactions.
5138  */
5139 
5140  /* Exit from parallel mode, if necessary. */
5141  if (IsInParallelMode())
5142  {
5144  s->parallelModeLevel = 0;
5145  }
5146 
5147  /*
5148  * We can skip all this stuff if the subxact failed before creating a
5149  * ResourceOwner...
5150  */
5151  if (s->curTransactionOwner)
5152  {
5153  AfterTriggerEndSubXact(false);
5159  s->parent->subTransactionId);
5161 
5162  /* Advertise the fact that we aborted in pg_xact. */
5163  (void) RecordTransactionAbort(true);
5164 
5165  /* Post-abort cleanup */
5168 
5170  s->parent->subTransactionId);
5171 
5174  false, false);
5176  s->parent->subTransactionId);
5177  AtEOSubXact_Inval(false);
5180  false, false);
5183  false, false);
5184  AtSubAbort_smgr();
5185 
5186  AtEOXact_GUC(false, s->gucNestLevel);
5187  AtEOSubXact_SPI(false, s->subTransactionId);
5189  s->parent->subTransactionId);
5191  s->parent->subTransactionId);
5193  s->parent->subTransactionId);
5195  AtEOSubXact_PgStat(false, s->nestingLevel);
5197  }
5198 
5199  /*
5200  * Restore the upper transaction's read-only state, too. This should be
5201  * redundant with GUC's cleanup but we may as well do it for consistency
5202  * with the commit case.
5203  */
5205 
5207 }
void AtSubAbort_Notify(void)
Definition: async.c:1810
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition: parallel.c:1244
sigset_t UnBlockSig
Definition: pqsignal.c:22
void pgstat_progress_end_command(void)
void AtEOSubXact_LargeObject(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: be-fsstubs.c:648
void UnlockBuffers(void)
Definition: bufmgr.c:4687
bool ConditionVariableCancelSleep(void)
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1904
#define WARNING
Definition: elog.h:36
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:3077
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2215
void ResetReindexState(int nestLevel)
Definition: index.c:4109
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1085
void ResetLogicalStreamingState(void)
Definition: logical.c:1902
void LWLockReleaseAll(void)
Definition: lwlock.c:1903
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:134
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:132
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:637
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: namespace.c:4004
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:113
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3330
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:488
@ 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:935
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition: spi.c:483
void LockErrorCleanup(void)
Definition: proc.c:698
void AtSubAbort_smgr(void)
Definition: storage.c:952
int parallelModeLevel
Definition: xact.c:209
FullTransactionId fullTransactionId
Definition: xact.c:191
bool prevXactReadOnly
Definition: xact.c:206
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:17615
void reschedule_timeouts(void)
Definition: timeout.c:544
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5337
static void pgstat_report_wait_end(void)
Definition: wait_event.h:104
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3744
static void AtSubAbort_Memory(void)
Definition: xact.c:1852
static const char * TransStateAsString(TransState state)
Definition: xact.c:5582
bool XactReadOnly
Definition: xact.c:82
static void AtSubAbort_childXids(void)
Definition: xact.c:1890
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1877
static void ShowTransactionState(const char *str)
Definition: xact.c:5479
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1702
bool IsInParallelMode(void)
Definition: xact.c:1069
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:144
void XLogResetInsertion(void)
Definition: xloginsert.c:223

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

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

◆ AbortTransaction()

static void AbortTransaction ( void  )
static

Definition at line 2697 of file xact.c.

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

References AfterTriggerEndXact(), Assert(), AtAbort_Memory(), AtAbort_Notify(), AtAbort_Portals(), AtAbort_ResourceOwner(), AtAbort_Twophase(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_Inval(), AtEOXact_LargeObject(), AtEOXact_LogicalRepWorkers(), AtEOXact_MultiXact(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_Parallel(), AtEOXact_PgStat(), AtEOXact_RelationCache(), AtEOXact_RelationMap(), AtEOXact_SMgr(), AtEOXact_SPI(), TransactionStateData::blockState, CallXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, elog(), HOLD_INTERRUPTS, InvalidTransactionId, IsInParallelMode(), LockErrorCleanup(), LWLockReleaseAll(), PGPROC::lxid, MyProc, TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pgstat_progress_end_command(), pgstat_report_wait_end(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, ProcArrayEndTransaction(), RecordTransactionAbort(), reschedule_timeouts(), ResetLogicalStreamingState(), ResetReindexState(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), RESUME_INTERRUPTS, SetUserIdAndSecContext(), smgrDoPendingDeletes(), smgrDoPendingSyncs(), SnapBuildResetExportedSnapshotState(), TransactionStateData::state, TBLOCK_PARALLEL_INPROGRESS, TopTransactionResourceOwner, TRANS_ABORT, TRANS_INPROGRESS, TRANS_PREPARE, 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 626 of file xact.c.

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

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

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

◆ AtAbort_Memory()

static void AtAbort_Memory ( void  )
static

Definition at line 1832 of file xact.c.

1833 {
1834  /*
1835  * Switch into TransactionAbortContext, which should have some free space
1836  * even if nothing else does. We'll work in this context until we've
1837  * finished cleaning up.
1838  *
1839  * It is barely possible to get here when we've not been able to create
1840  * TransactionAbortContext yet; if so use TopMemoryContext.
1841  */
1842  if (TransactionAbortContext != NULL)
1844  else
1846 }
MemoryContext TopMemoryContext
Definition: mcxt.c:141
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:138
static MemoryContext TransactionAbortContext
Definition: xact.c:297

References MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1864 of file xact.c.

1865 {
1866  /*
1867  * Make sure we have a valid ResourceOwner, if possible (else it will be
1868  * NULL, which is OK)
1869  */
1871 }

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1537 of file xact.c.

1538 {
1539  /*
1540  * Make any pending relation map changes visible. We must do this before
1541  * processing local sinval messages, so that the map changes will get
1542  * reflected into the relcache when relcache invals are processed.
1543  */
1545 
1546  /*
1547  * Make catalog changes visible to me for the next command.
1548  */
1550 }
void CommandEndInvalidationMessages(void)
Definition: inval.c:1173
void AtCCI_RelationMap(void)
Definition: relmapper.c:504

References AtCCI_RelationMap(), and CommandEndInvalidationMessages().

Referenced by CommandCounterIncrement().

◆ AtCleanup_Memory()

static void AtCleanup_Memory ( void  )
static

Definition at line 1922 of file xact.c.

1923 {
1925 
1926  /*
1927  * Now that we're "out" of a transaction, have the system allocate things
1928  * in the top memory context instead of per-transaction contexts.
1929  */
1931 
1932  /*
1933  * Clear the special abort context for next time.
1934  */
1935  if (TransactionAbortContext != NULL)
1937 
1938  /*
1939  * Release all transaction-local memory.
1940  */
1941  if (TopTransactionContext != NULL)
1943  TopTransactionContext = NULL;
1944  CurTransactionContext = NULL;
1946 }
MemoryContext TopTransactionContext
Definition: mcxt.c:146
MemoryContext CurTransactionContext
Definition: mcxt.c:147
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:403
#define MemoryContextResetAndDeleteChildren(ctx)
Definition: memutils.h:70
MemoryContext curTransactionContext
Definition: xact.c:199

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

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

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

1144 {
1146 }
void AcceptInvalidationMessages(void)
Definition: inval.c:746

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1152 of file xact.c.

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

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

Referenced by StartTransaction().

◆ AtStart_ResourceOwner()

static void AtStart_ResourceOwner ( void  )
static

Definition at line 1199 of file xact.c.

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

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

Referenced by StartTransaction().

◆ AtSubAbort_childXids()

static void AtSubAbort_childXids ( void  )
static

Definition at line 1890 of file xact.c.

1891 {
1893 
1894  /*
1895  * We keep the child-XID arrays in TopTransactionContext (see
1896  * AtSubCommit_childXids). This means we'd better free the array
1897  * explicitly at abort to avoid leakage.
1898  */
1899  if (s->childXids != NULL)
1900  pfree(s->childXids);
1901  s->childXids = NULL;
1902  s->nChildXids = 0;
1903  s->maxChildXids = 0;
1904 
1905  /*
1906  * We could prune the unreportedXids array here. But we don't bother. That
1907  * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1908  * would likely introduce more CPU time into the more common paths, so we
1909  * choose not to do that.
1910  */
1911 }
TransactionId * childXids
Definition: xact.c:201

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

Definition at line 1852 of file xact.c.

1853 {
1855 
1857 }

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1877 of file xact.c.

1878 {
1880 
1881  /* Make sure we have a valid ResourceOwner */
1883 }

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 1958 of file xact.c.

1959 {
1961 
1962  Assert(s->parent != NULL);
1963 
1964  /* Make sure we're not in an about-to-be-deleted context */
1967 
1968  /*
1969  * Clear the special abort context for next time.
1970  */
1971  if (TransactionAbortContext != NULL)
1973 
1974  /*
1975  * Delete the subxact local memory contexts. Its CurTransactionContext can
1976  * go too (note this also kills CurTransactionContexts from any children
1977  * of the subxact).
1978  */
1979  if (s->curTransactionContext)
1981  s->curTransactionContext = NULL;
1982 }

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

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

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

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

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

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

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

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

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4172 of file xact.c.

4173 {
4175 
4176  /*
4177  * If we are in STARTED state (that is, no transaction block is open),
4178  * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4179  * block.
4180  *
4181  * For caller convenience, we consider all other transaction states as
4182  * legal here; otherwise the caller would need its own state check, which
4183  * seems rather pointless.
4184  */
4185  if (s->blockState == TBLOCK_STARTED)
4187 }

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

Referenced by exec_simple_query().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4540 of file xact.c.

4541 {
4543 
4544  /*
4545  * Workers synchronize transaction state at the beginning of each parallel
4546  * operation, so we can't account for new subtransactions after that
4547  * point. We might be able to make an exception for the type of
4548  * subtransaction established by this function, which is typically used in
4549  * contexts where we're going to release or roll back the subtransaction
4550  * before proceeding further, so that no enduring change to the
4551  * transaction state occurs. For now, however, we prohibit this case along
4552  * with all the others.
4553  */
4554  if (IsInParallelMode())
4555  ereport(ERROR,
4556  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4557  errmsg("cannot start subtransactions during a parallel operation")));
4558 
4559  switch (s->blockState)
4560  {
4561  case TBLOCK_STARTED:
4562  case TBLOCK_INPROGRESS:
4564  case TBLOCK_END:
4565  case TBLOCK_PREPARE:
4566  case TBLOCK_SUBINPROGRESS:
4567  /* Normal subtransaction start */
4568  PushTransaction();
4569  s = CurrentTransactionState; /* changed by push */
4570 
4571  /*
4572  * Savepoint names, like the TransactionState block itself, live
4573  * in TopTransactionContext.
4574  */
4575  if (name)
4577  break;
4578 
4579  /* These cases are invalid. */
4580  case TBLOCK_DEFAULT:
4581  case TBLOCK_BEGIN:
4583  case TBLOCK_SUBBEGIN:
4584  case TBLOCK_SUBRELEASE:
4585  case TBLOCK_SUBCOMMIT:
4586  case TBLOCK_ABORT:
4587  case TBLOCK_SUBABORT:
4588  case TBLOCK_ABORT_END:
4589  case TBLOCK_SUBABORT_END:
4590  case TBLOCK_ABORT_PENDING:
4592  case TBLOCK_SUBRESTART:
4594  elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4596  break;
4597  }
4598 
4601 }
#define FATAL
Definition: elog.h:41
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1631
const char * name
static void PushTransaction(void)
Definition: xact.c:5249
void StartTransactionCommand(void)
Definition: xact.c:2937
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5529
void CommitTransactionCommand(void)
Definition: xact.c:3034

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

3771 {
3773 
3774  switch (s->blockState)
3775  {
3776  /*
3777  * We are not inside a transaction block, so allow one to begin.
3778  */
3779  case TBLOCK_STARTED:
3780  s->blockState = TBLOCK_BEGIN;
3781  break;
3782 
3783  /*
3784  * BEGIN converts an implicit transaction block to a regular one.
3785  * (Note that we allow this even if we've already done some
3786  * commands, which is a bit odd but matches historical practice.)
3787  */
3789  s->blockState = TBLOCK_BEGIN;
3790  break;
3791 
3792  /*
3793  * Already a transaction block in progress.
3794  */
3795  case TBLOCK_INPROGRESS:
3797  case TBLOCK_SUBINPROGRESS:
3798  case TBLOCK_ABORT:
3799  case TBLOCK_SUBABORT:
3800  ereport(WARNING,
3801  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3802  errmsg("there is already a transaction in progress")));
3803  break;
3804 
3805  /* These cases are invalid. */
3806  case TBLOCK_DEFAULT:
3807  case TBLOCK_BEGIN:
3808  case TBLOCK_SUBBEGIN:
3809  case TBLOCK_END:
3810  case TBLOCK_SUBRELEASE:
3811  case TBLOCK_SUBCOMMIT:
3812  case TBLOCK_ABORT_END:
3813  case TBLOCK_SUBABORT_END:
3814  case TBLOCK_ABORT_PENDING:
3816  case TBLOCK_SUBRESTART:
3818  case TBLOCK_PREPARE:
3819  elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3821  break;
3822  }
3823 }

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

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

◆ BlockStateAsString()

static const char * BlockStateAsString ( TBlockState  blockState)
static

Definition at line 5529 of file xact.c.

5530 {
5531  switch (blockState)
5532  {
5533  case TBLOCK_DEFAULT:
5534  return "DEFAULT";
5535  case TBLOCK_STARTED:
5536  return "STARTED";
5537  case TBLOCK_BEGIN:
5538  return "BEGIN";
5539  case TBLOCK_INPROGRESS:
5540  return "INPROGRESS";
5542  return "IMPLICIT_INPROGRESS";
5544  return "PARALLEL_INPROGRESS";
5545  case TBLOCK_END:
5546  return "END";
5547  case TBLOCK_ABORT:
5548  return "ABORT";
5549  case TBLOCK_ABORT_END:
5550  return "ABORT_END";
5551  case TBLOCK_ABORT_PENDING:
5552  return "ABORT_PENDING";
5553  case TBLOCK_PREPARE:
5554  return "PREPARE";
5555  case TBLOCK_SUBBEGIN:
5556  return "SUBBEGIN";
5557  case TBLOCK_SUBINPROGRESS:
5558  return "SUBINPROGRESS";
5559  case TBLOCK_SUBRELEASE:
5560  return "SUBRELEASE";
5561  case TBLOCK_SUBCOMMIT:
5562  return "SUBCOMMIT";
5563  case TBLOCK_SUBABORT:
5564  return "SUBABORT";
5565  case TBLOCK_SUBABORT_END:
5566  return "SUBABORT_END";
5568  return "SUBABORT_PENDING";
5569  case TBLOCK_SUBRESTART:
5570  return "SUBRESTART";
5572  return "SUBABORT_RESTART";
5573  }
5574  return "UNRECOGNIZED";
5575 }

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

3747 {
3748  SubXactCallbackItem *item;
3750 
3751  for (item = SubXact_callbacks; item; item = next)
3752  {
3753  /* allow callbacks to unregister themselves when called */
3754  next = item->next;
3755  item->callback(event, mySubid, parentSubid, item->arg);
3756  }
3757 }
static int32 next
Definition: blutils.c:219
struct SubXactCallbackItem * next
Definition: xact.c:316
SubXactCallback callback
Definition: xact.c:317
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:321

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

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

◆ CallXactCallbacks()

static void CallXactCallbacks ( XactEvent  event)
static

Definition at line 3684 of file xact.c.

3685 {
3686  XactCallbackItem *item;
3688 
3689  for (item = Xact_callbacks; item; item = next)
3690  {
3691  /* allow callbacks to unregister themselves when called */
3692  next = item->next;
3693  item->callback(event, item->arg);
3694  }
3695 }
struct XactCallbackItem * next
Definition: xact.c:304
void * arg
Definition: xact.c:306
XactCallback callback
Definition: xact.c:305
static XactCallbackItem * Xact_callbacks
Definition: xact.c:309

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

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

◆ CheckTransactionBlock()

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

Definition at line 3568 of file xact.c.

3569 {
3570  /*
3571  * xact block already started?
3572  */
3573  if (IsTransactionBlock())
3574  return;
3575 
3576  /*
3577  * subtransaction?
3578  */
3579  if (IsSubTransaction())
3580  return;
3581 
3582  /*
3583  * inside a function call?
3584  */
3585  if (!isTopLevel)
3586  return;
3587 
3588  ereport(throwError ? ERROR : WARNING,
3589  (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3590  /* translator: %s represents an SQL statement name */
3591  errmsg("%s can only be used in transaction blocks",
3592  stmtType)));
3593 }
bool IsSubTransaction(void)
Definition: xact.c:4889
bool IsTransactionBlock(void)
Definition: xact.c:4816

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

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5216 of file xact.c.

5217 {
5219 
5220  ShowTransactionState("CleanupSubTransaction");
5221 
5222  if (s->state != TRANS_ABORT)
5223  elog(WARNING, "CleanupSubTransaction while in %s state",
5225 
5227 
5230  if (s->curTransactionOwner)
5232  s->curTransactionOwner = NULL;
5233 
5235 
5236  s->state = TRANS_DEFAULT;
5237 
5238  PopTransaction();
5239 }
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1093
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:762
static void AtSubCleanup_Memory(void)
Definition: xact.c:1958
static void PopTransaction(void)
Definition: xact.c:5309

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

2889 {
2891 
2892  /*
2893  * State should still be TRANS_ABORT from AbortTransaction().
2894  */
2895  if (s->state != TRANS_ABORT)
2896  elog(FATAL, "CleanupTransaction: unexpected state %s",
2898 
2899  /*
2900  * do abort cleanup processing
2901  */
2902  AtCleanup_Portals(); /* now safe to release portal memory */
2903  AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
2904 
2905  CurrentResourceOwner = NULL; /* and resource owner */
2908  s->curTransactionOwner = NULL;
2911 
2912  AtCleanup_Memory(); /* and transaction memory */
2913 
2916  s->nestingLevel = 0;
2917  s->gucNestLevel = 0;
2918  s->childXids = NULL;
2919  s->nChildXids = 0;
2920  s->maxChildXids = 0;
2921  s->parallelModeLevel = 0;
2922 
2925 
2926  /*
2927  * done with abort processing, set current transaction state back to
2928  * default
2929  */
2930  s->state = TRANS_DEFAULT;
2931 }
#define InvalidSubTransactionId
Definition: c.h:647
void AtCleanup_Portals(void)
Definition: portalmem.c:859
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:971
#define InvalidFullTransactionId
Definition: transam.h:56
static int nParallelCurrentXids
Definition: xact.c:126

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

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

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(), ATAddCheckNNConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecCmd(), ATExecDropColumn(), ATExecDropExpression(), ATExecDropIdentity(), ATExecSetCompression(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), ATInheritAdjustNotNulls(), 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(), DefineIndex(), DefineRelation(), DefineVirtualRelation(), deleteOneObject(), DetachPartitionFinalize(), DropClonedTriggersFromPartition(), dropconstraint_internal(), DropRole(), end_replication_step(), EventTriggerDDLCommandEnd(), EventTriggerDDLCommandStart(), EventTriggerInvoke(), EventTriggerSQLDrop(), EventTriggerTableRewrite(), exec_eval_simple_expr(), exec_execute_message(), exec_parse_message(), exec_simple_query(), ExecGrant_common(), ExecGrant_Largeobject(), ExecGrant_Parameter(), ExecGrant_Relation(), execute_sql_string(), ExplainOnePlan(), finish_heap_swap(), fmgr_sql(), hashadjustmembers(), ImportForeignSchema(), index_build(), index_create(), IndexSetParentIndex(), InitTempTableNamespace(), inv_create(), inv_drop(), inv_truncate(), inv_write(), LogicalRepSyncTableStart(), make_new_heap(), makeConfigurationDependencies(), moveArrayTypeName(), objectNamesToOids(), OperatorShellMake(), OperatorUpd(), pg_import_system_collations(), PortalRunMulti(), ProcedureCreate(), process_syncing_tables_for_apply(), ProcessUtilitySlow(), recordExtensionInitPrivWorker(), reindex_index(), reindex_relation(), ReindexRelationConcurrently(), RelationSetNewRelfilenumber(), RemoveRoleFromObjectPolicy(), RenumberEnumType(), replorigin_create(), replorigin_drop_by_name(), ri_PerformCheck(), SetDefaultACL(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), standard_ProcessUtility(), StoreConstraints(), StorePartitionBound(), tryAttachPartitionForeignKey(), vacuum(), and validatePartitionedIndex().

◆ CommitSubTransaction()

static void CommitSubTransaction ( void  )
static

Definition at line 4949 of file xact.c.

4950 {
4952 
4953  ShowTransactionState("CommitSubTransaction");
4954 
4955  if (s->state != TRANS_INPROGRESS)
4956  elog(WARNING, "CommitSubTransaction while in %s state",
4958 
4959  /* Pre-commit processing goes here */
4960 
4962  s->parent->subTransactionId);
4963 
4964  /* If in parallel mode, clean up workers and exit parallel mode. */
4965  if (IsInParallelMode())
4966  {
4968  s->parallelModeLevel = 0;
4969  }
4970 
4971  /* Do the actual "commit", such as it is */
4972  s->state = TRANS_COMMIT;
4973 
4974  /* Must CCI to ensure commands of subtransaction are seen as done */
4976 
4977  /*
4978  * Prior to 8.4 we marked subcommit in clog at this point. We now only
4979  * perform that step, if required, as part of the atomic update of the
4980  * whole transaction tree at top level commit or abort.
4981  */
4982 
4983  /* Post-commit cleanup */
4986  AfterTriggerEndSubXact(true);
4989  s->parent->nestingLevel,
4992  s->parent->subTransactionId);
4994 
4996  s->parent->subTransactionId);
4997 
5000  true, false);
5002  s->parent->subTransactionId);
5003  AtEOSubXact_Inval(true);
5004  AtSubCommit_smgr();
5005 
5006  /*
5007  * The only lock we actually release here is the subtransaction XID lock.
5008  */
5012 
5013  /*
5014  * Other locks should get transferred to their parent resource owner.
5015  */
5018  true, false);
5021  true, false);
5022 
5023  AtEOXact_GUC(true, s->gucNestLevel);
5026  s->parent->subTransactionId);
5028  s->parent->subTransactionId);
5030  s->parent->subTransactionId);
5032  AtEOSubXact_PgStat(true, s->nestingLevel);
5034 
5035  /*
5036  * We need to restore the upper transaction's read-only state, in case the
5037  * upper is read-write while the child is read-only; GUC will incorrectly
5038  * think it should leave the child state in place.
5039  */
5041 
5045  s->curTransactionOwner = NULL;
5046 
5048 
5049  s->state = TRANS_DEFAULT;
5050 
5051  PopTransaction();
5052 }
void AtSubCommit_Notify(void)
Definition: async.c:1740
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:644
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition: portalmem.c:944
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:914
void AtSubCommit_smgr(void)
Definition: storage.c:932
static void AtSubCommit_Memory(void)
Definition: xact.c:1583
static void AtSubCommit_childXids(void)
Definition: xact.c:1612
void CommandCounterIncrement(void)
Definition: xact.c:1078
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition: xact.h:145
@ SUBXACT_EVENT_COMMIT_SUB
Definition: xact.h:143

References AfterTriggerEndSubXact(), AtEOSubXact_Files(), AtEOSubXact_HashTables(), AtEOSubXact_Inval(), AtEOSubXact_LargeObject(), AtEOSubXact_Namespace(), AtEOSubXact_on_commit_actions(), AtEOSubXact_Parallel(), AtEOSubXact_PgStat(), AtEOSubXact_RelationCache(), AtEOSubXact_SPI(), AtEOXact_GUC(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubCommit_Notify(), AtSubCommit_Portals(), AtSubCommit_smgr(), AtSubCommit_Snapshot(), CallSubXactCallbacks(), CommandCounterIncrement(), CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog(), TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, 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 2152 of file xact.c.

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

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

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

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 3034 of file xact.c.

3035 {
3038 
3039  /* Must save in case we need to restore below */
3041 
3042  switch (s->blockState)
3043  {
3044  /*
3045  * These shouldn't happen. TBLOCK_DEFAULT means the previous
3046  * StartTransactionCommand didn't set the STARTED state
3047  * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3048  * by EndParallelWorkerTransaction(), not this function.
3049  */
3050  case TBLOCK_DEFAULT:
3052  elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3054  break;
3055 
3056  /*
3057  * If we aren't in a transaction block, just do our usual
3058  * transaction commit, and return to the idle state.
3059  */
3060  case TBLOCK_STARTED:
3063  break;
3064 
3065  /*
3066  * We are completing a "BEGIN TRANSACTION" command, so we change
3067  * to the "transaction block in progress" state and return. (We
3068  * assume the BEGIN did nothing to the database, so we need no
3069  * CommandCounterIncrement.)
3070  */
3071  case TBLOCK_BEGIN:
3073  break;
3074 
3075  /*
3076  * This is the case when we have finished executing a command
3077  * someplace within a transaction block. We increment the command
3078  * counter and return.
3079  */
3080  case TBLOCK_INPROGRESS:
3082  case TBLOCK_SUBINPROGRESS:
3084  break;
3085 
3086  /*
3087  * We are completing a "COMMIT" command. Do it and return to the
3088  * idle state.
3089  */
3090  case TBLOCK_END:
3093  if (s->chain)
3094  {
3095  StartTransaction();
3097  s->chain = false;
3099  }
3100  break;
3101 
3102  /*
3103  * Here we are in the middle of a transaction block but one of the
3104  * commands caused an abort so we do nothing but remain in the
3105  * abort state. Eventually we will get a ROLLBACK command.
3106  */
3107  case TBLOCK_ABORT:
3108  case TBLOCK_SUBABORT:
3109  break;
3110 
3111  /*
3112  * Here we were in an aborted transaction block and we just got
3113  * the ROLLBACK command from the user, so clean up the
3114  * already-aborted transaction and return to the idle state.
3115  */
3116  case TBLOCK_ABORT_END:
3119  if (s->chain)
3120  {
3121  StartTransaction();
3123  s->chain = false;
3125  }
3126  break;
3127 
3128  /*
3129  * Here we were in a perfectly good transaction block but the user
3130  * told us to ROLLBACK anyway. We have to abort the transaction
3131  * and then clean up.
3132  */
3133  case TBLOCK_ABORT_PENDING:
3134  AbortTransaction();
3137  if (s->chain)
3138  {
3139  StartTransaction();
3141  s->chain = false;
3143  }
3144  break;
3145 
3146  /*
3147  * We are completing a "PREPARE TRANSACTION" command. Do it and
3148  * return to the idle state.
3149  */
3150  case TBLOCK_PREPARE:
3153  break;
3154 
3155  /*
3156  * The user issued a SAVEPOINT inside a transaction block. Start a
3157  * subtransaction. (DefineSavepoint already did PushTransaction,
3158  * so as to have someplace to put the SUBBEGIN state.)
3159  */
3160  case TBLOCK_SUBBEGIN:
3163  break;
3164 
3165  /*
3166  * The user issued a RELEASE command, so we end the current
3167  * subtransaction and return to the parent transaction. The parent
3168  * might be ended too, so repeat till we find an INPROGRESS
3169  * transaction or subtransaction.
3170  */
3171  case TBLOCK_SUBRELEASE:
3172  do
3173  {
3175  s = CurrentTransactionState; /* changed by pop */
3176  } while (s->blockState == TBLOCK_SUBRELEASE);
3177 
3180  break;
3181 
3182  /*
3183  * The user issued a COMMIT, so we end the current subtransaction
3184  * hierarchy and perform final commit. We do this by rolling up
3185  * any subtransactions into their parent, which leads to O(N^2)
3186  * operations with respect to resource owners - this isn't that
3187  * bad until we approach a thousands of savepoints but is
3188  * necessary for correctness should after triggers create new
3189  * resource owners.
3190  */
3191  case TBLOCK_SUBCOMMIT:
3192  do
3193  {
3195  s = CurrentTransactionState; /* changed by pop */
3196  } while (s->blockState == TBLOCK_SUBCOMMIT);
3197  /* If we had a COMMIT command, finish off the main xact too */
3198  if (s->blockState == TBLOCK_END)
3199  {
3200  Assert(s->parent == NULL);
3203  if (s->chain)
3204  {
3205  StartTransaction();
3207  s->chain = false;
3209  }
3210  }
3211  else if (s->blockState == TBLOCK_PREPARE)
3212  {
3213  Assert(s->parent == NULL);
3216  }
3217  else
3218  elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3220  break;
3221 
3222  /*
3223  * The current already-failed subtransaction is ending due to a
3224  * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3225  * examine the parent (which could be in any of several states).
3226  */
3227  case TBLOCK_SUBABORT_END:
3230  break;
3231 
3232  /*
3233  * As above, but it's not dead yet, so abort first.
3234  */
3239  break;
3240 
3241  /*
3242  * The current subtransaction is the target of a ROLLBACK TO
3243  * command. Abort and pop it, then start a new subtransaction
3244  * with the same name.
3245  */
3246  case TBLOCK_SUBRESTART:
3247  {
3248  char *name;
3249  int savepointLevel;
3250 
3251  /* save name and keep Cleanup from freeing it */
3252  name = s->name;
3253  s->name = NULL;
3254  savepointLevel = s->savepointLevel;
3255 
3258 
3259  DefineSavepoint(NULL);
3260  s = CurrentTransactionState; /* changed by push */
3261  s->name = name;
3262  s->savepointLevel = savepointLevel;
3263 
3264  /* This is the same as TBLOCK_SUBBEGIN case */
3268  }
3269  break;
3270 
3271  /*
3272  * Same as above, but the subtransaction had already failed, so we
3273  * don't need AbortSubTransaction.
3274  */
3276  {
3277  char *name;
3278  int savepointLevel;
3279 
3280  /* save name and keep Cleanup from freeing it */
3281  name = s->name;
3282  s->name = NULL;
3283  savepointLevel = s->savepointLevel;
3284 
3286 
3287  DefineSavepoint(NULL);
3288  s = CurrentTransactionState; /* changed by push */
3289  s->name = name;
3290  s->savepointLevel = savepointLevel;
3291 
3292  /* This is the same as TBLOCK_SUBBEGIN case */
3296  }
3297  break;
3298  }
3299 }
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3014
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3022
static void StartTransaction(void)
Definition: xact.c:1993
void DefineSavepoint(const char *name)
Definition: xact.c:4219
static void CommitSubTransaction(void)
Definition: xact.c:4949
static void CommitTransaction(void)
Definition: xact.c:2152
static void PrepareTransaction(void)
Definition: xact.c:2412
static void StartSubTransaction(void)
Definition: xact.c:4912

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

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

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

Definition at line 4219 of file xact.c.

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

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

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 4197 of file xact.c.

4198 {
4200 
4201  /*
4202  * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4203  * allowing CommitTransactionCommand to commit whatever happened during
4204  * the implicit transaction block as though it were a single statement.
4205  *
4206  * For caller convenience, we consider all other transaction states as
4207  * legal here; otherwise the caller would need its own state check, which
4208  * seems rather pointless.
4209  */
4212 }

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

Referenced by exec_simple_query().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 3890 of file xact.c.

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

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

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

◆ EnterParallelMode()

void EnterParallelMode ( void  )

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 5343 of file xact.c.

5344 {
5345  TransactionState s;
5346  Size nxids = 0;
5348 
5349  for (s = CurrentTransactionState; s != NULL; s = s->parent)
5350  {
5352  nxids = add_size(nxids, 1);
5353  nxids = add_size(nxids, s->nChildXids);
5354  }
5355 
5356  return add_size(size, mul_size(sizeof(TransactionId), nxids));
5357 }
size_t Size
Definition: c.h:594
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:233

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

1129 {
1130  forceSyncCommit = true;
1131 }
static bool forceSyncCommit
Definition: xact.c:287

References forceSyncCommit.

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 818 of file xact.c.

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

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

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

◆ GetCurrentFullTransactionId()

FullTransactionId GetCurrentFullTransactionId ( void  )

◆ GetCurrentFullTransactionIdIfAny()

FullTransactionId GetCurrentFullTransactionIdIfAny ( void  )

Definition at line 521 of file xact.c.

522 {
524 }

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 864 of file xact.c.

865 {
866  return stmtStartTimestamp;
867 }
static TimestampTz stmtStartTimestamp
Definition: xact.c:275

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

856 {
857  return xactStartTimestamp;
858 }
static TimestampTz xactStartTimestamp
Definition: xact.c:274

References xactStartTimestamp.

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

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 876 of file xact.c.

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

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

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

◆ GetStableLatestTransactionId()

TransactionId GetStableLatestTransactionId ( void  )

Definition at line 598 of file xact.c.

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

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

Referenced by xid_age().

◆ GetTopFullTransactionId()

◆ GetTopFullTransactionIdIfAny()

FullTransactionId GetTopFullTransactionIdIfAny ( void  )

Definition at line 490 of file xact.c.

491 {
493 }

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3612 of file xact.c.

3613 {
3614  /*
3615  * Return true on same conditions that would make
3616  * PreventInTransactionBlock error out
3617  */
3618  if (IsTransactionBlock())
3619  return true;
3620 
3621  if (IsSubTransaction())
3622  return true;
3623 
3625  return true;
3626 
3627  if (!isTopLevel)
3628  return true;
3629 
3632  return true;
3633 
3634  return false;
3635 }
int MyXactFlags
Definition: xact.c:136
#define XACT_FLAGS_PIPELINING
Definition: xact.h:121

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

Referenced by vacuum().

◆ IsSubTransaction()

◆ IsSubxactTopXidLogPending()

bool IsSubxactTopXidLogPending ( void  )

Definition at line 550 of file xact.c.

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

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

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 378 of file xact.c.

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

References CurrentTransactionState, TransactionStateData::state, and TRANS_INPROGRESS.

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

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

◆ MarkSubxactTopXidLogged()

void MarkSubxactTopXidLogged ( void  )

Definition at line 582 of file xact.c.

583 {
585 
587 }
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:550

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

Referenced by XLogInsertRecord().

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5309 of file xact.c.

5310 {
5312 
5313  if (s->state != TRANS_DEFAULT)
5314  elog(WARNING, "PopTransaction while in %s state",
5316 
5317  if (s->parent == NULL)
5318  elog(FATAL, "PopTransaction with no parent");
5319 
5321 
5322  /* Let's just make sure CurTransactionContext is good */
5325 
5326  /* Ditto for ResourceOwner links */
5329 
5330  /* Free the old child structure */
5331  if (s->name)
5332  pfree(s->name);
5333  pfree(s);
5334 }

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

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

References AfterTriggerEndXact(), AfterTriggerFireDeferred(), Assert(), AtCommit_Memory(), AtEOXact_ApplyLauncher(), AtEOXact_Buffers(), AtEOXact_ComboCid(), AtEOXact_Enum(), AtEOXact_Files(), AtEOXact_GUC(), AtEOXact_HashTables(), AtEOXact_LargeObject(), AtEOXact_LogicalRepWorkers(), AtEOXact_Namespace(), AtEOXact_on_commit_actions(), AtEOXact_RelationCache(), AtEOXact_SMgr(), AtEOXact_Snapshot(), AtEOXact_SPI(), AtPrepare_Locks(), AtPrepare_MultiXact(), AtPrepare_Notify(), AtPrepare_PgStat(), AtPrepare_PredicateLocks(), AtPrepare_RelationMap(), CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, 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 3838 of file xact.c.

3839 {
3840  TransactionState s;
3841  bool result;
3842 
3843  /* Set up to commit the current transaction */
3844  result = EndTransactionBlock(false);
3845 
3846  /* If successful, change outer tblock state to PREPARE */
3847  if (result)
3848  {
3850 
3851  while (s->parent != NULL)
3852  s = s->parent;
3853 
3854  if (s->blockState == TBLOCK_END)
3855  {
3856  /* Save GID where PrepareTransaction can find it again */
3858 
3860  }
3861  else
3862  {
3863  /*
3864  * ignore case where we are not in a transaction;
3865  * EndTransactionBlock already issued a warning.
3866  */
3869  /* Don't send back a PREPARE result tag... */
3870  result = false;
3871  }
3872  }
3873 
3874  return result;
3875 }
bool EndTransactionBlock(bool chain)
Definition: xact.c:3890

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

3482 {
3483  /*
3484  * xact block already started?
3485  */
3486  if (IsTransactionBlock())
3487  ereport(ERROR,
3488  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3489  /* translator: %s represents an SQL statement name */
3490  errmsg("%s cannot run inside a transaction block",
3491  stmtType)));
3492 
3493  /*
3494  * subtransaction?
3495  */
3496  if (IsSubTransaction())
3497  ereport(ERROR,
3498  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3499  /* translator: %s represents an SQL statement name */
3500  errmsg("%s cannot run inside a subtransaction",
3501  stmtType)));
3502 
3503  /*
3504  * inside a pipeline that has started an implicit transaction?
3505  */
3507  ereport(ERROR,
3508  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3509  /* translator: %s represents an SQL statement name */
3510  errmsg("%s cannot be executed within a pipeline",
3511  stmtType)));
3512 
3513  /*
3514  * inside a function call?
3515  */
3516  if (!isTopLevel)
3517  ereport(ERROR,
3518  (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3519  /* translator: %s represents an SQL statement name */
3520  errmsg("%s cannot be executed from a function", stmtType)));
3521 
3522  /* If we got past IsTransactionBlock test, should be in default state */
3525  elog(FATAL, "cannot prevent transaction chain");
3526 
3527  /* All okay. Set the flag to make sure the right thing happens later. */
3529 }
#define XACT_FLAGS_NEEDIMMEDIATECOMMIT
Definition: xact.h:114

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

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

◆ PushTransaction()

static void PushTransaction ( void  )
static

Definition at line 5249 of file xact.c.

5250 {
5252  TransactionState s;
5253 
5254  /*
5255  * We keep subtransaction state nodes in TopTransactionContext.
5256  */
5257  s = (TransactionState)
5259  sizeof(TransactionStateData));
5260 
5261  /*
5262  * Assign a subtransaction ID, watching out for counter wraparound.
5263  */
5266  {
5268  pfree(s);
5269  ereport(ERROR,
5270  (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5271  errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5272  }
5273 
5274  /*
5275  * We can now stack a minimally valid subtransaction without fear of
5276  * failure.
5277  */
5278  s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5280  s->parent = p;
5281  s->nestingLevel = p->nestingLevel + 1;
5284  s->state = TRANS_DEFAULT;
5288  s->parallelModeLevel = 0;
5289  s->topXidLogged = false;
5290 
5292 
5293  /*
5294  * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5295  * with the subtransaction from here on out; in particular they should not
5296  * assume that it necessarily has a transaction context, resource owner,
5297  * or XID.
5298  */
5299 }
int NewGUCNestLevel(void)
Definition: guc.c:2201
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1064
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:630
TransactionStateData * TransactionState
Definition: xact.c:215
static SubTransactionId currentSubTransactionId
Definition: xact.c:260

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

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

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

Referenced by AbortSubTransaction(), and AbortTransaction().

◆ RecordTransactionCommit()

static TransactionId RecordTransactionCommit ( void  )
static

Definition at line 1283 of file xact.c.

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

References Assert(), cleanup(), DELAY_CHKPT_START, PGPROC::delayChkptFlags, DoNotReplicateId, elog(), END_CRIT_SECTION,