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

Go to the source code of this file.

Data Structures

struct  TransactionStateData
 
struct  SerializedTransactionState
 
struct  XactCallbackItem
 
struct  SubXactCallbackItem
 

Macros

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)
 

Typedefs

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

Enumerations

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

Functions

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

Variables

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

Macro Definition Documentation

◆ SerializedTransactionStateHeaderSize

#define SerializedTransactionStateHeaderSize    offsetof(SerializedTransactionState, parallelCurrentXids)

Definition at line 239 of file xact.c.

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

typedef enum TBlockState TBlockState

◆ TransactionState

Definition at line 221 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 */
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 3451 of file xact.c.

3452{
3453 /*
3454 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3455 * done.
3456 */
3458 {
3459 }
3460}
static bool AbortCurrentTransactionInternal(void)
Definition: xact.c:3469

References AbortCurrentTransactionInternal().

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

◆ AbortCurrentTransactionInternal()

static bool AbortCurrentTransactionInternal ( void  )
static

Definition at line 3469 of file xact.c.

3470{
3472
3473 switch (s->blockState)
3474 {
3475 case TBLOCK_DEFAULT:
3476 if (s->state == TRANS_DEFAULT)
3477 {
3478 /* we are idle, so nothing to do */
3479 }
3480 else
3481 {
3482 /*
3483 * We can get here after an error during transaction start
3484 * (state will be TRANS_START). Need to clean up the
3485 * incompletely started transaction. First, adjust the
3486 * low-level state to suppress warning message from
3487 * AbortTransaction.
3488 */
3489 if (s->state == TRANS_START)
3493 }
3494 break;
3495
3496 /*
3497 * If we aren't in a transaction block, we just do the basic abort
3498 * & cleanup transaction. For this purpose, we treat an implicit
3499 * transaction block as if it were a simple statement.
3500 */
3501 case TBLOCK_STARTED:
3506 break;
3507
3508 /*
3509 * If we are in TBLOCK_BEGIN it means something screwed up right
3510 * after reading "BEGIN TRANSACTION". We assume that the user
3511 * will interpret the error as meaning the BEGIN failed to get him
3512 * into a transaction block, so we should abort and return to idle
3513 * state.
3514 */
3515 case TBLOCK_BEGIN:
3519 break;
3520
3521 /*
3522 * We are somewhere in a transaction block and we've gotten a
3523 * failure, so we abort the transaction and set up the persistent
3524 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3525 */
3526 case TBLOCK_INPROGRESS:
3530 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3531 break;
3532
3533 /*
3534 * Here, we failed while trying to COMMIT. Clean up the
3535 * transaction and return to idle state (we do not want to stay in
3536 * the transaction).
3537 */
3538 case TBLOCK_END:
3542 break;
3543
3544 /*
3545 * Here, we are already in an aborted transaction state and are
3546 * waiting for a ROLLBACK, but for some reason we failed again! So
3547 * we just remain in the abort state.
3548 */
3549 case TBLOCK_ABORT:
3550 case TBLOCK_SUBABORT:
3551 break;
3552
3553 /*
3554 * We are in a failed transaction and we got the ROLLBACK command.
3555 * We have already aborted, we just need to cleanup and go to idle
3556 * state.
3557 */
3558 case TBLOCK_ABORT_END:
3561 break;
3562
3563 /*
3564 * We are in a live transaction and we got a ROLLBACK command.
3565 * Abort, cleanup, go to idle state.
3566 */
3571 break;
3572
3573 /*
3574 * Here, we failed while trying to PREPARE. Clean up the
3575 * transaction and return to idle state (we do not want to stay in
3576 * the transaction).
3577 */
3578 case TBLOCK_PREPARE:
3582 break;
3583
3584 /*
3585 * We got an error inside a subtransaction. Abort just the
3586 * subtransaction, and go to the persistent SUBABORT state until
3587 * we get ROLLBACK.
3588 */
3592 break;
3593
3594 /*
3595 * If we failed while trying to create a subtransaction, clean up
3596 * the broken subtransaction and abort the parent. The same
3597 * applies if we get a failure while ending a subtransaction. As
3598 * we need to abort the parent, return false to request the caller
3599 * to do the next iteration.
3600 */
3601 case TBLOCK_SUBBEGIN:
3602 case TBLOCK_SUBRELEASE:
3603 case TBLOCK_SUBCOMMIT:
3605 case TBLOCK_SUBRESTART:
3608 return false;
3609
3610 /*
3611 * Same as above, except the Abort() was already done.
3612 */
3616 return false;
3617 }
3618
3619 /* Done, no more iterations required */
3620 return true;
3621}
TransState state
Definition: xact.c:199
TBlockState blockState
Definition: xact.c:200
static void CleanupSubTransaction(void)
Definition: xact.c:5383
static void CleanupTransaction(void)
Definition: xact.c:3009
static void AbortSubTransaction(void)
Definition: xact.c:5219
static void AbortTransaction(void)
Definition: xact.c:2809
static TransactionState CurrentTransactionState
Definition: xact.c:260

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

Referenced by AbortCurrentTransaction().

◆ AbortOutOfAnyTransaction()

void AbortOutOfAnyTransaction ( void  )

Definition at line 4862 of file xact.c.

4863{
4865
4866 /* Ensure we're not running in a doomed memory context */
4868
4869 /*
4870 * Get out of any transaction or nested transaction
4871 */
4872 do
4873 {
4874 switch (s->blockState)
4875 {
4876 case TBLOCK_DEFAULT:
4877 if (s->state == TRANS_DEFAULT)
4878 {
4879 /* Not in a transaction, do nothing */
4880 }
4881 else
4882 {
4883 /*
4884 * We can get here after an error during transaction start
4885 * (state will be TRANS_START). Need to clean up the
4886 * incompletely started transaction. First, adjust the
4887 * low-level state to suppress warning message from
4888 * AbortTransaction.
4889 */
4890 if (s->state == TRANS_START)
4894 }
4895 break;
4896 case TBLOCK_STARTED:
4897 case TBLOCK_BEGIN:
4898 case TBLOCK_INPROGRESS:
4901 case TBLOCK_END:
4903 case TBLOCK_PREPARE:
4904 /* In a transaction, so clean up */
4908 break;
4909 case TBLOCK_ABORT:
4910 case TBLOCK_ABORT_END:
4911
4912 /*
4913 * AbortTransaction is already done, still need Cleanup.
4914 * However, if we failed partway through running ROLLBACK,
4915 * there will be an active portal running that command, which
4916 * we need to shut down before doing CleanupTransaction.
4917 */
4921 break;
4922
4923 /*
4924 * In a subtransaction, so clean it up and abort parent too
4925 */
4926 case TBLOCK_SUBBEGIN:
4928 case TBLOCK_SUBRELEASE:
4929 case TBLOCK_SUBCOMMIT:
4931 case TBLOCK_SUBRESTART:
4934 s = CurrentTransactionState; /* changed by pop */
4935 break;
4936
4937 case TBLOCK_SUBABORT:
4940 /* As above, but AbortSubTransaction already done */
4941 if (s->curTransactionOwner)
4942 {
4943 /* As in TBLOCK_ABORT, might have a live portal to zap */
4948 }
4950 s = CurrentTransactionState; /* changed by pop */
4951 break;
4952 }
4953 } while (s->blockState != TBLOCK_DEFAULT);
4954
4955 /* Should be out of all subxacts now */
4956 Assert(s->parent == NULL);
4957
4958 /*
4959 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4960 * whether there were any transactions to close or not. (Callers that
4961 * don't intend to exit soon should switch to some other context to avoid
4962 * long-term memory leaks.)
4963 */
4965}
Assert(PointerIsAligned(start, uint64))
MemoryContext TopMemoryContext
Definition: mcxt.c:165
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
void AtAbort_Portals(void)
Definition: portalmem.c:783
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:981
SubTransactionId subTransactionId
Definition: xact.c:196
struct TransactionStateData * parent
Definition: xact.c:218
ResourceOwner curTransactionOwner
Definition: xact.c:204
static void AtAbort_Memory(void)
Definition: xact.c:1884

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

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

◆ AbortSubTransaction()

static void AbortSubTransaction ( void  )
static

Definition at line 5219 of file xact.c.

5220{
5222
5223 /* Prevent cancel/die interrupt while cleaning up */
5225
5226 /* Make sure we have a valid memory context and resource owner */
5229
5230 /*
5231 * Release any LW locks we might be holding as quickly as possible.
5232 * (Regular locks, however, must be held till we finish aborting.)
5233 * Releasing LW locks is critical since we might try to grab them again
5234 * while cleaning up!
5235 *
5236 * FIXME This may be incorrect --- Are there some locks we should keep?
5237 * Buffer locks, for example? I don't think so but I'm not sure.
5238 */
5240
5243
5245
5246 UnlockBuffers();
5247
5248 /* Reset WAL record construction state */
5250
5251 /* Cancel condition variable sleep */
5253
5254 /*
5255 * Also clean up any open wait for lock, since the lock manager will choke
5256 * if we try to wait for another lock before doing this.
5257 */
5259
5260 /*
5261 * If any timeout events are still active, make sure the timeout interrupt
5262 * is scheduled. This covers possible loss of a timeout interrupt due to
5263 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5264 * We delay this till after LockErrorCleanup so that we don't uselessly
5265 * reschedule lock or deadlock check timeouts.
5266 */
5268
5269 /*
5270 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5271 * handler. We do this fairly early in the sequence so that the timeout
5272 * infrastructure will be functional if needed while aborting.
5273 */
5274 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5275
5276 /*
5277 * check the current transaction state
5278 */
5279 ShowTransactionState("AbortSubTransaction");
5280
5281 if (s->state != TRANS_INPROGRESS)
5282 elog(WARNING, "AbortSubTransaction while in %s state",
5284
5285 s->state = TRANS_ABORT;
5286
5287 /*
5288 * Reset user ID which might have been changed transiently. (See notes in
5289 * AbortTransaction.)
5290 */
5292
5293 /* Forget about any active REINDEX. */
5295
5296 /* Reset logical streaming state. */
5298
5299 /*
5300 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5301 * exports are not supported in subtransactions.
5302 */
5303
5304 /*
5305 * If this subxact has started any unfinished parallel operation, clean up
5306 * its workers and exit parallel mode. Don't warn about leaked resources.
5307 */
5309 s->parallelModeLevel = 0;
5310
5311 /*
5312 * We can skip all this stuff if the subxact failed before creating a
5313 * ResourceOwner...
5314 */
5315 if (s->curTransactionOwner)
5316 {
5325
5326 /* Advertise the fact that we aborted in pg_xact. */
5327 (void) RecordTransactionAbort(true);
5328
5329 /* Post-abort cleanup */
5332
5335
5338 false, false);
5339
5340 AtEOXact_Aio(false);
5344 AtEOSubXact_Inval(false);
5347 false, false);
5350 false, false);
5352
5353 AtEOXact_GUC(false, s->gucNestLevel);
5364 }
5365
5366 /*
5367 * Restore the upper transaction's read-only state, too. This should be
5368 * redundant with GUC's cleanup but we may as well do it for consistency
5369 * with the commit case.
5370 */
5372
5374}
void pgaio_error_cleanup(void)
Definition: aio.c:1062
void AtEOXact_Aio(bool is_commit)
Definition: aio.c:1090
void AtSubAbort_Notify(void)
Definition: async.c:1761
void AtEOSubXact_Parallel(bool isCommit, SubTransactionId mySubId)
Definition: parallel.c:1254
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:653
void UnlockBuffers(void)
Definition: bufmgr.c:5509
bool ConditionVariableCancelSleep(void)
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1938
#define WARNING
Definition: elog.h:36
#define elog(elevel,...)
Definition: elog.h:226
void AtEOSubXact_Files(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: fd.c:3196
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2262
void ResetReindexState(int nestLevel)
Definition: index.c:4213
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1303
void ResetLogicalStreamingState(void)
Definition: logical.c:1905
void LWLockReleaseAll(void)
Definition: lwlock.c:1953
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:136
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:134
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:670
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: namespace.c:4558
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:113
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3364
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:658
@ RESOURCE_RELEASE_LOCKS
Definition: resowner.h:55
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition: resowner.h:54
@ RESOURCE_RELEASE_AFTER_LOCKS
Definition: resowner.h:56
void AtSubAbort_Snapshot(int level)
Definition: snapmgr.c:969
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition: spi.c:483
void LockErrorCleanup(void)
Definition: proc.c:814
void AtSubAbort_smgr(void)
Definition: storage.c:975
int parallelModeLevel
Definition: xact.c:214
FullTransactionId fullTransactionId
Definition: xact.c:195
bool prevXactReadOnly
Definition: xact.c:211
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:19351
void reschedule_timeouts(void)
Definition: timeout.c:540
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5399
void AtEOSubXact_TypeCache(void)
Definition: typcache.c:3186
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3898
static void AtSubAbort_Memory(void)
Definition: xact.c:1904
static const char * TransStateAsString(TransState state)
Definition: xact.c:5760
bool XactReadOnly
Definition: xact.c:82
static void AtSubAbort_childXids(void)
Definition: xact.c:1942
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1929
static void ShowTransactionState(const char *str)
Definition: xact.c:5648
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1754
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:144
void XLogResetInsertion(void)
Definition: xloginsert.c:222

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

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), CommitTransactionCommandInternal(), and RollbackAndReleaseCurrentSubTransaction().

◆ AbortTransaction()

static void AbortTransaction ( void  )
static

Definition at line 2809 of file xact.c.

2810{
2812 TransactionId latestXid;
2813 bool is_parallel_worker;
2814
2815 /* Prevent cancel/die interrupt while cleaning up */
2817
2818 /* Disable transaction timeout */
2819 if (TransactionTimeout > 0)
2821
2822 /* Make sure we have a valid memory context and resource owner */
2825
2826 /*
2827 * Release any LW locks we might be holding as quickly as possible.
2828 * (Regular locks, however, must be held till we finish aborting.)
2829 * Releasing LW locks is critical since we might try to grab them again
2830 * while cleaning up!
2831 */
2833
2834 /* Clear wait information and command progress indicator */
2837
2839
2840 /* Clean up buffer content locks, too */
2841 UnlockBuffers();
2842
2843 /* Reset WAL record construction state */
2845
2846 /* Cancel condition variable sleep */
2848
2849 /*
2850 * Also clean up any open wait for lock, since the lock manager will choke
2851 * if we try to wait for another lock before doing this.
2852 */
2854
2855 /*
2856 * If any timeout events are still active, make sure the timeout interrupt
2857 * is scheduled. This covers possible loss of a timeout interrupt due to
2858 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2859 * We delay this till after LockErrorCleanup so that we don't uselessly
2860 * reschedule lock or deadlock check timeouts.
2861 */
2863
2864 /*
2865 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2866 * handler. We do this fairly early in the sequence so that the timeout
2867 * infrastructure will be functional if needed while aborting.
2868 */
2869 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2870
2871 /*
2872 * check the current transaction state
2873 */
2874 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2875 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2876 elog(WARNING, "AbortTransaction while in %s state",
2878 Assert(s->parent == NULL);
2879
2880 /*
2881 * set the current transaction state information appropriately during the
2882 * abort processing
2883 */
2884 s->state = TRANS_ABORT;
2885
2886 /*
2887 * Reset user ID which might have been changed transiently. We need this
2888 * to clean up in case control escaped out of a SECURITY DEFINER function
2889 * or other local change of CurrentUserId; therefore, the prior value of
2890 * SecurityRestrictionContext also needs to be restored.
2891 *
2892 * (Note: it is not necessary to restore session authorization or role
2893 * settings here because those can only be changed via GUC, and GUC will
2894 * take care of rolling them back if need be.)
2895 */
2897
2898 /* Forget about any active REINDEX. */
2900
2901 /* Reset logical streaming state. */
2903
2904 /* Reset snapshot export state. */
2906
2907 /*
2908 * If this xact has started any unfinished parallel operation, clean up
2909 * its workers and exit parallel mode. Don't warn about leaked resources.
2910 */
2911 AtEOXact_Parallel(false);
2912 s->parallelModeLevel = 0;
2913 s->parallelChildXact = false; /* should be false already */
2914
2915 /*
2916 * do abort processing
2917 */
2918 AfterTriggerEndXact(false); /* 'false' means it's abort */
2920 smgrDoPendingSyncs(false, is_parallel_worker);
2921 AtEOXact_LargeObject(false);
2923 AtEOXact_RelationMap(false, is_parallel_worker);
2925
2926 /*
2927 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2928 * far as assigning an XID to advertise). But if we're inside a parallel
2929 * worker, skip this; the user backend must be the one to write the abort
2930 * record.
2931 */
2932 if (!is_parallel_worker)
2933 latestXid = RecordTransactionAbort(false);
2934 else
2935 {
2936 latestXid = InvalidTransactionId;
2937
2938 /*
2939 * Since the parallel leader won't get our value of XactLastRecEnd in
2940 * this case, we nudge WAL-writer ourselves in this case. See related
2941 * comments in RecordTransactionAbort for why this matters.
2942 */
2944 }
2945
2946 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2947
2948 /*
2949 * Let others know about no transaction in progress by me. Note that this
2950 * must be done _before_ releasing locks we hold and _after_
2951 * RecordTransactionAbort.
2952 */
2953 ProcArrayEndTransaction(MyProc, latestXid);
2954
2955 /*
2956 * Post-abort cleanup. See notes in CommitTransaction() concerning
2957 * ordering. We can skip all of it if the transaction failed before
2958 * creating a resource owner.
2959 */
2960 if (TopTransactionResourceOwner != NULL)
2961 {
2962 if (is_parallel_worker)
2964 else
2966
2969 false, true);
2970 AtEOXact_Aio(false);
2971 AtEOXact_Buffers(false);
2974 AtEOXact_Inval(false);
2978 false, true);
2981 false, true);
2982 smgrDoPendingDeletes(false);
2983
2984 AtEOXact_GUC(false, 1);
2985 AtEOXact_SPI(false);
2986 AtEOXact_Enum();
2988 AtEOXact_Namespace(false, is_parallel_worker);
2989 AtEOXact_SMgr();
2990 AtEOXact_Files(false);
2992 AtEOXact_HashTables(false);
2993 AtEOXact_PgStat(false, is_parallel_worker);
2997 }
2998
2999 /*
3000 * State remains TRANS_ABORT until CleanupTransaction().
3001 */
3003}
void AtAbort_Notify(void)
Definition: async.c:1671
void AtEOXact_Parallel(bool isCommit)
Definition: parallel.c:1275
void AtEOXact_LogicalRepWorkers(bool isCommit)
Definition: worker.c:5125
void pgstat_report_xact_timestamp(TimestampTz tstamp)
void AtEOXact_LargeObject(bool isCommit)
Definition: be-fsstubs.c:607
void AtEOXact_Buffers(bool isCommit)
Definition: bufmgr.c:3989
uint32 TransactionId
Definition: c.h:623
void AtEOXact_ComboCid(void)
Definition: combocid.c:182
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1912
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3229
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1192
void AtEOXact_ApplyLauncher(bool isCommit)
Definition: launcher.c:1083
void AtEOXact_MultiXact(void)
Definition: multixact.c:1808
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition: namespace.c:4512
void AtEOXact_Enum(void)
Definition: pg_enum.c:726
void AtEOXact_PgStat(bool isCommit, bool parallel)
Definition: pgstat_xact.c:40
void ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
Definition: procarray.c:667
void AtEOXact_RelationCache(bool isCommit)
Definition: relcache.c:3212
void AtEOXact_RelationMap(bool isCommit, bool isParallelWorker)
Definition: relmapper.c:541
ResourceOwner TopTransactionResourceOwner
Definition: resowner.c:175
void AtEOXact_SMgr(void)
Definition: smgr.c:1008
void SnapBuildResetExportedSnapshotState(void)
Definition: snapbuild.c:627
void AtEOXact_SPI(bool isCommit)
Definition: spi.c:429
PGPROC * MyProc
Definition: proc.c:67
int TransactionTimeout
Definition: proc.c:62
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:741
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:673
struct PGPROC::@127 vxid
LocalTransactionId lxid
Definition: proc.h:201
bool parallelChildXact
Definition: xact.c:215
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:19319
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:685
@ TRANSACTION_TIMEOUT
Definition: timeout.h:34
#define InvalidTransactionId
Definition: transam.h:31
void AfterTriggerEndXact(bool isCommit)
Definition: trigger.c:5303
void AtAbort_Twophase(void)
Definition: twophase.c:304
void AtEOXact_TypeCache(void)
Definition: typcache.c:3180
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1916
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3838
@ XACT_EVENT_ABORT
Definition: xact.h:130
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:131
XLogRecPtr XactLastRecEnd
Definition: xlog.c:254
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2752

References AfterTriggerEndXact(), Assert(), AtAbort_Memory(), AtAbort_Notify(), AtAbort_Portals(), AtAbort_ResourceOwner(), AtAbort_Twophase(), AtEOXact_Aio(), 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(), AtEOXact_TypeCache(), TransactionStateData::blockState, CallXactCallbacks(), ConditionVariableCancelSleep(), CurrentTransactionState, disable_timeout(), elog, HOLD_INTERRUPTS, InvalidTransactionId, LockErrorCleanup(), LWLockReleaseAll(), PGPROC::lxid, MyProc, TransactionStateData::nestingLevel, TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pgaio_error_cleanup(), pgstat_progress_end_command(), pgstat_report_wait_end(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, ProcArrayEndTransaction(), RecordTransactionAbort(), reschedule_timeouts(), ResetLogicalStreamingState(), ResetReindexState(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerRelease(), RESUME_INTERRUPTS, SetUserIdAndSecContext(), smgrDoPendingDeletes(), smgrDoPendingSyncs(), SnapBuildResetExportedSnapshotState(), TransactionStateData::state, TBLOCK_PARALLEL_INPROGRESS, TopTransactionResourceOwner, TRANS_ABORT, TRANS_INPROGRESS, TRANS_PREPARE, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), UnBlockSig, UnlockBuffers(), PGPROC::vxid, WARNING, XACT_EVENT_ABORT, XACT_EVENT_PARALLEL_ABORT, XactLastRecEnd, XLogResetInsertion(), and XLogSetAsyncXactLSN().

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), and CommitTransactionCommandInternal().

◆ AssignTransactionId()

static void AssignTransactionId ( TransactionState  s)
static

Definition at line 635 of file xact.c.

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

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

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

◆ AtAbort_Memory()

static void AtAbort_Memory ( void  )
static

Definition at line 1884 of file xact.c.

1885{
1886 /*
1887 * Switch into TransactionAbortContext, which should have some free space
1888 * even if nothing else does. We'll work in this context until we've
1889 * finished cleaning up.
1890 *
1891 * It is barely possible to get here when we've not been able to create
1892 * TransactionAbortContext yet; if so use TopMemoryContext.
1893 */
1894 if (TransactionAbortContext != NULL)
1896 else
1898}
static MemoryContext TransactionAbortContext
Definition: xact.c:303

References MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1916 of file xact.c.

1917{
1918 /*
1919 * Make sure we have a valid ResourceOwner, if possible (else it will be
1920 * NULL, which is OK)
1921 */
1923}

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1579 of file xact.c.

1580{
1581 /*
1582 * Make any pending relation map changes visible. We must do this before
1583 * processing local sinval messages, so that the map changes will get
1584 * reflected into the relcache when relcache invals are processed.
1585 */
1587
1588 /*
1589 * Make catalog changes visible to me for the next command.
1590 */
1592}
void CommandEndInvalidationMessages(void)
Definition: inval.c:1402
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 1974 of file xact.c.

1975{
1977
1978 /* Should be at top level */
1979 Assert(s->parent == NULL);
1980
1981 /*
1982 * Return to the memory context that was current before we started the
1983 * transaction. (In principle, this could not be any of the contexts we
1984 * are about to delete. If it somehow is, assertions in mcxt.c will
1985 * complain.)
1986 */
1988
1989 /*
1990 * Clear the special abort context for next time.
1991 */
1992 if (TransactionAbortContext != NULL)
1994
1995 /*
1996 * Release all transaction-local memory, the same as in AtCommit_Memory,
1997 * except we must cope with the possibility that we didn't get as far as
1998 * creating TopTransactionContext.
1999 */
2000 if (TopTransactionContext != NULL)
2002
2003 /*
2004 * Clear these pointers as a pro-forma matter. (Notionally, while
2005 * TopTransactionContext still exists, it's currently not associated with
2006 * this TransactionState struct.)
2007 */
2008 CurTransactionContext = NULL;
2009 s->curTransactionContext = NULL;
2010}
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:414
MemoryContext TopTransactionContext
Definition: mcxt.c:170
MemoryContext CurTransactionContext
Definition: mcxt.c:171
MemoryContext priorContext
Definition: xact.c:205
MemoryContext curTransactionContext
Definition: xact.c:203

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

Referenced by CleanupTransaction().

◆ AtCommit_Memory()

static void AtCommit_Memory ( void  )
static

Definition at line 1598 of file xact.c.

1599{
1601
1602 /*
1603 * Return to the memory context that was current before we started the
1604 * transaction. (In principle, this could not be any of the contexts we
1605 * are about to delete. If it somehow is, assertions in mcxt.c will
1606 * complain.)
1607 */
1609
1610 /*
1611 * Release all transaction-local memory. TopTransactionContext survives
1612 * but becomes empty; any sub-contexts go away.
1613 */
1616
1617 /*
1618 * Clear these pointers as a pro-forma matter. (Notionally, while
1619 * TopTransactionContext still exists, it's currently not associated with
1620 * this TransactionState struct.)
1621 */
1622 CurTransactionContext = NULL;
1623 s->curTransactionContext = NULL;
1624}

References Assert(), CurrentTransactionState, TransactionStateData::curTransactionContext, CurTransactionContext, MemoryContextReset(), MemoryContextSwitchTo(), TransactionStateData::priorContext, and TopTransactionContext.

Referenced by CommitTransaction(), and PrepareTransaction().

◆ AtStart_Cache()

static void AtStart_Cache ( void  )
static

Definition at line 1167 of file xact.c.

1168{
1170}
void AcceptInvalidationMessages(void)
Definition: inval.c:929

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1176 of file xact.c.

1177{
1179
1180 /*
1181 * Remember the memory context that was active prior to transaction start.
1182 */
1184
1185 /*
1186 * If this is the first time through, create a private context for
1187 * AbortTransaction to work in. By reserving some space now, we can
1188 * insulate AbortTransaction from out-of-memory scenarios. Like
1189 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1190 * size, so that space will be reserved immediately.
1191 */
1192 if (TransactionAbortContext == NULL)
1195 "TransactionAbortContext",
1196 32 * 1024,
1197 32 * 1024,
1198 32 * 1024);
1199
1200 /*
1201 * Likewise, if this is the first time through, create a top-level context
1202 * for transaction-local data. This context will be reset at transaction
1203 * end, and then re-used in later transactions.
1204 */
1205 if (TopTransactionContext == NULL)
1208 "TopTransactionContext",
1210
1211 /*
1212 * In a top-level transaction, CurTransactionContext is the same as
1213 * TopTransactionContext.
1214 */
1217
1218 /* Make the CurTransactionContext active. */
1220}
MemoryContext CurrentMemoryContext
Definition: mcxt.c:159
#define AllocSetContextCreate
Definition: memutils.h:149
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:180

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

Referenced by StartTransaction().

◆ AtStart_ResourceOwner()

static void AtStart_ResourceOwner ( void  )
static

Definition at line 1226 of file xact.c.

1227{
1229
1230 /*
1231 * We shouldn't have a transaction resource owner already.
1232 */
1234
1235 /*
1236 * Create a toplevel resource owner for the transaction.
1237 */
1238 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1239
1243}
ResourceOwner ResourceOwnerCreate(ResourceOwner parent, const char *name)
Definition: resowner.c:421
ResourceOwner CurTransactionResourceOwner
Definition: resowner.c:174

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

Referenced by StartTransaction().

◆ AtSubAbort_childXids()

static void AtSubAbort_childXids ( void  )
static

Definition at line 1942 of file xact.c.

1943{
1945
1946 /*
1947 * We keep the child-XID arrays in TopTransactionContext (see
1948 * AtSubCommit_childXids). This means we'd better free the array
1949 * explicitly at abort to avoid leakage.
1950 */
1951 if (s->childXids != NULL)
1952 pfree(s->childXids);
1953 s->childXids = NULL;
1954 s->nChildXids = 0;
1955 s->maxChildXids = 0;
1956
1957 /*
1958 * We could prune the unreportedXids array here. But we don't bother. That
1959 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1960 * would likely introduce more CPU time into the more common paths, so we
1961 * choose not to do that.
1962 */
1963}
TransactionId * childXids
Definition: xact.c:206

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

Definition at line 1904 of file xact.c.

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1929 of file xact.c.

1930{
1932
1933 /* Make sure we have a valid ResourceOwner */
1935}

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 2022 of file xact.c.

2023{
2025
2026 Assert(s->parent != NULL);
2027
2028 /*
2029 * Return to the memory context that was current before we started the
2030 * subtransaction. (In principle, this could not be any of the contexts
2031 * we are about to delete. If it somehow is, assertions in mcxt.c will
2032 * complain.)
2033 */
2035
2036 /* Update CurTransactionContext (might not be same as priorContext) */
2038
2039 /*
2040 * Clear the special abort context for next time.
2041 */
2042 if (TransactionAbortContext != NULL)
2044
2045 /*
2046 * Delete the subxact local memory contexts. Its CurTransactionContext can
2047 * go too (note this also kills CurTransactionContexts from any children
2048 * of the subxact).
2049 */
2050 if (s->curTransactionContext)
2052 s->curTransactionContext = NULL;
2053}
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:485

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

Referenced by CleanupSubTransaction().

◆ AtSubCommit_childXids()

static void AtSubCommit_childXids ( void  )
static

Definition at line 1664 of file xact.c.

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

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

1636{
1638
1639 Assert(s->parent != NULL);
1640
1641 /* Return to parent transaction level's memory context. */
1644
1645 /*
1646 * Ordinarily we cannot throw away the child's CurTransactionContext,
1647 * since the data it contains will be needed at upper commit. However, if
1648 * there isn't actually anything in it, we can throw it away. This avoids
1649 * a small memory leak in the common case of "trivial" subxacts.
1650 */
1652 {
1654 s->curTransactionContext = NULL;
1655 }
1656}
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:774

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

1255{
1257
1259
1260 /*
1261 * Remember the context that was active prior to subtransaction start.
1262 */
1264
1265 /*
1266 * Create a CurTransactionContext, which will be used to hold data that
1267 * survives subtransaction commit but disappears on subtransaction abort.
1268 * We make it a child of the immediate parent's CurTransactionContext.
1269 */
1271 "CurTransactionContext",
1274
1275 /* Make the CurTransactionContext active. */
1277}

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

Referenced by StartSubTransaction().

◆ AtSubStart_ResourceOwner()

static void AtSubStart_ResourceOwner ( void  )
static

Definition at line 1283 of file xact.c.

1284{
1286
1287 Assert(s->parent != NULL);
1288
1289 /*
1290 * Create a resource owner for the subtransaction. We make it a child of
1291 * the immediate parent's resource owner.
1292 */
1295 "SubTransaction");
1296
1299}

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

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4326 of file xact.c.

4327{
4329
4330 /*
4331 * If we are in STARTED state (that is, no transaction block is open),
4332 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4333 * block.
4334 *
4335 * For caller convenience, we consider all other transaction states as
4336 * legal here; otherwise the caller would need its own state check, which
4337 * seems rather pointless.
4338 */
4339 if (s->blockState == TBLOCK_STARTED)
4341}

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

Referenced by exec_simple_query(), and start_xact_command().

◆ BeginInternalSubTransaction()

void BeginInternalSubTransaction ( const char *  name)

Definition at line 4694 of file xact.c.

4695{
4697 bool save_ExitOnAnyError = ExitOnAnyError;
4698
4699 /*
4700 * Errors within this function are improbable, but if one does happen we
4701 * force a FATAL exit. Callers generally aren't prepared to handle losing
4702 * control, and moreover our transaction state is probably corrupted if we
4703 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4704 */
4705 ExitOnAnyError = true;
4706
4707 /*
4708 * We do not check for parallel mode here. It's permissible to start and
4709 * end "internal" subtransactions while in parallel mode, so long as no
4710 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4711 * AssignTransactionId() and CommandCounterIncrement().
4712 */
4713
4714 switch (s->blockState)
4715 {
4716 case TBLOCK_STARTED:
4717 case TBLOCK_INPROGRESS:
4720 case TBLOCK_END:
4721 case TBLOCK_PREPARE:
4723 /* Normal subtransaction start */
4725 s = CurrentTransactionState; /* changed by push */
4726
4727 /*
4728 * Savepoint names, like the TransactionState block itself, live
4729 * in TopTransactionContext.
4730 */
4731 if (name)
4733 break;
4734
4735 /* These cases are invalid. */
4736 case TBLOCK_DEFAULT:
4737 case TBLOCK_BEGIN:
4738 case TBLOCK_SUBBEGIN:
4739 case TBLOCK_SUBRELEASE:
4740 case TBLOCK_SUBCOMMIT:
4741 case TBLOCK_ABORT:
4742 case TBLOCK_SUBABORT:
4743 case TBLOCK_ABORT_END:
4747 case TBLOCK_SUBRESTART:
4749 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4751 break;
4752 }
4753
4756
4757 ExitOnAnyError = save_ExitOnAnyError;
4758}
#define FATAL
Definition: elog.h:41
bool ExitOnAnyError
Definition: globals.c:124
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:2309
const char * name
static void PushTransaction(void)
Definition: xact.c:5416
void StartTransactionCommand(void)
Definition: xact.c:3059
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5707
void CommitTransactionCommand(void)
Definition: xact.c:3157

References TransactionStateData::blockState, BlockStateAsString(), CommitTransactionCommand(), CurrentTransactionState, elog, ExitOnAnyError, FATAL, MemoryContextStrdup(), TransactionStateData::name, name, PushTransaction(), StartTransactionCommand(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, TBLOCK_SUBRESTART, and TopTransactionContext.

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_returnnext(), pltcl_subtrans_begin(), pltcl_subtransaction(), PLy_spi_subtransaction_begin(), PLy_subtransaction_enter(), ReorderBufferImmediateInvalidation(), and ReorderBufferProcessTXN().

◆ BeginTransactionBlock()

void BeginTransactionBlock ( void  )

Definition at line 3924 of file xact.c.

3925{
3927
3928 switch (s->blockState)
3929 {
3930 /*
3931 * We are not inside a transaction block, so allow one to begin.
3932 */
3933 case TBLOCK_STARTED:
3935 break;
3936
3937 /*
3938 * BEGIN converts an implicit transaction block to a regular one.
3939 * (Note that we allow this even if we've already done some
3940 * commands, which is a bit odd but matches historical practice.)
3941 */
3944 break;
3945
3946 /*
3947 * Already a transaction block in progress.
3948 */
3949 case TBLOCK_INPROGRESS:
3952 case TBLOCK_ABORT:
3953 case TBLOCK_SUBABORT:
3955 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3956 errmsg("there is already a transaction in progress")));
3957 break;
3958
3959 /* These cases are invalid. */
3960 case TBLOCK_DEFAULT:
3961 case TBLOCK_BEGIN:
3962 case TBLOCK_SUBBEGIN:
3963 case TBLOCK_END:
3964 case TBLOCK_SUBRELEASE:
3965 case TBLOCK_SUBCOMMIT:
3966 case TBLOCK_ABORT_END:
3970 case TBLOCK_SUBRESTART:
3972 case TBLOCK_PREPARE:
3973 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3975 break;
3976 }
3977}

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

5708{
5709 switch (blockState)
5710 {
5711 case TBLOCK_DEFAULT:
5712 return "DEFAULT";
5713 case TBLOCK_STARTED:
5714 return "STARTED";
5715 case TBLOCK_BEGIN:
5716 return "BEGIN";
5717 case TBLOCK_INPROGRESS:
5718 return "INPROGRESS";
5720 return "IMPLICIT_INPROGRESS";
5722 return "PARALLEL_INPROGRESS";
5723 case TBLOCK_END:
5724 return "END";
5725 case TBLOCK_ABORT:
5726 return "ABORT";
5727 case TBLOCK_ABORT_END:
5728 return "ABORT_END";
5730 return "ABORT_PENDING";
5731 case TBLOCK_PREPARE:
5732 return "PREPARE";
5733 case TBLOCK_SUBBEGIN:
5734 return "SUBBEGIN";
5736 return "SUBINPROGRESS";
5737 case TBLOCK_SUBRELEASE:
5738 return "SUBRELEASE";
5739 case TBLOCK_SUBCOMMIT:
5740 return "SUBCOMMIT";
5741 case TBLOCK_SUBABORT:
5742 return "SUBABORT";
5744 return "SUBABORT_END";
5746 return "SUBABORT_PENDING";
5747 case TBLOCK_SUBRESTART:
5748 return "SUBRESTART";
5750 return "SUBABORT_RESTART";
5751 }
5752 return "UNRECOGNIZED";
5753}

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

Referenced by BeginInternalSubTransaction(), BeginTransactionBlock(), CommitTransactionCommandInternal(), DefineSavepoint(), EndTransactionBlock(), ReleaseCurrentSubTransaction(), ReleaseSavepoint(), RollbackAndReleaseCurrentSubTransaction(), RollbackToSavepoint(), ShowTransactionStateRec(), StartTransactionCommand(), TransactionBlockStatusCode(), and UserAbortTransactionBlock().

◆ CallSubXactCallbacks()

static void CallSubXactCallbacks ( SubXactEvent  event,
SubTransactionId  mySubid,
SubTransactionId  parentSubid 
)
static

Definition at line 3898 of file xact.c.

3901{
3902 SubXactCallbackItem *item;
3904
3905 for (item = SubXact_callbacks; item; item = next)
3906 {
3907 /* allow callbacks to unregister themselves when called */
3908 next = item->next;
3909 item->callback(event, mySubid, parentSubid, item->arg);
3910 }
3911}
static int32 next
Definition: blutils.c:224
struct SubXactCallbackItem * next
Definition: xact.c:322
SubXactCallback callback
Definition: xact.c:323
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:327

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

3839{
3840 XactCallbackItem *item;
3842
3843 for (item = Xact_callbacks; item; item = next)
3844 {
3845 /* allow callbacks to unregister themselves when called */
3846 next = item->next;
3847 item->callback(event, item->arg);
3848 }
3849}
struct XactCallbackItem * next
Definition: xact.c:310
void * arg
Definition: xact.c:312
XactCallback callback
Definition: xact.c:311
static XactCallbackItem * Xact_callbacks
Definition: xact.c:315

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

3726{
3727 /*
3728 * xact block already started?
3729 */
3730 if (IsTransactionBlock())
3731 return;
3732
3733 /*
3734 * subtransaction?
3735 */
3736 if (IsSubTransaction())
3737 return;
3738
3739 /*
3740 * inside a function call?
3741 */
3742 if (!isTopLevel)
3743 return;
3744
3745 ereport(throwError ? ERROR : WARNING,
3746 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3747 /* translator: %s represents an SQL statement name */
3748 errmsg("%s can only be used in transaction blocks",
3749 stmtType)));
3750}
bool IsSubTransaction(void)
Definition: xact.c:5044
bool IsTransactionBlock(void)
Definition: xact.c:4971

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

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5383 of file xact.c.

5384{
5386
5387 ShowTransactionState("CleanupSubTransaction");
5388
5389 if (s->state != TRANS_ABORT)
5390 elog(WARNING, "CleanupSubTransaction while in %s state",
5392
5394
5397 if (s->curTransactionOwner)
5399 s->curTransactionOwner = NULL;
5400
5402
5403 s->state = TRANS_DEFAULT;
5404
5406}
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1094
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:871
static void AtSubCleanup_Memory(void)
Definition: xact.c:2022
static void PopTransaction(void)
Definition: xact.c:5478

References AtSubCleanup_Memory(), AtSubCleanup_Portals(), CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, TransactionStateData::parent, PopTransaction(), ResourceOwnerDelete(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, TRANS_ABORT, TRANS_DEFAULT, TransStateAsString(), and WARNING.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), CommitTransactionCommandInternal(), and RollbackAndReleaseCurrentSubTransaction().

◆ CleanupTransaction()

static void CleanupTransaction ( void  )
static

Definition at line 3009 of file xact.c.

3010{
3012
3013 /*
3014 * State should still be TRANS_ABORT from AbortTransaction().
3015 */
3016 if (s->state != TRANS_ABORT)
3017 elog(FATAL, "CleanupTransaction: unexpected state %s",
3019
3020 /*
3021 * do abort cleanup processing
3022 */
3023 AtCleanup_Portals(); /* now safe to release portal memory */
3024 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3025
3026 CurrentResourceOwner = NULL; /* and resource owner */
3029 s->curTransactionOwner = NULL;
3032
3033 AtCleanup_Memory(); /* and transaction memory */
3034
3037 s->nestingLevel = 0;
3038 s->gucNestLevel = 0;
3039 s->childXids = NULL;
3040 s->nChildXids = 0;
3041 s->maxChildXids = 0;
3042 s->parallelModeLevel = 0;
3043 s->parallelChildXact = false;
3044
3047
3048 /*
3049 * done with abort processing, set current transaction state back to
3050 * default
3051 */
3052 s->state = TRANS_DEFAULT;
3053}
#define InvalidSubTransactionId
Definition: c.h:629
void AtCleanup_Portals(void)
Definition: portalmem.c:860
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:1003
#define InvalidFullTransactionId
Definition: transam.h:56
static void AtCleanup_Memory(void)
Definition: xact.c:1974
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::parallelChildXact, TransactionStateData::parallelModeLevel, ResourceOwnerDelete(), TransactionStateData::state, TransactionStateData::subTransactionId, TopTransactionResourceOwner, TRANS_ABORT, TRANS_DEFAULT, TransStateAsString(), and XactTopFullTransactionId.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), and CommitTransactionCommandInternal().

◆ CommandCounterIncrement()

void CommandCounterIncrement ( void  )

Definition at line 1100 of file xact.c.

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

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

Referenced by _SPI_execute_plan(), acquire_inherited_sample_rows(), addFkConstraint(), AddRoleMems(), AlterPublicationOptions(), AlterRole(), ATAddCheckNNConstraint(), ATExecAddColumn(), ATExecAlterColumnType(), ATExecAlterConstrInheritability(), ATExecCmd(), ATExecDropColumn(), ATExecDropExpression(), ATExecDropIdentity(), ATExecSetAccessMethodNoStorage(), ATExecSetCompression(), ATExecSetExpression(), ATExecSetNotNull(), ATExecSetTableSpace(), ATExecSetTableSpaceNoStorage(), ATParseTransformCmd(), ATRewriteTables(), AttachPartitionEnsureIndexes(), AttachPartitionForeignKey(), btadjustmembers(), CommitSubTransaction(), CommitTransactionCommandInternal(), copy_table_data(), create_ctas_internal(), create_toast_table(), CreateFKCheckTrigger(), createForeignKeyActionTriggers(), CreateForeignTable(), CreatePublication(), CreateRole(), CreateSchemaCommand(), CreateTriggerFiringOn(), DefineCollation(), DefineDomain(), DefineIndex(), DefineRelation(), DefineVirtualRelation(), delete_pg_statistic(), deleteOneObject(), DetachPartitionFinalize(), do_analyze_rel(), DropClonedTriggersFromPartition(), dropconstraint_internal(), DropForeignKeyConstraintTriggers(), 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(), relation_statistics_update(), RelationSetNewRelfilenumber(), RemoveInheritedConstraint(), RemoveRoleFromInitPriv(), RemoveRoleFromObjectPolicy(), RenumberEnumType(), ReplaceRoleInInitPriv(), replorigin_create(), replorigin_drop_by_name(), ri_PerformCheck(), set_attnotnull(), SetDatabaseHasLoginEventTriggers(), SetDefaultACL(), SetMatViewPopulatedState(), shdepReassignOwned(), SPI_cursor_open_internal(), standard_ProcessUtility(), StoreConstraints(), StorePartitionBound(), upsert_pg_statistic(), vacuum(), and validatePartitionedIndex().

◆ CommitSubTransaction()

static void CommitSubTransaction ( void  )
static

Definition at line 5104 of file xact.c.

5105{
5107
5108 ShowTransactionState("CommitSubTransaction");
5109
5110 if (s->state != TRANS_INPROGRESS)
5111 elog(WARNING, "CommitSubTransaction while in %s state",
5113
5114 /* Pre-commit processing goes here */
5115
5118
5119 /*
5120 * If this subxact has started any unfinished parallel operation, clean up
5121 * its workers and exit parallel mode. Warn about leaked resources.
5122 */
5124 if (s->parallelModeLevel != 0)
5125 {
5126 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5128 s->parallelModeLevel = 0;
5129 }
5130
5131 /* Do the actual "commit", such as it is */
5132 s->state = TRANS_COMMIT;
5133
5134 /* Must CCI to ensure commands of subtransaction are seen as done */
5136
5137 /*
5138 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5139 * perform that step, if required, as part of the atomic update of the
5140 * whole transaction tree at top level commit or abort.
5141 */
5142
5143 /* Post-commit cleanup */
5149 s->parent->nestingLevel,
5154
5157
5160 true, false);
5164 AtEOSubXact_Inval(true);
5166
5167 /*
5168 * The only lock we actually release here is the subtransaction XID lock.
5169 */
5173
5174 /*
5175 * Other locks should get transferred to their parent resource owner.
5176 */
5179 true, false);
5182 true, false);
5183
5184 AtEOXact_GUC(true, s->gucNestLevel);
5195
5196 /*
5197 * We need to restore the upper transaction's read-only state, in case the
5198 * upper is read-write while the child is read-only; GUC will incorrectly
5199 * think it should leave the child state in place.
5200 */
5202
5206 s->curTransactionOwner = NULL;
5207
5209
5210 s->state = TRANS_DEFAULT;
5211
5213}
void AtSubCommit_Notify(void)
Definition: async.c:1691
void XactLockTableDelete(TransactionId xid)
Definition: lmgr.c:639
void AtSubCommit_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, int parentLevel, ResourceOwner parentXactOwner)
Definition: portalmem.c:945
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:948
void AtSubCommit_smgr(void)
Definition: storage.c:955
static void AtSubCommit_Memory(void)
Definition: xact.c:1635
static void AtSubCommit_childXids(void)
Definition: xact.c:1664
void CommandCounterIncrement(void)
Definition: xact.c:1100
@ 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(), AtEOSubXact_TypeCache(), AtEOXact_GUC(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubCommit_Notify(), AtSubCommit_Portals(), AtSubCommit_smgr(), AtSubCommit_Snapshot(), CallSubXactCallbacks(), CommandCounterIncrement(), CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, elog, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, TransactionStateData::gucNestLevel, TransactionStateData::nestingLevel, TransactionStateData::parallelModeLevel, TransactionStateData::parent, PopTransaction(), TransactionStateData::prevXactReadOnly, RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_COMMIT_SUB, SUBXACT_EVENT_PRE_COMMIT_SUB, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TransStateAsString(), WARNING, XactLockTableDelete(), XactReadOnly, and XidFromFullTransactionId.

Referenced by CommitTransactionCommandInternal(), and ReleaseCurrentSubTransaction().

◆ CommitTransaction()

static void CommitTransaction ( void  )
static

Definition at line 2228 of file xact.c.

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

Referenced by CommitTransactionCommandInternal(), EndParallelWorkerTransaction(), EndRestoreLOs(), restore_toc_entries_prefork(), restore_toc_entry(), and RestoreArchive().

◆ CommitTransactionCommand()

void CommitTransactionCommand ( void  )

Definition at line 3157 of file xact.c.

3158{
3159 /*
3160 * Repeatedly call CommitTransactionCommandInternal() until all the work
3161 * is done.
3162 */
3164 {
3165 }
3166}
static bool CommitTransactionCommandInternal(void)
Definition: xact.c:3175

References CommitTransactionCommandInternal().

Referenced by _SPI_commit(), AllTablesyncsReady(), apply_handle_commit_internal(), apply_handle_commit_prepared(), apply_handle_prepare(), apply_handle_prepare_internal(), apply_handle_rollback_prepared(), apply_handle_stream_prepare(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), BeginInternalSubTransaction(), BootstrapModeMain(), clear_subscription_skip_lsn(), cluster_multiple_rels(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), finish_sync_worker(), 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(), process_syncing_tables_for_apply(), process_syncing_tables_for_sync(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), run_apply_worker(), shell_check_detail(), stream_abort_internal(), stream_stop_internal(), synchronize_slots(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ CommitTransactionCommandInternal()

static bool CommitTransactionCommandInternal ( void  )
static

Definition at line 3175 of file xact.c.

3176{
3179
3180 /* Must save in case we need to restore below */
3182
3183 switch (s->blockState)
3184 {
3185 /*
3186 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3187 * StartTransactionCommand didn't set the STARTED state
3188 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3189 * by EndParallelWorkerTransaction(), not this function.
3190 */
3191 case TBLOCK_DEFAULT:
3193 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3195 break;
3196
3197 /*
3198 * If we aren't in a transaction block, just do our usual
3199 * transaction commit, and return to the idle state.
3200 */
3201 case TBLOCK_STARTED:
3204 break;
3205
3206 /*
3207 * We are completing a "BEGIN TRANSACTION" command, so we change
3208 * to the "transaction block in progress" state and return. (We
3209 * assume the BEGIN did nothing to the database, so we need no
3210 * CommandCounterIncrement.)
3211 */
3212 case TBLOCK_BEGIN:
3214 break;
3215
3216 /*
3217 * This is the case when we have finished executing a command
3218 * someplace within a transaction block. We increment the command
3219 * counter and return.
3220 */
3221 case TBLOCK_INPROGRESS:
3225 break;
3226
3227 /*
3228 * We are completing a "COMMIT" command. Do it and return to the
3229 * idle state.
3230 */
3231 case TBLOCK_END:
3234 if (s->chain)
3235 {
3238 s->chain = false;
3240 }
3241 break;
3242
3243 /*
3244 * Here we are in the middle of a transaction block but one of the
3245 * commands caused an abort so we do nothing but remain in the
3246 * abort state. Eventually we will get a ROLLBACK command.
3247 */
3248 case TBLOCK_ABORT:
3249 case TBLOCK_SUBABORT:
3250 break;
3251
3252 /*
3253 * Here we were in an aborted transaction block and we just got
3254 * the ROLLBACK command from the user, so clean up the
3255 * already-aborted transaction and return to the idle state.
3256 */
3257 case TBLOCK_ABORT_END:
3260 if (s->chain)
3261 {
3264 s->chain = false;
3266 }
3267 break;
3268
3269 /*
3270 * Here we were in a perfectly good transaction block but the user
3271 * told us to ROLLBACK anyway. We have to abort the transaction
3272 * and then clean up.
3273 */
3278 if (s->chain)
3279 {
3282 s->chain = false;
3284 }
3285 break;
3286
3287 /*
3288 * We are completing a "PREPARE TRANSACTION" command. Do it and
3289 * return to the idle state.
3290 */
3291 case TBLOCK_PREPARE:
3294 break;
3295
3296 /*
3297 * The user issued a SAVEPOINT inside a transaction block. Start a
3298 * subtransaction. (DefineSavepoint already did PushTransaction,
3299 * so as to have someplace to put the SUBBEGIN state.)
3300 */
3301 case TBLOCK_SUBBEGIN:
3304 break;
3305
3306 /*
3307 * The user issued a RELEASE command, so we end the current
3308 * subtransaction and return to the parent transaction. The parent
3309 * might be ended too, so repeat till we find an INPROGRESS
3310 * transaction or subtransaction.
3311 */
3312 case TBLOCK_SUBRELEASE:
3313 do
3314 {
3316 s = CurrentTransactionState; /* changed by pop */
3317 } while (s->blockState == TBLOCK_SUBRELEASE);
3318
3321 break;
3322
3323 /*
3324 * The user issued a COMMIT, so we end the current subtransaction
3325 * hierarchy and perform final commit. We do this by rolling up
3326 * any subtransactions into their parent, which leads to O(N^2)
3327 * operations with respect to resource owners - this isn't that
3328 * bad until we approach a thousands of savepoints but is
3329 * necessary for correctness should after triggers create new
3330 * resource owners.
3331 */
3332 case TBLOCK_SUBCOMMIT:
3333 do
3334 {
3336 s = CurrentTransactionState; /* changed by pop */
3337 } while (s->blockState == TBLOCK_SUBCOMMIT);
3338 /* If we had a COMMIT command, finish off the main xact too */
3339 if (s->blockState == TBLOCK_END)
3340 {
3341 Assert(s->parent == NULL);
3344 if (s->chain)
3345 {
3348 s->chain = false;
3350 }
3351 }
3352 else if (s->blockState == TBLOCK_PREPARE)
3353 {
3354 Assert(s->parent == NULL);
3357 }
3358 else
3359 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3361 break;
3362
3363 /*
3364 * The current already-failed subtransaction is ending due to a
3365 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3366 * examine the parent (which could be in any of several states).
3367 * As we need to examine the parent, return false to request the
3368 * caller to do the next iteration.
3369 */
3372 return false;
3373
3374 /*
3375 * As above, but it's not dead yet, so abort first.
3376 */
3380 return false;
3381
3382 /*
3383 * The current subtransaction is the target of a ROLLBACK TO
3384 * command. Abort and pop it, then start a new subtransaction
3385 * with the same name.
3386 */
3387 case TBLOCK_SUBRESTART:
3388 {
3389 char *name;
3390 int savepointLevel;
3391
3392 /* save name and keep Cleanup from freeing it */
3393 name = s->name;
3394 s->name = NULL;
3395 savepointLevel = s->savepointLevel;
3396
3399
3400 DefineSavepoint(NULL);
3401 s = CurrentTransactionState; /* changed by push */
3402 s->name = name;
3403 s->savepointLevel = savepointLevel;
3404
3405 /* This is the same as TBLOCK_SUBBEGIN case */
3409 }
3410 break;
3411
3412 /*
3413 * Same as above, but the subtransaction had already failed, so we
3414 * don't need AbortSubTransaction.
3415 */
3417 {
3418 char *name;
3419 int savepointLevel;
3420
3421 /* save name and keep Cleanup from freeing it */
3422 name = s->name;
3423 s->name = NULL;
3424 savepointLevel = s->savepointLevel;
3425
3427
3428 DefineSavepoint(NULL);
3429 s = CurrentTransactionState; /* changed by push */
3430 s->name = name;
3431 s->savepointLevel = savepointLevel;
3432
3433 /* This is the same as TBLOCK_SUBBEGIN case */
3437 }
3438 break;
3439 }
3440
3441 /* Done, no more iterations required */
3442 return true;
3443}
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3136
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3144
static void StartTransaction(void)
Definition: xact.c:2064
void DefineSavepoint(const char *name)
Definition: xact.c:4373
static void CommitSubTransaction(void)
Definition: xact.c:5104
static void CommitTransaction(void)
Definition: xact.c:2228
static void PrepareTransaction(void)
Definition: xact.c:2515
static void StartSubTransaction(void)
Definition: xact.c:5067

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

Referenced by CommitTransactionCommand().

◆ DefineSavepoint()

void DefineSavepoint ( const char *  name)

Definition at line 4373 of file xact.c.

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

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

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

◆ EndImplicitTransactionBlock()

void EndImplicitTransactionBlock ( void  )

Definition at line 4351 of file xact.c.

4352{
4354
4355 /*
4356 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4357 * allowing CommitTransactionCommand to commit whatever happened during
4358 * the implicit transaction block as though it were a single statement.
4359 *
4360 * For caller convenience, we consider all other transaction states as
4361 * legal here; otherwise the caller would need its own state check, which
4362 * seems rather pointless.
4363 */
4366}

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

Referenced by exec_simple_query(), and PostgresMain().

◆ EndParallelWorkerTransaction()

◆ EndTransactionBlock()

bool EndTransactionBlock ( bool  chain)

Definition at line 4044 of file xact.c.

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

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()

◆ EstimateTransactionStateSpace()

Size EstimateTransactionStateSpace ( void  )

Definition at line 5512 of file xact.c.

5513{
5515 Size nxids = 0;
5517
5518 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5519 {
5521 nxids = add_size(nxids, 1);
5522 nxids = add_size(nxids, s->nChildXids);
5523 }
5524
5525 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5526}
size_t Size
Definition: c.h:576
Size add_size(Size s1, Size s2)
Definition: shmem.c:493
Size mul_size(Size s1, Size s2)
Definition: shmem.c:510
#define SerializedTransactionStateHeaderSize
Definition: xact.c:239

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

Referenced by InitializeParallelDSM().

◆ ExitParallelMode()

◆ ForceSyncCommit()

void ForceSyncCommit ( void  )

Definition at line 1152 of file xact.c.

1153{
1154 forceSyncCommit = true;
1155}
static bool forceSyncCommit
Definition: xact.c:293

References forceSyncCommit.

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 829 of file xact.c.

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

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

Referenced by ATRewriteTable(), CatalogTuplesMultiInsertWithInfo(), CopyFrom(), create_edata_for_relation(), create_estate_for_relation(), FindConflictTuple(), GetSnapshotData(), GetSnapshotDataReuse(), heap_inplace_lock(), 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()

◆ GetCurrentFullTransactionIdIfAny()

FullTransactionId GetCurrentFullTransactionIdIfAny ( void  )

Definition at line 530 of file xact.c.

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 879 of file xact.c.

880{
881 return stmtStartTimestamp;
882}
static TimestampTz stmtStartTimestamp
Definition: xact.c:281

References stmtStartTimestamp.

Referenced by check_log_duration(), CreatePortal(), InitializeParallelDSM(), pgstat_report_activity(), statement_timestamp(), and StorePreparedStatement().

◆ GetCurrentSubTransactionId()

◆ GetCurrentTransactionId()

◆ GetCurrentTransactionIdIfAny()

◆ GetCurrentTransactionNestLevel()

◆ GetCurrentTransactionStartTimestamp()

TimestampTz GetCurrentTransactionStartTimestamp ( void  )

◆ GetCurrentTransactionStopTimestamp()

TimestampTz GetCurrentTransactionStopTimestamp ( void  )

Definition at line 891 of file xact.c.

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

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

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

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

Referenced by xid_age().

◆ GetTopFullTransactionId()

◆ GetTopFullTransactionIdIfAny()

FullTransactionId GetTopFullTransactionIdIfAny ( void  )

Definition at line 499 of file xact.c.

500{
502}

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3769 of file xact.c.

3770{
3771 /*
3772 * Return true on same conditions that would make
3773 * PreventInTransactionBlock error out
3774 */
3775 if (IsTransactionBlock())
3776 return true;
3777
3778 if (IsSubTransaction())
3779 return true;
3780
3781 if (!isTopLevel)
3782 return true;
3783
3786 return true;
3787
3788 return false;
3789}

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

Referenced by vacuum().

◆ IsSubTransaction()

◆ IsSubxactTopXidLogPending()

bool IsSubxactTopXidLogPending ( void  )

Definition at line 559 of file xact.c.

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

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

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 387 of file xact.c.

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

References CurrentTransactionState, TransactionStateData::state, and TRANS_INPROGRESS.

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

◆ MarkCurrentTransactionIdLoggedIfAny()

void MarkCurrentTransactionIdLoggedIfAny ( void  )

◆ MarkSubxactTopXidLogged()

void MarkSubxactTopXidLogged ( void  )

Definition at line 591 of file xact.c.

592{
594
596}
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:559

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

Referenced by XLogInsertRecord().

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5478 of file xact.c.

5479{
5481
5482 if (s->state != TRANS_DEFAULT)
5483 elog(WARNING, "PopTransaction while in %s state",
5485
5486 if (s->parent == NULL)
5487 elog(FATAL, "PopTransaction with no parent");
5488
5490
5491 /* Let's just make sure CurTransactionContext is good */
5494
5495 /* Ditto for ResourceOwner links */
5498
5499 /* Free the old child structure */
5500 if (s->name)
5501 pfree(s->name);
5502 pfree(s);
5503}

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

2516{
2519 GlobalTransaction gxact;
2520 TimestampTz prepared_at;
2521
2523
2524 ShowTransactionState("PrepareTransaction");
2525
2526 /*
2527 * check the current transaction state
2528 */
2529 if (s->state != TRANS_INPROGRESS)
2530 elog(WARNING, "PrepareTransaction while in %s state",
2532 Assert(s->parent == NULL);
2533
2534 /*
2535 * Do pre-commit processing that involves calling user-defined code, such
2536 * as triggers. Since closing cursors could queue trigger actions,
2537 * triggers could open cursors, etc, we have to keep looping until there's
2538 * nothing left to do.
2539 */
2540 for (;;)
2541 {
2542 /*
2543 * Fire all currently pending deferred triggers.
2544 */
2546
2547 /*
2548 * Close open portals (converting holdable ones into static portals).
2549 * If there weren't any, we are done ... otherwise loop back to check
2550 * if they queued deferred triggers. Lather, rinse, repeat.
2551 */
2552 if (!PreCommit_Portals(true))
2553 break;
2554 }
2555
2557
2558 /*
2559 * The remaining actions cannot call any user-defined code, so it's safe
2560 * to start shutting down within-transaction services. But note that most
2561 * of this stuff could still throw an error, which would switch us into
2562 * the transaction-abort path.
2563 */
2564
2565 /* Shut down the deferred-trigger manager */
2566 AfterTriggerEndXact(true);
2567
2568 /*
2569 * Let ON COMMIT management do its thing (must happen after closing
2570 * cursors, to avoid dangling-reference problems)
2571 */
2573
2574 /*
2575 * Synchronize files that are created and not WAL-logged during this
2576 * transaction. This must happen before EndPrepare(), so that we don't see
2577 * committed-but-broken files after a crash and COMMIT PREPARED.
2578 */
2579 smgrDoPendingSyncs(true, false);
2580
2581 /* close large objects before lower-level cleanup */
2583
2584 /* NOTIFY requires no work at this point */
2585
2586 /*
2587 * Mark serializable transaction as complete for predicate locking
2588 * purposes. This should be done as late as we can put it and still allow
2589 * errors to be raised for failure patterns found at commit.
2590 */
2592
2593 /*
2594 * Don't allow PREPARE TRANSACTION if we've accessed a temporary table in
2595 * this transaction. Having the prepared xact hold locks on another
2596 * backend's temp table seems a bad idea --- for instance it would prevent
2597 * the backend from exiting. There are other problems too, such as how to
2598 * clean up the source backend's local buffers and ON COMMIT state if the
2599 * prepared xact includes a DROP of a temp table.
2600 *
2601 * Other objects types, like functions, operators or extensions, share the
2602 * same restriction as they should not be created, locked or dropped as
2603 * this can mess up with this session or even a follow-up session trying
2604 * to use the same temporary namespace.
2605 *
2606 * We must check this after executing any ON COMMIT actions, because they
2607 * might still access a temp relation.
2608 *
2609 * XXX In principle this could be relaxed to allow some useful special
2610 * cases, such as a temp table created and dropped all within the
2611 * transaction. That seems to require much more bookkeeping though.
2612 */
2614 ereport(ERROR,
2615 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2616 errmsg("cannot PREPARE a transaction that has operated on temporary objects")));
2617
2618 /*
2619 * Likewise, don't allow PREPARE after pg_export_snapshot. This could be
2620 * supported if we added cleanup logic to twophase.c, but for now it
2621 * doesn't seem worth the trouble.
2622 */
2624 ereport(ERROR,
2625 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2626 errmsg("cannot PREPARE a transaction that has exported snapshots")));
2627
2628 /* Prevent cancel/die interrupt while cleaning up */
2630
2631 /*
2632 * set the current transaction state information appropriately during
2633 * prepare processing
2634 */
2635 s->state = TRANS_PREPARE;
2636
2637 /* Disable transaction timeout */
2638 if (TransactionTimeout > 0)
2640
2641 prepared_at = GetCurrentTimestamp();
2642
2643 /*
2644 * Reserve the GID for this transaction. This could fail if the requested
2645 * GID is invalid or already in use.
2646 */
2647 gxact = MarkAsPreparing(xid, prepareGID, prepared_at,
2649 prepareGID = NULL;
2650
2651 /*
2652 * Collect data for the 2PC state file. Note that in general, no actual
2653 * state change should happen in the called modules during this step,
2654 * since it's still possible to fail before commit, and in that case we
2655 * want transaction abort to be able to clean up. (In particular, the
2656 * AtPrepare routines may error out if they find cases they cannot
2657 * handle.) State cleanup should happen in the PostPrepare routines
2658 * below. However, some modules can go ahead and clear state here because
2659 * they wouldn't do anything with it during abort anyway.
2660 *
2661 * Note: because the 2PC state file records will be replayed in the same
2662 * order they are made, the order of these calls has to match the order in
2663 * which we want things to happen during COMMIT PREPARED or ROLLBACK
2664 * PREPARED; in particular, pay attention to whether things should happen
2665 * before or after releasing the transaction's locks.
2666 */
2667 StartPrepare(gxact);
2668
2675
2676 /*
2677 * Here is where we really truly prepare.
2678 *
2679 * We have to record transaction prepares even if we didn't make any
2680 * updates, because the transaction manager might get confused if we lose
2681 * a global transaction.
2682 */
2683 EndPrepare(gxact);
2684
2685 /*
2686 * Now we clean up backend-internal state and release internal resources.
2687 */
2688
2689 /* Reset XactLastRecEnd until the next transaction writes something */
2690 XactLastRecEnd = 0;
2691
2692 /*
2693 * Transfer our locks to a dummy PGPROC. This has to be done before
2694 * ProcArrayClearTransaction(). Otherwise, a GetLockConflicts() would
2695 * conclude "xact already committed or aborted" for our locks.
2696 */
2697 PostPrepare_Locks(xid);
2698
2699 /*
2700 * Let others know about no transaction in progress by me. This has to be
2701 * done *after* the prepared transaction has been marked valid, else
2702 * someone may think it is unlocked and recyclable.
2703 */
2705
2706 /*
2707 * In normal commit-processing, this is all non-critical post-transaction
2708 * cleanup. When the transaction is prepared, however, it's important
2709 * that the locks and other per-backend resources are transferred to the
2710 * prepared transaction's PGPROC entry. Note that if an error is raised
2711 * here, it's too late to abort the transaction. XXX: This probably should
2712 * be in a critical section, to force a PANIC if any of this fails, but
2713 * that cure could be worse than the disease.
2714 */
2715
2717
2720 true, true);
2721
2722 AtEOXact_Aio(true);
2723
2724 /* Check we've released all buffer pins */
2725 AtEOXact_Buffers(true);
2726
2727 /* Clean up the relation cache */
2729
2730 /* Clean up the type cache */
2732
2733 /* notify doesn't need a postprepare call */
2734
2736
2738
2740
2742
2744
2747 true, true);
2750 true, true);
2751
2752 /*
2753 * Allow another backend to finish the transaction. After
2754 * PostPrepare_Twophase(), the transaction is completely detached from our
2755 * backend. The rest is just non-critical cleanup of backend-local state.
2756 */
2758
2759 /* PREPARE acts the same as COMMIT as far as GUC is concerned */
2760 AtEOXact_GUC(true, 1);
2761 AtEOXact_SPI(true);
2762 AtEOXact_Enum();
2764 AtEOXact_Namespace(true, false);
2765 AtEOXact_SMgr();
2766 AtEOXact_Files(true);
2768 AtEOXact_HashTables(true);
2769 /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
2770 AtEOXact_Snapshot(true, true);
2771 /* we treat PREPARE as ROLLBACK so far as waking workers goes */
2775
2776 CurrentResourceOwner = NULL;
2778 s->curTransactionOwner = NULL;
2781
2783
2786 s->nestingLevel = 0;
2787 s->gucNestLevel = 0;
2788 s->childXids = NULL;
2789 s->nChildXids = 0;
2790 s->maxChildXids = 0;
2791
2794
2795 /*
2796 * done with 1st phase commit processing, set current transaction state
2797 * back to default
2798 */
2799 s->state = TRANS_DEFAULT;
2800
2802}
void AtPrepare_Notify(void)
Definition: async.c:836
int64 TimestampTz
Definition: timestamp.h:39
Oid MyDatabaseId
Definition: globals.c:95
void PostPrepare_Inval(void)
Definition: inval.c:986
void AtPrepare_Locks(void)
Definition: lock.c:3443
void PostPrepare_Locks(TransactionId xid)
Definition: lock.c:3539
Oid GetUserId(void)
Definition: miscinit.c:520
void AtPrepare_MultiXact(void)
Definition: multixact.c:1836
void PostPrepare_MultiXact(TransactionId xid)
Definition: multixact.c:1850
void AtPrepare_PgStat(void)
Definition: pgstat_xact.c:191
void PostPrepare_PgStat(void)
Definition: pgstat_xact.c:211
void AtPrepare_PredicateLocks(void)
Definition: predicate.c:4790
void PostPrepare_PredicateLocks(TransactionId xid)
Definition: predicate.c:4859
void ProcArrayClearTransaction(PGPROC *proc)
Definition: procarray.c:907
void AtPrepare_RelationMap(void)
Definition: relmapper.c:588
bool XactHasExportedSnapshots(void)
Definition: snapmgr.c:1561
void PostPrepare_smgr(void)
Definition: storage.c:934
void EndPrepare(GlobalTransaction gxact)
Definition: twophase.c:1142
void StartPrepare(GlobalTransaction gxact)
Definition: twophase.c:1049
void PostPrepare_Twophase(void)
Definition: twophase.c:344
GlobalTransaction MarkAsPreparing(TransactionId xid, const char *gid, TimestampTz prepared_at, Oid owner, Oid databaseid)
Definition: twophase.c:359
static char * prepareGID
Definition: xact.c:288
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:454
int MyXactFlags
Definition: xact.c:136
@ 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_Aio(), 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(), AtEOXact_TypeCache(), AtPrepare_Locks(), AtPrepare_MultiXact(), AtPrepare_Notify(), AtPrepare_PgStat(), AtPrepare_PredicateLocks(), AtPrepare_RelationMap(), CallXactCallbacks(), TransactionStateData::childXids, CurrentResourceOwner, CurrentTransactionState, TransactionStateData::curTransactionOwner, CurTransactionResourceOwner, disable_timeout(), elog, EndPrepare(), ereport, errcode(), errmsg(), ERROR, TransactionStateData::fullTransactionId, GetCurrentTimestamp(), GetCurrentTransactionId(), GetUserId(), TransactionStateData::gucNestLevel, HOLD_INTERRUPTS, InvalidFullTransactionId, InvalidSubTransactionId, IsInParallelMode(), MarkAsPreparing(), TransactionStateData::maxChildXids, MyDatabaseId, MyProc, MyXactFlags, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nParallelCurrentXids, TransactionStateData::parent, pgstat_report_xact_timestamp(), PostPrepare_Inval(), PostPrepare_Locks(), PostPrepare_MultiXact(), PostPrepare_PgStat(), PostPrepare_PredicateLocks(), PostPrepare_smgr(), PostPrepare_Twophase(), PreCommit_CheckForSerializationFailure(), PreCommit_on_commit_actions(), PreCommit_Portals(), prepareGID, ProcArrayClearTransaction(), RESOURCE_RELEASE_AFTER_LOCKS, RESOURCE_RELEASE_BEFORE_LOCKS, RESOURCE_RELEASE_LOCKS, ResourceOwnerDelete(), ResourceOwnerRelease(), RESUME_INTERRUPTS, ShowTransactionState(), smgrDoPendingSyncs(), StartPrepare(), TransactionStateData::state, TransactionStateData::subTransactionId, TopTransactionResourceOwner, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_PREPARE, TRANSACTION_TIMEOUT, TransactionTimeout, TransStateAsString(), WARNING, XACT_EVENT_PRE_PREPARE, XACT_EVENT_PREPARE, XACT_FLAGS_ACCESSEDTEMPNAMESPACE, XactHasExportedSnapshots(), XactLastRecEnd, and XactTopFullTransactionId.

Referenced by CommitTransactionCommandInternal().

◆ PrepareTransactionBlock()

bool PrepareTransactionBlock ( const char *  gid)

Definition at line 3992 of file xact.c.

3993{
3995 bool result;
3996
3997 /* Set up to commit the current transaction */
3998 result = EndTransactionBlock(false);
3999
4000 /* If successful, change outer tblock state to PREPARE */
4001 if (result)
4002 {
4004
4005 while (s->parent != NULL)
4006 s = s->parent;
4007
4008 if (s->blockState == TBLOCK_END)
4009 {
4010 /* Save GID where PrepareTransaction can find it again */
4012
4014 }
4015 else
4016 {
4017 /*
4018 * ignore case where we are not in a transaction;
4019 * EndTransactionBlock already issued a warning.
4020 */
4023 /* Don't send back a PREPARE result tag... */
4024 result = false;
4025 }
4026 }
4027
4028 return result;
4029}
bool EndTransactionBlock(bool chain)
Definition: xact.c:4044

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

3649{
3650 /*
3651 * xact block already started?
3652 */
3653 if (IsTransactionBlock())
3654 ereport(ERROR,
3655 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3656 /* translator: %s represents an SQL statement name */
3657 errmsg("%s cannot run inside a transaction block",
3658 stmtType)));
3659
3660 /*
3661 * subtransaction?
3662 */
3663 if (IsSubTransaction())
3664 ereport(ERROR,
3665 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3666 /* translator: %s represents an SQL statement name */
3667 errmsg("%s cannot run inside a subtransaction",
3668 stmtType)));
3669
3670 /*
3671 * inside a function call?
3672 */
3673 if (!isTopLevel)
3674 ereport(ERROR,
3675 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3676 /* translator: %s represents an SQL statement name */
3677 errmsg("%s cannot be executed from a function", stmtType)));
3678
3679 /* If we got past IsTransactionBlock test, should be in default state */
3682 elog(FATAL, "cannot prevent transaction chain");
3683
3684 /* All okay. Set the flag to make sure the right thing happens later. */
3686}
#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, and XACT_FLAGS_NEEDIMMEDIATECOMMIT.

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

◆ PushTransaction()

static void PushTransaction ( void  )
static

Definition at line 5416 of file xact.c.

5417{
5420
5421 /*
5422 * We keep subtransaction state nodes in TopTransactionContext.
5423 */
5424 s = (TransactionState)
5426 sizeof(TransactionStateData));
5427
5428 /*
5429 * Assign a subtransaction ID, watching out for counter wraparound.
5430 */
5433 {
5435 pfree(s);
5436 ereport(ERROR,
5437 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5438 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5439 }
5440
5441 /*
5442 * We can now stack a minimally valid subtransaction without fear of
5443 * failure.
5444 */
5445 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5447 s->parent = p;
5448 s->nestingLevel = p->nestingLevel + 1;
5451 s->state = TRANS_DEFAULT;
5456 s->parallelModeLevel = 0;
5458 s->topXidLogged = false;
5459
5461
5462 /*
5463 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5464 * with the subtransaction from here on out; in particular they should not
5465 * assume that it necessarily has a transaction context, resource owner,
5466 * or XID.
5467 */
5468}
int NewGUCNestLevel(void)
Definition: guc.c:2235
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1290
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:663
bool startedInRecovery
Definition: xact.c:212
TransactionStateData * TransactionState
Definition: xact.c:221
static SubTransactionId currentSubTransactionId
Definition: xact.c:266

References TransactionStateData::blockState, currentSubTransactionId, CurrentTransactionState, ereport, errcode(), errmsg(), ERROR, TransactionStateData::fullTransactionId, GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, InvalidSubTransactionId, MemoryContextAllocZero(), TransactionStateData::nestingLevel, NewGUCNestLevel(), TransactionStateData::parallelChildXact, TransactionStateData::parallelModeLevel, TransactionStateData::parent, pfree(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, TransactionStateData::prevXactReadOnly, TransactionStateData::savepointLevel, TransactionStateData::startedInRecovery, TransactionStateData::state, TransactionStateData::subTransactionId, TBLOCK_SUBBEGIN, TopTransactionContext, TransactionStateData::topXidLogged, TRANS_DEFAULT, and XactReadOnly.

Referenced by BeginInternalSubTransaction(), and DefineSavepoint().

◆ RecordTransactionAbort()

static TransactionId RecordTransactionAbort ( bool  isSubXact)
static

Definition at line 1754 of file xact.c.

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

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

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

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

Referenced by CommitTransaction().

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3864 of file xact.c.

3865{
3866 SubXactCallbackItem *item;
3867
3868 item = (SubXactCallbackItem *)
3870 item->callback = callback;
3871 item->arg = arg;
3872 item->next = SubXact_callbacks;
3873 SubXact_callbacks = item;
3874}
void * arg
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:46

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

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

◆ RegisterXactCallback()

void RegisterXactCallback ( XactCallback  callback,
void *  arg 
)

◆ ReleaseCurrentSubTransaction()

void ReleaseCurrentSubTransaction ( void  )

Definition at line 4768 of file xact.c.

4769{
4771
4772 /*
4773 * We do not check for parallel mode here. It's permissible to start and
4774 * end "internal" subtransactions while in parallel mode, so long as no
4775 * new XIDs or command IDs are assigned.
4776 */
4777
4779 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4784 s = CurrentTransactionState; /* changed by pop */
4786}

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

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_subtrans_commit(), pltcl_subtransaction(), PLy_spi_subtransaction_commit(), and PLy_subtransaction_exit().

◆ ReleaseSavepoint()

void ReleaseSavepoint ( const char *  name)

Definition at line 4458 of file xact.c.

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

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

Referenced by standard_ProcessUtility().

◆ RequireTransactionBlock()

void RequireTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3716 of file xact.c.

3717{
3718 CheckTransactionBlock(isTopLevel, true, stmtType);
3719}
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3725

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4796 of file xact.c.

4797{
4799
4800 /*
4801 * We do not check for parallel mode here. It's permissible to start and
4802 * end "internal" subtransactions while in parallel mode, so long as no
4803 * new XIDs or command IDs are assigned.
4804 */
4805
4806 switch (s->blockState)
4807 {
4808 /* Must be in a subtransaction */
4810 case TBLOCK_SUBABORT:
4811 break;
4812
4813 /* These cases are invalid. */
4814 case TBLOCK_DEFAULT:
4815 case TBLOCK_STARTED:
4816 case TBLOCK_BEGIN:
4819 case TBLOCK_SUBBEGIN:
4820 case TBLOCK_INPROGRESS:
4821 case TBLOCK_END:
4822 case TBLOCK_SUBRELEASE:
4823 case TBLOCK_SUBCOMMIT:
4824 case TBLOCK_ABORT:
4825 case TBLOCK_ABORT_END:
4829 case TBLOCK_SUBRESTART:
4831 case TBLOCK_PREPARE:
4832 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4834 break;
4835 }
4836
4837 /*
4838 * Abort the current subtransaction, if needed.
4839 */
4842
4843 /* And clean it up, too */
4845
4846 s = CurrentTransactionState; /* changed by pop */
4852}

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

Referenced by exec_stmt_block(), plperl_spi_exec(), plperl_spi_exec_prepared(), plperl_spi_fetchrow(), plperl_spi_prepare(), plperl_spi_query(), plperl_spi_query_prepared(), pltcl_subtrans_abort(), pltcl_subtransaction(), PLy_abort_open_subtransactions(), PLy_spi_subtransaction_abort(), PLy_subtransaction_exit(), ReorderBufferImmediateInvalidation(), and ReorderBufferProcessTXN().

◆ RollbackToSavepoint()

void RollbackToSavepoint ( const char *  name)

Definition at line 4567 of file xact.c.

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

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

Referenced by pa_stream_abort(), and standard_ProcessUtility().

◆ SaveTransactionCharacteristics()

◆ SerializeTransactionState()

void SerializeTransactionState ( Size  maxsize,
char *  start_address 
)

Definition at line 5540 of file xact.c.

5541{
5543 Size nxids = 0;
5544 Size i = 0;
5545 TransactionId *workspace;
5547
5548 result = (SerializedTransactionState *) start_address;
5549
5550 result->xactIsoLevel = XactIsoLevel;
5553 result->currentFullTransactionId =
5556
5557 /*
5558 * If we're running in a parallel worker and launching a parallel worker
5559 * of our own, we can just pass along the information that was passed to
5560 * us.
5561 */
5562 if (nParallelCurrentXids > 0)
5563 {
5565 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5567 return;
5568 }
5569
5570 /*
5571 * OK, we need to generate a sorted list of XIDs that our workers should
5572 * view as current. First, figure out how many there are.
5573 */
5574 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5575 {
5577 nxids = add_size(nxids, 1);
5578 nxids = add_size(nxids, s->nChildXids);
5579 }
5581 <= maxsize);
5582
5583 /* Copy them to our scratch space. */
5584 workspace = palloc(nxids * sizeof(TransactionId));
5585 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5586 {
5588 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5589 if (s->nChildXids > 0)
5590 memcpy(&workspace[i], s->childXids,
5591 s->nChildXids * sizeof(TransactionId));
5592 i += s->nChildXids;
5593 }
5594 Assert(i == nxids);
5595
5596 /* Sort them. */
5597 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5598
5599 /* Copy data into output area. */
5600 result->nParallelCurrentXids = nxids;
5601 memcpy(&result->parallelCurrentXids[0], workspace,
5602 nxids * sizeof(TransactionId));
5603}
int i
Definition: isn.c:77
#define qsort(a, b, c, d)
Definition: port.h:479
FullTransactionId currentFullTransactionId
Definition: xact.c:232
FullTransactionId topFullTransactionId
Definition: xact.c:231
CommandId currentCommandId
Definition: xact.c:233
TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.c:235
static TransactionId * ParallelCurrentXids
Definition: xact.c:127
int xidComparator(const void *arg1, const void *arg2)
Definition: xid.c:152

References add_size(), Assert(), TransactionStateData::childXids, SerializedTransactionState::currentCommandId, currentCommandId, SerializedTransactionState::currentFullTransactionId, CurrentTransactionState, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, i, TransactionStateData::nChildXids, nParallelCurrentXids, SerializedTransactionState::nParallelCurrentXids, palloc(), ParallelCurrentXids, SerializedTransactionState::parallelCurrentXids, TransactionStateData::parent, qsort, SerializedTransactionStateHeaderSize, SerializedTransactionState::topFullTransactionId, XactDeferrable, SerializedTransactionState::xactDeferrable, XactIsoLevel, SerializedTransactionState::xactIsoLevel, XactTopFullTransactionId, xidComparator(), and XidFromFullTransactionId.

Referenced by InitializeParallelDSM().

◆ SetCurrentStatementStartTimestamp()

◆ SetParallelStartTimestamps()

void SetParallelStartTimestamps ( TimestampTz  xact_ts,
TimestampTz  stmt_ts 
)

Definition at line 859 of file xact.c.

860{
862 xactStartTimestamp = xact_ts;
863 stmtStartTimestamp = stmt_ts;
864}

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

Referenced by ParallelWorkerMain().

◆ ShowTransactionState()

static void ShowTransactionState ( const char *  str)
static

Definition at line 5648 of file xact.c.

5649{
5650 /* skip work if message will definitely not be printed */
5653}
bool message_level_is_interesting(int elevel)
Definition: elog.c:273
#define DEBUG5
Definition: elog.h:26
const char * str
static void ShowTransactionStateRec(const char *str, TransactionState s)
Definition: xact.c:5660

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

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

◆ ShowTransactionStateRec()

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

Definition at line 5660 of file xact.c.

5661{
5663
5664 if (s->parent)
5665 {
5666 /*
5667 * Since this function recurses, it could be driven to stack overflow.
5668 * This is just a debugging aid, so we can leave out some details
5669 * instead of erroring out with check_stack_depth().
5670 */
5671 if (stack_is_too_deep())
5673 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5674 str, s->nestingLevel)));
5675 else
5677 }
5678
5680 if (s->nChildXids > 0)
5681 {
5682 int i;
5683
5684 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5685 for (i = 1; i < s->nChildXids; i++)
5686 appendStringInfo(&buf, " %u", s->childXids[i]);
5687 }
5689 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5690 str, s->nestingLevel,
5691 PointerIsValid(s->name) ? s->name : "unnamed",
5695 (unsigned int) s->subTransactionId,
5696 (unsigned int) currentCommandId,
5697 currentCommandIdUsed ? " (used)" : "",
5698 buf.data)));
5699 pfree(buf.data);
5700}
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1158
static char * buf
Definition: pg_test_fsync.c:72
bool stack_is_too_deep(void)
Definition: stack_depth.c:109
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:145
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97

References appendStringInfo(), TransactionStateData::blockState, BlockStateAsString(), buf, TransactionStateData::childXids, currentCommandId, currentCommandIdUsed, DEBUG5, ereport, errmsg_internal(), TransactionStateData::fullTransactionId, i, initStringInfo(), TransactionStateData::name, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, TransactionStateData::parent, pfree(), PointerIsValid, ShowTransactionStateRec(), stack_is_too_deep(), TransactionStateData::state, str, TransactionStateData::subTransactionId, TransStateAsString(), and XidFromFullTransactionId.

Referenced by ShowTransactionState(), and ShowTransactionStateRec().

◆ StartParallelWorkerTransaction()

◆ StartSubTransaction()

static void StartSubTransaction ( void  )
static

Definition at line 5067 of file xact.c.

5068{
5070
5071 if (s->state != TRANS_DEFAULT)
5072 elog(WARNING, "StartSubTransaction while in %s state",
5074
5075 s->state = TRANS_START;
5076
5077 /*
5078 * Initialize subsystems for new subtransaction
5079 *
5080 * must initialize resource-management stuff first
5081 */
5085
5087
5088 /*
5089 * Call start-of-subxact callbacks
5090 */
5093
5094 ShowTransactionState("StartSubTransaction");
5095}
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5351
static void AtSubStart_ResourceOwner(void)
Definition: xact.c:1283
static void AtSubStart_Memory(void)
Definition: xact.c:1254
@ SUBXACT_EVENT_START_SUB
Definition: xact.h:142

References AfterTriggerBeginSubXact(), AtSubStart_Memory(), AtSubStart_ResourceOwner(), CallSubXactCallbacks(), CurrentTransactionState, elog, TransactionStateData::parent, ShowTransactionState(), TransactionStateData::state, TransactionStateData::subTransactionId, SUBXACT_EVENT_START_SUB, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_START, TransStateAsString(), and WARNING.

Referenced by CommitTransactionCommandInternal().

◆ StartTransaction()

static void StartTransaction ( void  )
static

Definition at line 2064 of file xact.c.

2065{
2068
2069 /*
2070 * Let's just make sure the state stack is empty
2071 */
2074
2076
2077 /* check the current transaction state */
2078 Assert(s->state == TRANS_DEFAULT);
2079
2080 /*
2081 * Set the current transaction state information appropriately during
2082 * start processing. Note that once the transaction status is switched
2083 * this process cannot fail until the user ID and the security context
2084 * flags are fetched below.
2085 */
2086 s->state = TRANS_START;
2087 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2088
2089 /* Determine if statements are logged in this transaction */
2091 (log_xact_sample_rate == 1 ||
2093
2094 /*
2095 * initialize current transaction state fields
2096 *
2097 * note: prevXactReadOnly is not used at the outermost level
2098 */
2099 s->nestingLevel = 1;
2100 s->gucNestLevel = 1;
2101 s->childXids = NULL;
2102 s->nChildXids = 0;
2103 s->maxChildXids = 0;
2104
2105 /*
2106 * Once the current user ID and the security context flags are fetched,
2107 * both will be properly reset even if transaction startup fails.
2108 */
2110
2111 /* SecurityRestrictionContext should never be set outside a transaction */
2112 Assert(s->prevSecContext == 0);
2113
2114 /*
2115 * Make sure we've reset xact state variables
2116 *
2117 * If recovery is still in progress, mark this transaction as read-only.
2118 * We have lower level defences in XLogInsert and elsewhere to stop us
2119 * from modifying data during recovery, but this gives the normal
2120 * indication to the user that the transaction is read-only.
2121 */
2122 if (RecoveryInProgress())
2123 {
2124 s->startedInRecovery = true;
2125 XactReadOnly = true;
2126 }
2127 else
2128 {
2129 s->startedInRecovery = false;
2131 }
2134 forceSyncCommit = false;
2135 MyXactFlags = 0;
2136
2137 /*
2138 * reinitialize within-transaction counters
2139 */
2143 currentCommandIdUsed = false;
2144
2145 /*
2146 * initialize reported xid accounting
2147 */
2148 nUnreportedXids = 0;
2149 s->didLogXid = false;
2150
2151 /*
2152 * must initialize resource-management stuff first
2153 */
2156
2157 /*
2158 * Assign a new LocalTransactionId, and combine it with the proc number to
2159 * form a virtual transaction id.
2160 */
2161 vxid.procNumber = MyProcNumber;
2163
2164 /*
2165 * Lock the virtual transaction id before we announce it in the proc array
2166 */
2168
2169 /*
2170 * Advertise it in the proc array. We assume assignment of
2171 * localTransactionId is atomic, and the proc number should be set
2172 * already.
2173 */
2176
2177 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2178
2179 /*
2180 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2181 * be the same as the first command's statement_timestamp(), so don't do a
2182 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2183 * for transactions started inside procedures (i.e., nonatomic SPI
2184 * contexts), we do need to advance the timestamp. Also, in a parallel
2185 * worker, the timestamp should already have been provided by a call to
2186 * SetParallelStartTimestamps().
2187 */
2188 if (!IsParallelWorker())
2189 {
2192 else
2194 }
2195 else
2198 /* Mark xactStopTimestamp as unset. */
2200
2201 /*
2202 * initialize other subsystems for new transaction
2203 */
2204 AtStart_GUC();
2205 AtStart_Cache();
2207
2208 /*
2209 * done with start processing, set current transaction state to "in
2210 * progress"
2211 */
2213
2214 /* Schedule transaction timeout */
2215 if (TransactionTimeout > 0)
2217
2218 ShowTransactionState("StartTransaction");
2219}
#define TopSubTransactionId
Definition: c.h:630
#define FirstCommandId
Definition: c.h:639
ProcNumber MyProcNumber
Definition: globals.c:91
void AtStart_GUC(void)
Definition: guc.c:2215
double log_xact_sample_rate
Definition: guc_tables.c:547
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4587
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:268
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:700
bool SPI_inside_nonatomic_context(void)
Definition: spi.c:582
ProcNumber procNumber
Definition: proc.h:196
LocalTransactionId localTransactionId
Definition: lock.h:63
ProcNumber procNumber
Definition: lock.h:62
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:560
void AfterTriggerBeginXact(void)
Definition: trigger.c:5021
static void AtStart_Memory(void)
Definition: xact.c:1176
bool DefaultXactDeferrable
Definition: xact.c:84
static void AtStart_ResourceOwner(void)
Definition: xact.c:1226
static void AtStart_Cache(void)
Definition: xact.c:1167
int DefaultXactIsoLevel
Definition: xact.c:78
bool xact_is_sampled
Definition: xact.c:296
bool DefaultXactReadOnly
Definition: xact.c:81
bool RecoveryInProgress(void)
Definition: xlog.c:6522

References AfterTriggerBeginXact(), Assert(), AtStart_Cache(), AtStart_GUC(), AtStart_Memory(), AtStart_ResourceOwner(), TransactionStateData::childXids, currentCommandId, currentCommandIdUsed, currentSubTransactionId, CurrentTransactionState, DefaultXactDeferrable, DefaultXactIsoLevel, DefaultXactReadOnly, TransactionStateData::didLogXid, enable_timeout_after(), FirstCommandId, forceSyncCommit, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetCurrentTimestamp(), GetNextLocalTransactionId(), GetUserIdAndSecContext(), TransactionStateData::gucNestLevel, InvalidFullTransactionId, IsParallelWorker, VirtualTransactionId::localTransactionId, log_xact_sample_rate, PGPROC::lxid, TransactionStateData::maxChildXids, MyProc, MyProcNumber, MyXactFlags, TransactionStateData::nChildXids, TransactionStateData::nestingLevel, nUnreportedXids, pg_global_prng_state, pg_prng_double(), pgstat_report_xact_timestamp(), TransactionStateData::prevSecContext, TransactionStateData::prevUser, VirtualTransactionId::procNumber, PGPROC::procNumber, RecoveryInProgress(), ShowTransactionState(), SPI_inside_nonatomic_context(), TransactionStateData::startedInRecovery, TransactionStateData::state, stmtStartTimestamp, TransactionStateData::subTransactionId, TopSubTransactionId, TopTransactionStateData, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_START, TRANSACTION_TIMEOUT, TransactionTimeout, VirtualXactLockTableInsert(), PGPROC::vxid, xact_is_sampled, XactDeferrable, XactIsoLevel, XactReadOnly, xactStartTimestamp, xactStopTimestamp, and XactTopFullTransactionId.

Referenced by _doSetFixedOutputState(), CommitTransactionCommandInternal(), restore_toc_entry(), RestoreArchive(), StartParallelWorkerTransaction(), StartRestoreLOs(), and StartTransactionCommand().

◆ StartTransactionCommand()

void StartTransactionCommand ( void  )

Definition at line 3059 of file xact.c.

3060{
3062
3063 switch (s->blockState)
3064 {
3065 /*
3066 * if we aren't in a transaction block, we just do our usual start
3067 * transaction.
3068 */
3069 case TBLOCK_DEFAULT:
3072 break;
3073
3074 /*
3075 * We are somewhere in a transaction block or subtransaction and
3076 * about to start a new command. For now we do nothing, but
3077 * someday we may do command-local resource initialization. (Note
3078 * that any needed CommandCounterIncrement was done by the
3079 * previous CommitTransactionCommand.)
3080 */
3081 case TBLOCK_INPROGRESS:
3084 break;
3085
3086 /*
3087 * Here we are in a failed transaction block (one of the commands
3088 * caused an abort) so we do nothing but remain in the abort
3089 * state. Eventually we will get a ROLLBACK command which will
3090 * get us out of this state. (It is up to other code to ensure
3091 * that no commands other than ROLLBACK will be processed in these
3092 * states.)
3093 */
3094 case TBLOCK_ABORT:
3095 case TBLOCK_SUBABORT:
3096 break;
3097
3098 /* These cases are invalid. */
3099 case TBLOCK_STARTED:
3100 case TBLOCK_BEGIN:
3102 case TBLOCK_SUBBEGIN:
3103 case TBLOCK_END:
3104 case TBLOCK_SUBRELEASE:
3105 case TBLOCK_SUBCOMMIT:
3106 case TBLOCK_ABORT_END:
3110 case TBLOCK_SUBRESTART:
3112 case TBLOCK_PREPARE:
3113 elog(ERROR, "StartTransactionCommand: unexpected state %s",
3115 break;
3116 }
3117
3118 /*
3119 * We must switch to CurTransactionContext before returning. This is
3120 * already done if we called StartTransaction, otherwise not.
3121 */
3124}

References Assert(), TransactionStateData::blockState, BlockStateAsString(), CurrentTransactionState, CurTransactionContext, elog, ERROR, MemoryContextSwitchTo(), StartTransaction(), TBLOCK_ABORT, TBLOCK_ABORT_END, TBLOCK_ABORT_PENDING, TBLOCK_BEGIN, TBLOCK_DEFAULT, TBLOCK_END, TBLOCK_IMPLICIT_INPROGRESS, TBLOCK_INPROGRESS, TBLOCK_PARALLEL_INPROGRESS, TBLOCK_PREPARE, TBLOCK_STARTED, TBLOCK_SUBABORT, TBLOCK_SUBABORT_END, TBLOCK_SUBABORT_PENDING, TBLOCK_SUBABORT_RESTART, TBLOCK_SUBBEGIN, TBLOCK_SUBCOMMIT, TBLOCK_SUBINPROGRESS, TBLOCK_SUBRELEASE, and TBLOCK_SUBRESTART.

Referenced by _SPI_commit(), _SPI_rollback(), apply_handle_commit_internal(), ATExecDetachPartition(), autoprewarm_database_main(), bbsink_server_new(), begin_replication_step(), BeginInternalSubTransaction(), BootstrapModeMain(), clear_subscription_skip_lsn(), cluster(), cluster_multiple_rels(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), FetchTableStates(), finish_sync_worker(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), ParallelApplyWorkerMain(), ParallelWorkerMain(), perform_work_item(), process_syncing_tables_for_apply(), process_syncing_tables_for_sync(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), ReorderBufferProcessTXN(), run_apply_worker(), shell_check_detail(), SnapBuildExportSnapshot(), start_xact_command(), synchronize_slots(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ SubTransactionIsActive()

bool SubTransactionIsActive ( SubTransactionId  subxid)

Definition at line 805 of file xact.c.

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

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

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 5003 of file xact.c.

5004{
5006
5007 switch (s->blockState)
5008 {
5009 case TBLOCK_DEFAULT:
5010 case TBLOCK_STARTED:
5011 return 'I'; /* idle --- not in transaction */
5012 case TBLOCK_BEGIN:
5013 case TBLOCK_SUBBEGIN:
5014 case TBLOCK_INPROGRESS:
5018 case TBLOCK_END:
5019 case TBLOCK_SUBRELEASE:
5020 case TBLOCK_SUBCOMMIT:
5021 case TBLOCK_PREPARE:
5022 return 'T'; /* in transaction */
5023 case TBLOCK_ABORT:
5024 case TBLOCK_SUBABORT:
5025 case TBLOCK_ABORT_END:
5029 case TBLOCK_SUBRESTART:
5031 return 'E'; /* in failed transaction */
5032 }
5033
5034 /* should never get here */
5035 elog(FATAL, "invalid transaction block state: %s",
5037 return 0; /* keep compiler quiet */
5038}

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

Referenced by ReadyForQuery().

◆ TransactionIdIsCurrentTransactionId()

bool TransactionIdIsCurrentTransactionId ( TransactionId  xid)

Definition at line 941 of file xact.c.

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

References TransactionStateData::childXids, CurrentTransactionState, TransactionStateData::fullTransactionId, FullTransactionIdIsValid, GetTopTransactionIdIfAny(), TransactionStateData::nChildXids, nParallelCurrentXids, ParallelCurrentXids, TransactionStateData::parent, TransactionStateData::state, TRANS_ABORT, TransactionIdEquals, TransactionIdIsNormal, TransactionIdPrecedes(), and XidFromFullTransactionId.

Referenced by compute_new_xmax_infomask(), Do_MultiXactIdWait(), DoesMultiXactIdConflict(), ExecCheckTupleVisible(), ExecMergeMatched(), ExecOnConflictUpdate(), FreezeMultiXactId(), get_xid_status(), heap_delete(), heap_inplace_lock(), heap_lock_tuple(), heap_update(), heapam_index_build_range_scan(), heapam_relation_copy_for_cluster(), heapam_scan_analyze_next_tuple(), heapam_tuple_lock(), HeapTupleHeaderAdjustCmax(), HeapTupleHeaderGetCmax(), HeapTupleHeaderGetCmin(), HeapTupleHeaderIsOnlyLocked(), HeapTupleSatisfiesDirty(), HeapTupleSatisfiesMVCC(), HeapTupleSatisfiesSelf(), HeapTupleSatisfiesToast(), HeapTupleSatisfiesUpdate(), HeapTupleSatisfiesVacuumHorizon(), MultiXactIdIsRunning(), PredicateLockTID(), SnapBuildWaitSnapshot(), test_lockmode_for_conflict(), TransactionIdIsInProgress(), tts_buffer_is_current_xact_tuple(), and tts_heap_is_current_xact_tuple().

◆ TransactionStartedDuringRecovery()

bool TransactionStartedDuringRecovery ( void  )

Definition at line 1042 of file xact.c.

1043{
1045}

References CurrentTransactionState, and TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

◆ TransStateAsString()

static const char * TransStateAsString ( TransState  state)
static

Definition at line 5760 of file xact.c.

5761{
5762 switch (state)
5763 {
5764 case TRANS_DEFAULT:
5765 return "DEFAULT";
5766 case TRANS_START:
5767 return "START";
5768 case TRANS_INPROGRESS:
5769 return "INPROGRESS";
5770 case TRANS_COMMIT:
5771 return "COMMIT";
5772 case TRANS_ABORT:
5773 return "ABORT";
5774 case TRANS_PREPARE:
5775 return "PREPARE";
5776 }
5777 return "UNRECOGNIZED";
5778}
Definition: regguts.h:323

References TRANS_ABORT, TRANS_COMMIT, TRANS_DEFAULT, TRANS_INPROGRESS, TRANS_PREPARE, and TRANS_START.

Referenced by AbortSubTransaction(), AbortTransaction(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), PopTransaction(), PrepareTransaction(), ShowTransactionStateRec(), and StartSubTransaction().

◆ UnregisterSubXactCallback()

void UnregisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3877 of file xact.c.

3878{
3879 SubXactCallbackItem *item;
3880 SubXactCallbackItem *prev;
3881
3882 prev = NULL;
3883 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3884 {
3885 if (item->callback == callback && item->arg == arg)
3886 {
3887 if (prev)
3888 prev->next = item->next;
3889 else
3890 SubXact_callbacks = item->next;
3891 pfree(item);
3892 break;
3893 }
3894 }
3895}

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

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3817 of file xact.c.

3818{
3819 XactCallbackItem *item;
3820 XactCallbackItem *prev;
3821
3822 prev = NULL;
3823 for (item = Xact_callbacks; item; prev = item, item = item->next)
3824 {
3825 if (item->callback == callback && item->arg == arg)
3826 {
3827 if (prev)
3828 prev->next = item->next;
3829 else
3830 Xact_callbacks = item->next;
3831 pfree(item);
3832 break;
3833 }
3834 }
3835}

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

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4204 of file xact.c.

4205{
4207
4208 switch (s->blockState)
4209 {
4210 /*
4211 * We are inside a transaction block and we got a ROLLBACK command
4212 * from the user, so tell CommitTransactionCommand to abort and
4213 * exit the transaction block.
4214 */
4215 case TBLOCK_INPROGRESS:
4217 break;
4218
4219 /*
4220 * We are inside a failed transaction block and we got a ROLLBACK
4221 * command from the user. Abort processing is already done, so
4222 * CommitTransactionCommand just has to cleanup and go back to
4223 * idle state.
4224 */
4225 case TBLOCK_ABORT:
4227 break;
4228
4229 /*
4230 * We are inside a subtransaction. Mark everything up to top
4231 * level as exitable.
4232 */
4234 case TBLOCK_SUBABORT:
4235 while (s->parent != NULL)
4236 {
4239 else if (s->blockState == TBLOCK_SUBABORT)
4241 else
4242 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4244 s = s->parent;
4245 }
4246 if (s->blockState == TBLOCK_INPROGRESS)
4248 else if (s->blockState == TBLOCK_ABORT)
4250 else
4251 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4253 break;
4254
4255 /*
4256 * The user issued ABORT when not inside a transaction. For
4257 * ROLLBACK without CHAIN, issue a WARNING and go to abort state.
4258 * The upcoming call to CommitTransactionCommand() will then put
4259 * us back into the default state. For ROLLBACK AND CHAIN, error.
4260 *
4261 * We do the same thing with ABORT inside an implicit transaction,
4262 * although in this case we might be rolling back actual database
4263 * state changes. (It's debatable whether we should issue a
4264 * WARNING in this case, but we have done so historically.)
4265 */
4266 case TBLOCK_STARTED:
4268 if (chain)
4269 ereport(ERROR,
4270 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4271 /* translator: %s represents an SQL statement name */
4272 errmsg("%s can only be used in transaction blocks",
4273 "ROLLBACK AND CHAIN")));
4274 else
4276 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
4277 errmsg("there is no transaction in progress")));
4279 break;
4280
4281 /*
4282 * The user issued an ABORT that somehow ran inside a parallel
4283 * worker. We can't cope with that.
4284 */
4286 ereport(FATAL,
4287 (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
4288 errmsg("cannot abort during a parallel operation")));
4289 break;
4290
4291 /* These cases are invalid. */
4292 case TBLOCK_DEFAULT:
4293 case TBLOCK_BEGIN:
4294 case TBLOCK_SUBBEGIN:
4295 case TBLOCK_END:
4296 case TBLOCK_SUBRELEASE:
4297 case TBLOCK_SUBCOMMIT:
4298 case TBLOCK_ABORT_END:
4302 case TBLOCK_SUBRESTART:
4304 case TBLOCK_PREPARE:
4305 elog(FATAL, "UserAbortTransactionBlock: unexpected state %s",
4307 break;
4308 }
4309
4312
4313 s->chain = chain;
4314}

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

Referenced by standard_ProcessUtility().

◆ WarnNoTransactionBlock()

void WarnNoTransactionBlock ( bool  isTopLevel,
const char *  stmtType 
)

Definition at line 3710 of file xact.c.

3711{
3712 CheckTransactionBlock(isTopLevel, false, stmtType);
3713}

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6363 of file xact.c.

6364{
6365 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6366
6367 /* Backup blocks are not used in xact records */
6369
6370 if (info == XLOG_XACT_COMMIT)
6371 {
6372 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6373 xl_xact_parsed_commit parsed;
6374
6375 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6376 xact_redo_commit(&parsed, XLogRecGetXid(record),
6377 record->EndRecPtr, XLogRecGetOrigin(record));
6378 }
6379 else if (info == XLOG_XACT_COMMIT_PREPARED)
6380 {
6381 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6382 xl_xact_parsed_commit parsed;
6383
6384 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6385 xact_redo_commit(&parsed, parsed.twophase_xid,
6386 record->EndRecPtr, XLogRecGetOrigin(record));
6387
6388 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6389 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6390 PrepareRedoRemove(parsed.twophase_xid, false);
6391 LWLockRelease(TwoPhaseStateLock);
6392 }
6393 else if (info == XLOG_XACT_ABORT)
6394 {
6395 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6396 xl_xact_parsed_abort parsed;
6397
6398 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6399 xact_redo_abort(&parsed, XLogRecGetXid(record),
6400 record->EndRecPtr, XLogRecGetOrigin(record));
6401 }
6402 else if (info == XLOG_XACT_ABORT_PREPARED)
6403 {
6404 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6405 xl_xact_parsed_abort parsed;
6406
6407 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6408 xact_redo_abort(&parsed, parsed.twophase_xid,
6409 record->EndRecPtr, XLogRecGetOrigin(record));
6410
6411 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6412 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6413 PrepareRedoRemove(parsed.twophase_xid, false);
6414 LWLockRelease(TwoPhaseStateLock);
6415 }
6416 else if (info == XLOG_XACT_PREPARE)
6417 {
6418 /*
6419 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6420 * gxact entry.
6421 */
6422 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6424 record->ReadRecPtr,
6425 record->EndRecPtr,
6426 XLogRecGetOrigin(record));
6427 LWLockRelease(TwoPhaseStateLock);
6428 }
6429 else if (info == XLOG_XACT_ASSIGNMENT)
6430 {
6432
6435 xlrec->nsubxacts, xlrec->xsub);
6436 }
6437 else if (info == XLOG_XACT_INVALIDATIONS)
6438 {
6439 /*
6440 * XXX we do ignore this for now, what matters are invalidations
6441 * written into the commit record.
6442 */
6443 }
6444 else
6445 elog(PANIC, "xact_redo: unknown op code %u", info);
6446}
uint8_t uint8
Definition: c.h:500
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1182
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1902
@ LW_EXCLUSIVE
Definition: lwlock.h:114
void ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids)
Definition: procarray.c:1318
XLogRecPtr EndRecPtr
Definition: xlogreader.h:207
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:206
TransactionId xsub[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.h:222
TransactionId twophase_xid
Definition: xact.h:427
TransactionId twophase_xid
Definition: xact.h:397
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2571
void PrepareRedoAdd(char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2469
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6130
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6284
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:172
#define XLOG_XACT_INVALIDATIONS
Definition: xact.h:175
#define XLOG_XACT_PREPARE
Definition: xact.h:170
#define XLOG_XACT_COMMIT
Definition: xact.h:169
#define XLOG_XACT_OPMASK
Definition: xact.h:179
#define XLOG_XACT_ABORT
Definition: xact.h:171
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:173
void ParseCommitRecord(uint8 info, xl_xact_commit *xlrec, xl_xact_parsed_commit *parsed)
Definition: xactdesc.c:35
void ParseAbortRecord(uint8 info, xl_xact_abort *xlrec, xl_xact_parsed_abort *parsed)
Definition: xactdesc.c:141
#define XLogRecGetOrigin(decoder)
Definition: xlogreader.h:413
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLogRecGetXid(decoder)
Definition: xlogreader.h:412
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:417
HotStandbyState standbyState
Definition: xlogutils.c:53
@ STANDBY_INITIALIZED
Definition: xlogutils.h:53

References Assert(), elog, XLogReaderState::EndRecPtr, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_xact_assignment::nsubxacts, PANIC, ParseAbortRecord(), ParseCommitRecord(), PrepareRedoAdd(), PrepareRedoRemove(), ProcArrayApplyXidAssignment(), XLogReaderState::ReadRecPtr, STANDBY_INITIALIZED, standbyState, xl_xact_parsed_commit::twophase_xid, xl_xact_parsed_abort::twophase_xid, xact_redo_abort(), xact_redo_commit(), XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_ASSIGNMENT, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_INVALIDATIONS, XLOG_XACT_OPMASK, XLOG_XACT_PREPARE, XLogRecGetData, XLogRecGetInfo, XLogRecGetOrigin, XLogRecGetXid, XLogRecHasAnyBlockRefs, xl_xact_assignment::xsub, and xl_xact_assignment::xtop.

◆ xact_redo_abort()

static void xact_redo_abort ( xl_xact_parsed_abort parsed,
TransactionId  xid,
XLogRecPtr  lsn,
RepOriginId  origin_id 
)
static

Definition at line 6284 of file xact.c.

6286{
6287 TransactionId max_xid;
6288
6290
6291 /* Make sure nextXid is beyond any XID mentioned in the record. */
6292 max_xid = TransactionIdLatest(xid,
6293 parsed->nsubxacts,
6294 parsed->subxacts);
6296
6298 {
6299 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6300 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6301 }
6302 else
6303 {
6304 /*
6305 * If a transaction completion record arrives that has as-yet
6306 * unobserved subtransactions then this will not have been fully
6307 * handled by the call to RecordKnownAssignedTransactionIds() in the
6308 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6309 * cover that case. This is confusing and it is easy to think this
6310 * call is irrelevant, which has happened three times in development
6311 * already. Leave it in.
6312 */
6314
6315 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6316 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6317
6318 /*
6319 * We must update the ProcArray after we have marked clog.
6320 */
6321 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6322
6323 /*
6324 * There are no invalidation messages to send or undo.
6325 */
6326
6327 /*
6328 * Release locks, if any. There are no invalidations to send.
6329 */
6330 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6331 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6332 }
6333
6334 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6335 {
6336 /* recover apply progress */
6337 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6338 false /* backward */ , false /* WAL */ );
6339 }
6340
6341 /* Make sure files supposed to be dropped are dropped */
6342 if (parsed->nrels > 0)
6343 {
6344 /*
6345 * See comments about update of minimum recovery point on truncation,
6346 * in xact_redo_commit().
6347 */
6348 XLogFlush(lsn);
6349
6350 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6351 }
6352
6353 if (parsed->nstats > 0)
6354 {
6355 /* see equivalent call for relations above */
6356 XLogFlush(lsn);
6357
6358 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6359 }
6360}
void DropRelationFiles(RelFileLocator *delrels, int ndelrels, bool isRedo)
Definition: md.c:1587
void replorigin_advance(RepOriginId node, XLogRecPtr remote_commit, XLogRecPtr local_commit, bool go_backward, bool wal_log)
Definition: origin.c:888
void pgstat_execute_transactional_drops(int ndrops, struct xl_xact_stats_item *items, bool is_redo)
Definition: pgstat_xact.c:314
void RecordKnownAssignedTransactionIds(TransactionId xid)
Definition: procarray.c:4403
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition: procarray.c:4472
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition: standby.c:1092
xl_xact_stats_item * stats
Definition: xact.h:425
RelFileLocator * xlocators
Definition: xact.h:422
TransactionId * subxacts
Definition: xact.h:419
XLogRecPtr origin_lsn
Definition: xact.h:430
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition: varsup.c:304
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:193
#define XACT_XINFO_HAS_AE_LOCKS
Definition: xact.h:194
@ STANDBY_DISABLED
Definition: xlogutils.h:52

References AdvanceNextFullTransactionIdPastXid(), Assert(), DropRelationFiles(), ExpireTreeKnownAssignedTransactionIds(), xl_xact_parsed_abort::nrels, xl_xact_parsed_abort::nstats, xl_xact_parsed_abort::nsubxacts, xl_xact_parsed_abort::origin_lsn, pgstat_execute_transactional_drops(), RecordKnownAssignedTransactionIds(), replorigin_advance(), STANDBY_DISABLED, StandbyReleaseLockTree(), standbyState, xl_xact_parsed_abort::stats, xl_xact_parsed_abort::subxacts, TransactionIdAbortTree(), TransactionIdIsValid, TransactionIdLatest(), XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_ORIGIN, xl_xact_parsed_abort::xinfo, xl_xact_parsed_abort::xlocators, and XLogFlush().

Referenced by xact_redo().

◆ xact_redo_commit()

static void xact_redo_commit ( xl_xact_parsed_commit parsed,
TransactionId  xid,
XLogRecPtr  lsn,
RepOriginId  origin_id 
)
static

Definition at line 6130 of file xact.c.

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

References AdvanceNextFullTransactionIdPastXid(), Assert(), xl_xact_parsed_commit::dbId, DropRelationFiles(), ExpireTreeKnownAssignedTransactionIds(), InvalidRepOriginId, xl_xact_parsed_commit::msgs, xl_xact_parsed_commit::nmsgs, xl_xact_parsed_commit::nrels, xl_xact_parsed_commit::nstats, xl_xact_parsed_commit::nsubxacts, xl_xact_parsed_commit::origin_lsn, xl_xact_parsed_commit::origin_timestamp, pgstat_execute_transactional_drops(), ProcessCommittedInvalidationMessages(), RecordKnownAssignedTransactionIds(), replorigin_advance(), STANDBY_DISABLED, StandbyReleaseLockTree(), standbyState, xl_xact_parsed_commit::stats, xl_xact_parsed_commit::subxacts, TransactionIdAsyncCommitTree(), TransactionIdCommitTree(), TransactionIdIsValid, TransactionIdLatest(), TransactionTreeSetCommitTsData(), xl_xact_parsed_commit::tsId, xl_xact_parsed_commit::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_ORIGIN, XactCompletionApplyFeedback, XactCompletionForceSyncCommit, XactCompletionRelcacheInitFileInval, xl_xact_parsed_commit::xinfo, xl_xact_parsed_commit::xlocators, XLogFlush(), and XLogRequestWalReceiverReply().

Referenced by xact_redo().

◆ xactGetCommittedChildren()

int xactGetCommittedChildren ( TransactionId **  ptr)

Definition at line 5790 of file xact.c.

5791{
5793
5794 if (s->nChildXids == 0)
5795 *ptr = NULL;
5796 else
5797 *ptr = s->childXids;
5798
5799 return s->nChildXids;
5800}

References TransactionStateData::childXids, CurrentTransactionState, and TransactionStateData::nChildXids.

Referenced by ExportSnapshot(), RecordTransactionAbort(), RecordTransactionCommit(), and StartPrepare().

◆ XactLogAbortRecord()

XLogRecPtr XactLogAbortRecord ( TimestampTz  abort_time,
int  nsubxacts,
TransactionId subxacts,
int  nrels,
RelFileLocator rels,
int  ndroppedstats,
xl_xact_stats_item droppedstats,
int  xactflags,
TransactionId  twophase_xid,
const char *  twophase_gid 
)

Definition at line 5986 of file xact.c.

5992{
5993 xl_xact_abort xlrec;
5994 xl_xact_xinfo xl_xinfo;
5995 xl_xact_subxacts xl_subxacts;
5996 xl_xact_relfilelocators xl_relfilelocators;
5997 xl_xact_stats_items xl_dropped_stats;
5998 xl_xact_twophase xl_twophase;
5999 xl_xact_dbinfo xl_dbinfo;
6000 xl_xact_origin xl_origin;
6001
6002 uint8 info;
6003
6005
6006 xl_xinfo.xinfo = 0;
6007
6008 /* decide between a plain and 2pc abort */
6009 if (!TransactionIdIsValid(twophase_xid))
6010 info = XLOG_XACT_ABORT;
6011 else
6013
6014
6015 /* First figure out and collect all the information needed */
6016
6017 xlrec.xact_time = abort_time;
6018
6020 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
6021
6022 if (nsubxacts > 0)
6023 {
6024 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
6025 xl_subxacts.nsubxacts = nsubxacts;
6026 }
6027
6028 if (nrels > 0)
6029 {
6031 xl_relfilelocators.nrels = nrels;
6032 info |= XLR_SPECIAL_REL_UPDATE;
6033 }
6034
6035 if (ndroppedstats > 0)
6036 {
6038 xl_dropped_stats.nitems = ndroppedstats;
6039 }
6040
6041 if (TransactionIdIsValid(twophase_xid))
6042 {
6043 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
6044 xl_twophase.xid = twophase_xid;
6045 Assert(twophase_gid != NULL);
6046
6048 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6049 }
6050
6051 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6052 {
6053 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6054 xl_dbinfo.dbId = MyDatabaseId;
6055 xl_dbinfo.tsId = MyDatabaseTableSpace;
6056 }
6057
6058 /*
6059 * Dump transaction origin information. We need this during recovery to
6060 * update the replication origin progress.
6061 */
6063 {
6064 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6065
6068 }
6069
6070 if (xl_xinfo.xinfo != 0)
6071 info |= XLOG_XACT_HAS_INFO;
6072
6073 /* Then include all the collected data into the abort record. */
6074
6076
6078
6079 if (xl_xinfo.xinfo != 0)
6080 XLogRegisterData(&xl_xinfo, sizeof(xl_xinfo));
6081
6082 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6083 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
6084
6085 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6086 {
6087 XLogRegisterData(&xl_subxacts,
6089 XLogRegisterData(subxacts,
6090 nsubxacts * sizeof(TransactionId));
6091 }
6092
6094 {
6095 XLogRegisterData(&xl_relfilelocators,
6097 XLogRegisterData(rels,
6098 nrels * sizeof(RelFileLocator));
6099 }
6100
6101 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6102 {
6103 XLogRegisterData(&xl_dropped_stats,
6105 XLogRegisterData(droppedstats,
6106 ndroppedstats * sizeof(xl_xact_stats_item));
6107 }
6108
6109 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6110 {
6111 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
6112 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6113 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6114 }
6115
6116 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6117 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
6118
6119 /* Include the replication origin */
6121
6122 return XLogInsert(RM_XACT_ID, info);
6123}
Oid MyDatabaseTableSpace
Definition: globals.c:97
volatile uint32 CritSectionCount
Definition: globals.c:46
TimestampTz xact_time
Definition: xact.h:338
Oid tsId
Definition: xact.h:258
Oid dbId
Definition: xact.h:257
TimestampTz origin_timestamp
Definition: xact.h:317
XLogRecPtr origin_lsn
Definition: xact.h:316
int nsubxacts
Definition: xact.h:263
TransactionId xid
Definition: xact.h:311
uint32 xinfo
Definition: xact.h:252
#define MinSizeOfXactSubxacts
Definition: xact.h:266
#define XACT_XINFO_HAS_GID
Definition: xact.h:195
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:108
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:192
#define MinSizeOfXactRelfileLocators
Definition: xact.h:273
#define MinSizeOfXactStatsItems
Definition: xact.h:300
#define XACT_XINFO_HAS_RELFILELOCATORS
Definition: xact.h:190
#define MinSizeOfXactAbort
Definition: xact.h:350
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:188
#define XLOG_XACT_HAS_INFO
Definition: xact.h:182
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:189
#define XACT_XINFO_HAS_DROPPED_STATS
Definition: xact.h:196
#define XLOG_INCLUDE_ORIGIN
Definition: xlog.h:154
void XLogSetRecordFlags(uint8 flags)
Definition: xloginsert.c:456
#define XLR_SPECIAL_REL_UPDATE
Definition: xlogrecord.h:82

References Assert(), CritSectionCount, xl_xact_dbinfo::dbId, InvalidRepOriginId, MinSizeOfXactAbort, MinSizeOfXactRelfileLocators, MinSizeOfXactStatsItems, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, xl_xact_stats_items::nitems, xl_xact_relfilelocators::nrels, xl_xact_subxacts::nsubxacts, xl_xact_origin::origin_lsn, xl_xact_origin::origin_timestamp, replorigin_session_origin, replorigin_session_origin_lsn, replorigin_session_origin_timestamp, TransactionIdIsValid, xl_xact_dbinfo::tsId, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, xl_xact_abort::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_DROPPED_STATS, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILELOCATORS, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, xl_xact_twophase::xid, xl_xact_xinfo::xinfo, XLOG_INCLUDE_ORIGIN, XLOG_XACT_ABORT, XLOG_XACT_ABORT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogSetRecordFlags(), and XLR_SPECIAL_REL_UPDATE.

Referenced by RecordTransactionAbort(), and RecordTransactionAbortPrepared().

◆ XactLogCommitRecord()

XLogRecPtr XactLogCommitRecord ( TimestampTz  commit_time,
int  nsubxacts,
TransactionId subxacts,
int  nrels,
RelFileLocator rels,
int  ndroppedstats,
xl_xact_stats_item droppedstats,
int  nmsgs,
SharedInvalidationMessage msgs,
bool  relcacheInval,
int  xactflags,
TransactionId  twophase_xid,
const char *  twophase_gid 
)

Definition at line 5814 of file xact.c.

5822{
5823 xl_xact_commit xlrec;
5824 xl_xact_xinfo xl_xinfo;
5825 xl_xact_dbinfo xl_dbinfo;
5826 xl_xact_subxacts xl_subxacts;
5827 xl_xact_relfilelocators xl_relfilelocators;
5828 xl_xact_stats_items xl_dropped_stats;
5829 xl_xact_invals xl_invals;
5830 xl_xact_twophase xl_twophase;
5831 xl_xact_origin xl_origin;
5832 uint8 info;
5833
5835
5836 xl_xinfo.xinfo = 0;
5837
5838 /* decide between a plain and 2pc commit */
5839 if (!TransactionIdIsValid(twophase_xid))
5840 info = XLOG_XACT_COMMIT;
5841 else
5843
5844 /* First figure out and collect all the information needed */
5845
5846 xlrec.xact_time = commit_time;
5847
5848 if (relcacheInval)
5850 if (forceSyncCommit)
5853 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5854
5855 /*
5856 * Check if the caller would like to ask standbys for immediate feedback
5857 * once this commit is applied.
5858 */
5861
5862 /*
5863 * Relcache invalidations requires information about the current database
5864 * and so does logical decoding.
5865 */
5866 if (nmsgs > 0 || XLogLogicalInfoActive())
5867 {
5868 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5869 xl_dbinfo.dbId = MyDatabaseId;
5870 xl_dbinfo.tsId = MyDatabaseTableSpace;
5871 }
5872
5873 if (nsubxacts > 0)
5874 {
5875 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5876 xl_subxacts.nsubxacts = nsubxacts;
5877 }
5878
5879 if (nrels > 0)
5880 {
5882 xl_relfilelocators.nrels = nrels;
5883 info |= XLR_SPECIAL_REL_UPDATE;
5884 }
5885
5886 if (ndroppedstats > 0)
5887 {
5889 xl_dropped_stats.nitems = ndroppedstats;
5890 }
5891
5892 if (nmsgs > 0)
5893 {
5894 xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5895 xl_invals.nmsgs = nmsgs;
5896 }
5897
5898 if (TransactionIdIsValid(twophase_xid))
5899 {
5900 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5901 xl_twophase.xid = twophase_xid;
5902 Assert(twophase_gid != NULL);
5903
5905 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5906 }
5907
5908 /* dump transaction origin information */
5910 {
5911 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5912
5915 }
5916
5917 if (xl_xinfo.xinfo != 0)
5918 info |= XLOG_XACT_HAS_INFO;
5919
5920 /* Then include all the collected data into the commit record. */
5921
5923
5924 XLogRegisterData(&xlrec, sizeof(xl_xact_commit));
5925
5926 if (xl_xinfo.xinfo != 0)
5927 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5928
5929 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5930 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
5931
5932 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5933 {
5934 XLogRegisterData(&xl_subxacts,
5936 XLogRegisterData(subxacts,
5937 nsubxacts * sizeof(TransactionId));
5938 }
5939
5941 {
5942 XLogRegisterData(&xl_relfilelocators,
5944 XLogRegisterData(rels,
5945 nrels * sizeof(RelFileLocator));
5946 }
5947
5948 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5949 {
5950 XLogRegisterData(&xl_dropped_stats,
5952 XLogRegisterData(droppedstats,
5953 ndroppedstats * sizeof(xl_xact_stats_item));
5954 }
5955
5956 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5957 {
5959 XLogRegisterData(msgs,
5960 nmsgs * sizeof(SharedInvalidationMessage));
5961 }
5962
5963 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5964 {
5965 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
5966 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5967 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5968 }
5969
5970 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5971 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
5972
5973 /* we allow filtering by xacts */
5975
5976 return XLogInsert(RM_XACT_ID, info);
5977}
TimestampTz xact_time
Definition: xact.h:322
int nmsgs
Definition: xact.h:304
#define MinSizeOfXactInvals
Definition: xact.h:307
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE
Definition: xact.h:207
#define XACT_COMPLETION_FORCE_SYNC_COMMIT
Definition: xact.h:208
@ SYNCHRONOUS_COMMIT_REMOTE_APPLY
Definition: xact.h:75
#define XACT_COMPLETION_APPLY_FEEDBACK
Definition: xact.h:206
#define XACT_XINFO_HAS_INVALS
Definition: xact.h:191

References Assert(), CritSectionCount, xl_xact_dbinfo::dbId, forceSyncCommit, InvalidRepOriginId, MinSizeOfXactInvals, MinSizeOfXactRelfileLocators, MinSizeOfXactStatsItems, MinSizeOfXactSubxacts, MyDatabaseId, MyDatabaseTableSpace, xl_xact_stats_items::nitems, xl_xact_invals::nmsgs, xl_xact_relfilelocators::nrels, xl_xact_subxacts::nsubxacts, xl_xact_origin::origin_lsn, xl_xact_origin::origin_timestamp, replorigin_session_origin, replorigin_session_origin_lsn, replorigin_session_origin_timestamp, synchronous_commit, SYNCHRONOUS_COMMIT_REMOTE_APPLY, TransactionIdIsValid, xl_xact_dbinfo::tsId, XACT_COMPLETION_APPLY_FEEDBACK, XACT_COMPLETION_FORCE_SYNC_COMMIT, XACT_COMPLETION_UPDATE_RELCACHE_FILE, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, xl_xact_commit::xact_time, XACT_XINFO_HAS_AE_LOCKS, XACT_XINFO_HAS_DBINFO, XACT_XINFO_HAS_DROPPED_STATS, XACT_XINFO_HAS_GID, XACT_XINFO_HAS_INVALS, XACT_XINFO_HAS_ORIGIN, XACT_XINFO_HAS_RELFILELOCATORS, XACT_XINFO_HAS_SUBXACTS, XACT_XINFO_HAS_TWOPHASE, xl_xact_twophase::xid, xl_xact_xinfo::xinfo, XLOG_INCLUDE_ORIGIN, XLOG_XACT_COMMIT, XLOG_XACT_COMMIT_PREPARED, XLOG_XACT_HAS_INFO, XLogBeginInsert(), XLogInsert(), XLogLogicalInfoActive, XLogRegisterData(), XLogSetRecordFlags(), and XLR_SPECIAL_REL_UPDATE.

Referenced by RecordTransactionCommit(), and RecordTransactionCommitPrepared().

Variable Documentation

◆ bsysscan

◆ CheckXidAlive

◆ currentCommandId

◆ currentCommandIdUsed

bool currentCommandIdUsed
static

◆ currentSubTransactionId

SubTransactionId currentSubTransactionId
static

Definition at line 266 of file xact.c.

Referenced by PushTransaction(), and StartTransaction().

◆ CurrentTransactionState

TransactionState CurrentTransactionState = &TopTransactionStateData
static

Definition at line 260 of file xact.c.

Referenced by AbortCurrentTransactionInternal(), AbortOutOfAnyTransaction(), AbortSubTransaction(), AbortTransaction(), AtCleanup_Memory(), AtCommit_Memory(), AtStart_Memory(), AtStart_ResourceOwner(), AtSubAbort_childXids(), AtSubAbort_ResourceOwner(), AtSubCleanup_Memory(), AtSubCommit_childXids(), AtSubCommit_Memory(), AtSubStart_Memory(), AtSubStart_ResourceOwner(), BeginImplicitTransactionBlock(), BeginInternalSubTransaction(), BeginTransactionBlock(), CleanupSubTransaction(), CleanupTransaction(), CommitSubTransaction(), CommitTransaction(), CommitTransactionCommandInternal(), DefineSavepoint(), EndImplicitTransactionBlock(), EndParallelWorkerTransaction(), EndTransactionBlock(), EnterParallelMode(), EstimateTransactionStateSpace(), ExitParallelMode(), GetCurrentFullTransactionId(), GetCurrentFullTransactionIdIfAny(), GetCurrentSubTransactionId(), GetCurrentTransactionId(), GetCurrentTransactionIdIfAny(), GetCurrentTransactionNestLevel(), GetCurrentTransactionStopTimestamp(), IsAbortedTransactionBlockState(), IsInParallelMode(), IsInTransactionBlock(), IsSubTransaction(), IsSubxactTopXidLogPending(), IsTransactionBlock(), IsTransactionOrTransactionBlock(), IsTransactionState(), MarkCurrentTransactionIdLoggedIfAny(), MarkSubxactTopXidLogged(), PopTransaction(), PrepareTransaction(), PrepareTransactionBlock(), PreventInTransactionBlock(), PushTransaction(), ReleaseCurrentSubTransaction(), ReleaseSavepoint(), RollbackAndReleaseCurrentSubTransaction(), RollbackToSavepoint(), SerializeTransactionState(), ShowTransactionState(), StartParallelWorkerTransaction(), StartSubTransaction(), StartTransaction(), StartTransactionCommand(), SubTransactionIsActive(), TransactionBlockStatusCode(), TransactionIdIsCurrentTransactionId(), TransactionStartedDuringRecovery(), UserAbortTransactionBlock(), and xactGetCommittedChildren().

◆ DefaultXactDeferrable

bool DefaultXactDeferrable = false

Definition at line 84 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactIsoLevel

int DefaultXactIsoLevel = XACT_READ_COMMITTED

Definition at line 78 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactReadOnly

bool DefaultXactReadOnly = false

Definition at line 81 of file xact.c.

Referenced by StartTransaction().

◆ forceSyncCommit

bool forceSyncCommit = false
static

◆ MyXactFlags

◆ nParallelCurrentXids

◆ nUnreportedXids

int nUnreportedXids
static

Definition at line 257 of file xact.c.

Referenced by AssignTransactionId(), and StartTransaction().

◆ ParallelCurrentXids

TransactionId* ParallelCurrentXids
static

◆ prepareGID

char* prepareGID
static

Definition at line 288 of file xact.c.

Referenced by PrepareTransaction(), and PrepareTransactionBlock().

◆ stmtStartTimestamp

◆ SubXact_callbacks

SubXactCallbackItem* SubXact_callbacks = NULL
static

◆ synchronous_commit

int synchronous_commit = SYNCHRONOUS_COMMIT_ON

Definition at line 87 of file xact.c.

Referenced by AutoVacWorkerMain(), RecordTransactionCommit(), and XactLogCommitRecord().

◆ TopTransactionStateData

TransactionStateData TopTransactionStateData
static
Initial value:
= {
.state = TRANS_DEFAULT,
.blockState = TBLOCK_DEFAULT,
.topXidLogged = false,
}

Definition at line 247 of file xact.c.

Referenced by AssignTransactionId(), GetTopFullTransactionId(), GetTopTransactionId(), and StartTransaction().

◆ TransactionAbortContext

MemoryContext TransactionAbortContext = NULL
static

◆ unreportedXids

TransactionId unreportedXids[PGPROC_MAX_CACHED_SUBXIDS]
static

Definition at line 258 of file xact.c.

Referenced by AssignTransactionId().

◆ Xact_callbacks

XactCallbackItem* Xact_callbacks = NULL
static

Definition at line 315 of file xact.c.

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

◆ xact_is_sampled

bool xact_is_sampled = false

Definition at line 296 of file xact.c.

Referenced by check_log_duration(), and StartTransaction().

◆ XactDeferrable

◆ XactIsoLevel

◆ XactReadOnly

◆ xactStartTimestamp

TimestampTz xactStartTimestamp
static

◆ xactStopTimestamp

TimestampTz xactStopTimestamp
static

Definition at line 282 of file xact.c.

Referenced by GetCurrentTransactionStopTimestamp(), and StartTransaction().

◆ XactTopFullTransactionId