Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

PostgreSQL Source Code git master
xact.c File Reference
#include "postgres.h"
#include <time.h>
#include <unistd.h>
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/parallel.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "catalog/index.h"
#include "catalog/namespace.h"
#include "catalog/pg_enum.h"
#include "catalog/storage.h"
#include "commands/async.h"
#include "commands/tablecmds.h"
#include "commands/trigger.h"
#include "common/pg_prng.h"
#include "executor/spi.h"
#include "libpq/be-fsstubs.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "replication/logical.h"
#include "replication/logicallauncher.h"
#include "replication/logicalworker.h"
#include "replication/origin.h"
#include "replication/snapbuild.h"
#include "replication/syncrep.h"
#include "storage/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 3463 of file xact.c.

3464{
3465 /*
3466 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3467 * done.
3468 */
3470 {
3471 }
3472}
static bool AbortCurrentTransactionInternal(void)
Definition: xact.c:3481

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

3482{
3484
3485 switch (s->blockState)
3486 {
3487 case TBLOCK_DEFAULT:
3488 if (s->state == TRANS_DEFAULT)
3489 {
3490 /* we are idle, so nothing to do */
3491 }
3492 else
3493 {
3494 /*
3495 * We can get here after an error during transaction start
3496 * (state will be TRANS_START). Need to clean up the
3497 * incompletely started transaction. First, adjust the
3498 * low-level state to suppress warning message from
3499 * AbortTransaction.
3500 */
3501 if (s->state == TRANS_START)
3505 }
3506 break;
3507
3508 /*
3509 * If we aren't in a transaction block, we just do the basic abort
3510 * & cleanup transaction. For this purpose, we treat an implicit
3511 * transaction block as if it were a simple statement.
3512 */
3513 case TBLOCK_STARTED:
3518 break;
3519
3520 /*
3521 * If we are in TBLOCK_BEGIN it means something screwed up right
3522 * after reading "BEGIN TRANSACTION". We assume that the user
3523 * will interpret the error as meaning the BEGIN failed to get him
3524 * into a transaction block, so we should abort and return to idle
3525 * state.
3526 */
3527 case TBLOCK_BEGIN:
3531 break;
3532
3533 /*
3534 * We are somewhere in a transaction block and we've gotten a
3535 * failure, so we abort the transaction and set up the persistent
3536 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3537 */
3538 case TBLOCK_INPROGRESS:
3542 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3543 break;
3544
3545 /*
3546 * Here, we failed while trying to COMMIT. Clean up the
3547 * transaction and return to idle state (we do not want to stay in
3548 * the transaction).
3549 */
3550 case TBLOCK_END:
3554 break;
3555
3556 /*
3557 * Here, we are already in an aborted transaction state and are
3558 * waiting for a ROLLBACK, but for some reason we failed again! So
3559 * we just remain in the abort state.
3560 */
3561 case TBLOCK_ABORT:
3562 case TBLOCK_SUBABORT:
3563 break;
3564
3565 /*
3566 * We are in a failed transaction and we got the ROLLBACK command.
3567 * We have already aborted, we just need to cleanup and go to idle
3568 * state.
3569 */
3570 case TBLOCK_ABORT_END:
3573 break;
3574
3575 /*
3576 * We are in a live transaction and we got a ROLLBACK command.
3577 * Abort, cleanup, go to idle state.
3578 */
3583 break;
3584
3585 /*
3586 * Here, we failed while trying to PREPARE. Clean up the
3587 * transaction and return to idle state (we do not want to stay in
3588 * the transaction).
3589 */
3590 case TBLOCK_PREPARE:
3594 break;
3595
3596 /*
3597 * We got an error inside a subtransaction. Abort just the
3598 * subtransaction, and go to the persistent SUBABORT state until
3599 * we get ROLLBACK.
3600 */
3604 break;
3605
3606 /*
3607 * If we failed while trying to create a subtransaction, clean up
3608 * the broken subtransaction and abort the parent. The same
3609 * applies if we get a failure while ending a subtransaction. As
3610 * we need to abort the parent, return false to request the caller
3611 * to do the next iteration.
3612 */
3613 case TBLOCK_SUBBEGIN:
3614 case TBLOCK_SUBRELEASE:
3615 case TBLOCK_SUBCOMMIT:
3617 case TBLOCK_SUBRESTART:
3620 return false;
3621
3622 /*
3623 * Same as above, except the Abort() was already done.
3624 */
3628 return false;
3629 }
3630
3631 /* Done, no more iterations required */
3632 return true;
3633}
TransState state
Definition: xact.c:199
TBlockState blockState
Definition: xact.c:200
static void CleanupSubTransaction(void)
Definition: xact.c:5395
static void CleanupTransaction(void)
Definition: xact.c:3021
static void AbortSubTransaction(void)
Definition: xact.c:5231
static void AbortTransaction(void)
Definition: xact.c:2821
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 4874 of file xact.c.

4875{
4877
4878 /* Ensure we're not running in a doomed memory context */
4880
4881 /*
4882 * Get out of any transaction or nested transaction
4883 */
4884 do
4885 {
4886 switch (s->blockState)
4887 {
4888 case TBLOCK_DEFAULT:
4889 if (s->state == TRANS_DEFAULT)
4890 {
4891 /* Not in a transaction, do nothing */
4892 }
4893 else
4894 {
4895 /*
4896 * We can get here after an error during transaction start
4897 * (state will be TRANS_START). Need to clean up the
4898 * incompletely started transaction. First, adjust the
4899 * low-level state to suppress warning message from
4900 * AbortTransaction.
4901 */
4902 if (s->state == TRANS_START)
4906 }
4907 break;
4908 case TBLOCK_STARTED:
4909 case TBLOCK_BEGIN:
4910 case TBLOCK_INPROGRESS:
4913 case TBLOCK_END:
4915 case TBLOCK_PREPARE:
4916 /* In a transaction, so clean up */
4920 break;
4921 case TBLOCK_ABORT:
4922 case TBLOCK_ABORT_END:
4923
4924 /*
4925 * AbortTransaction is already done, still need Cleanup.
4926 * However, if we failed partway through running ROLLBACK,
4927 * there will be an active portal running that command, which
4928 * we need to shut down before doing CleanupTransaction.
4929 */
4933 break;
4934
4935 /*
4936 * In a subtransaction, so clean it up and abort parent too
4937 */
4938 case TBLOCK_SUBBEGIN:
4940 case TBLOCK_SUBRELEASE:
4941 case TBLOCK_SUBCOMMIT:
4943 case TBLOCK_SUBRESTART:
4946 s = CurrentTransactionState; /* changed by pop */
4947 break;
4948
4949 case TBLOCK_SUBABORT:
4952 /* As above, but AbortSubTransaction already done */
4953 if (s->curTransactionOwner)
4954 {
4955 /* As in TBLOCK_ABORT, might have a live portal to zap */
4960 }
4962 s = CurrentTransactionState; /* changed by pop */
4963 break;
4964 }
4965 } while (s->blockState != TBLOCK_DEFAULT);
4966
4967 /* Should be out of all subxacts now */
4968 Assert(s->parent == NULL);
4969
4970 /*
4971 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4972 * whether there were any transactions to close or not. (Callers that
4973 * don't intend to exit soon should switch to some other context to avoid
4974 * long-term memory leaks.)
4975 */
4977}
Assert(PointerIsAligned(start, uint64))
MemoryContext TopMemoryContext
Definition: mcxt.c:166
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
void AtAbort_Portals(void)
Definition: portalmem.c:781
void AtSubAbort_Portals(SubTransactionId mySubid, SubTransactionId parentSubid, ResourceOwner myXactOwner, ResourceOwner parentXactOwner)
Definition: portalmem.c:979
SubTransactionId subTransactionId
Definition: xact.c:196
struct TransactionStateData * parent
Definition: xact.c:218
ResourceOwner curTransactionOwner
Definition: xact.c:204
static void AtAbort_Memory(void)
Definition: xact.c:1896

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

5232{
5234
5235 /* Prevent cancel/die interrupt while cleaning up */
5237
5238 /* Make sure we have a valid memory context and resource owner */
5241
5242 /*
5243 * Release any LW locks we might be holding as quickly as possible.
5244 * (Regular locks, however, must be held till we finish aborting.)
5245 * Releasing LW locks is critical since we might try to grab them again
5246 * while cleaning up!
5247 *
5248 * FIXME This may be incorrect --- Are there some locks we should keep?
5249 * Buffer locks, for example? I don't think so but I'm not sure.
5250 */
5252
5255
5257
5258 UnlockBuffers();
5259
5260 /* Reset WAL record construction state */
5262
5263 /* Cancel condition variable sleep */
5265
5266 /*
5267 * Also clean up any open wait for lock, since the lock manager will choke
5268 * if we try to wait for another lock before doing this.
5269 */
5271
5272 /*
5273 * If any timeout events are still active, make sure the timeout interrupt
5274 * is scheduled. This covers possible loss of a timeout interrupt due to
5275 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5276 * We delay this till after LockErrorCleanup so that we don't uselessly
5277 * reschedule lock or deadlock check timeouts.
5278 */
5280
5281 /*
5282 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5283 * handler. We do this fairly early in the sequence so that the timeout
5284 * infrastructure will be functional if needed while aborting.
5285 */
5286 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5287
5288 /*
5289 * check the current transaction state
5290 */
5291 ShowTransactionState("AbortSubTransaction");
5292
5293 if (s->state != TRANS_INPROGRESS)
5294 elog(WARNING, "AbortSubTransaction while in %s state",
5296
5297 s->state = TRANS_ABORT;
5298
5299 /*
5300 * Reset user ID which might have been changed transiently. (See notes in
5301 * AbortTransaction.)
5302 */
5304
5305 /* Forget about any active REINDEX. */
5307
5308 /* Reset logical streaming state. */
5310
5311 /*
5312 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5313 * exports are not supported in subtransactions.
5314 */
5315
5316 /*
5317 * If this subxact has started any unfinished parallel operation, clean up
5318 * its workers and exit parallel mode. Don't warn about leaked resources.
5319 */
5321 s->parallelModeLevel = 0;
5322
5323 /*
5324 * We can skip all this stuff if the subxact failed before creating a
5325 * ResourceOwner...
5326 */
5327 if (s->curTransactionOwner)
5328 {
5337
5338 /* Advertise the fact that we aborted in pg_xact. */
5339 (void) RecordTransactionAbort(true);
5340
5341 /* Post-abort cleanup */
5344
5347
5350 false, false);
5351
5352 AtEOXact_Aio(false);
5356 AtEOSubXact_Inval(false);
5359 false, false);
5362 false, false);
5364
5365 AtEOXact_GUC(false, s->gucNestLevel);
5376 }
5377
5378 /*
5379 * Restore the upper transaction's read-only state, too. This should be
5380 * redundant with GUC's cleanup but we may as well do it for consistency
5381 * with the commit case.
5382 */
5384
5386}
void pgaio_error_cleanup(void)
Definition: aio.c:1162
void AtEOXact_Aio(bool is_commit)
Definition: aio.c:1190
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:5544
bool ConditionVariableCancelSleep(void)
void AtEOSubXact_HashTables(bool isCommit, int nestDepth)
Definition: dynahash.c:1957
#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:3193
void AtEOXact_GUC(bool isCommit, int nestLevel)
Definition: guc.c:2267
void ResetReindexState(int nestLevel)
Definition: index.c:4213
void AtEOSubXact_Inval(bool isCommit)
Definition: inval.c:1310
void ResetLogicalStreamingState(void)
Definition: logical.c:1942
void LWLockReleaseAll(void)
Definition: lwlock.c:1945
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:135
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:133
void SetUserIdAndSecContext(Oid userid, int sec_context)
Definition: miscinit.c:619
void AtEOSubXact_Namespace(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: namespace.c:4628
void AtEOSubXact_PgStat(bool isCommit, int nestDepth)
Definition: pgstat_xact.c:113
void AtEOSubXact_RelationCache(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: relcache.c:3378
void ResourceOwnerRelease(ResourceOwner owner, ResourceReleasePhase phase, bool isCommit, bool isTopLevel)
Definition: resowner.c:655
@ 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:980
void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
Definition: spi.c:482
void LockErrorCleanup(void)
Definition: proc.c:813
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:19425
void reschedule_timeouts(void)
Definition: timeout.c:540
#define FullTransactionIdIsValid(x)
Definition: transam.h:55
void AfterTriggerEndSubXact(bool isCommit)
Definition: trigger.c:5435
void AtEOSubXact_TypeCache(void)
Definition: typcache.c:3197
static void pgstat_report_wait_end(void)
Definition: wait_event.h:85
static void CallSubXactCallbacks(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: xact.c:3910
static void AtSubAbort_Memory(void)
Definition: xact.c:1916
static const char * TransStateAsString(TransState state)
Definition: xact.c:5772
bool XactReadOnly
Definition: xact.c:82
static void AtSubAbort_childXids(void)
Definition: xact.c:1954
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1941
static void ShowTransactionState(const char *str)
Definition: xact.c:5660
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1766
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:145
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 2821 of file xact.c.

2822{
2824 TransactionId latestXid;
2825 bool is_parallel_worker;
2826
2827 /* Prevent cancel/die interrupt while cleaning up */
2829
2830 /* Disable transaction timeout */
2831 if (TransactionTimeout > 0)
2833
2834 /* Make sure we have a valid memory context and resource owner */
2837
2838 /*
2839 * Release any LW locks we might be holding as quickly as possible.
2840 * (Regular locks, however, must be held till we finish aborting.)
2841 * Releasing LW locks is critical since we might try to grab them again
2842 * while cleaning up!
2843 */
2845
2846 /* Clear wait information and command progress indicator */
2849
2851
2852 /* Clean up buffer content locks, too */
2853 UnlockBuffers();
2854
2855 /* Reset WAL record construction state */
2857
2858 /* Cancel condition variable sleep */
2860
2861 /*
2862 * Also clean up any open wait for lock, since the lock manager will choke
2863 * if we try to wait for another lock before doing this.
2864 */
2866
2867 /*
2868 * If any timeout events are still active, make sure the timeout interrupt
2869 * is scheduled. This covers possible loss of a timeout interrupt due to
2870 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2871 * We delay this till after LockErrorCleanup so that we don't uselessly
2872 * reschedule lock or deadlock check timeouts.
2873 */
2875
2876 /*
2877 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2878 * handler. We do this fairly early in the sequence so that the timeout
2879 * infrastructure will be functional if needed while aborting.
2880 */
2881 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2882
2883 /*
2884 * check the current transaction state
2885 */
2886 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2887 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2888 elog(WARNING, "AbortTransaction while in %s state",
2890 Assert(s->parent == NULL);
2891
2892 /*
2893 * set the current transaction state information appropriately during the
2894 * abort processing
2895 */
2896 s->state = TRANS_ABORT;
2897
2898 /*
2899 * Reset user ID which might have been changed transiently. We need this
2900 * to clean up in case control escaped out of a SECURITY DEFINER function
2901 * or other local change of CurrentUserId; therefore, the prior value of
2902 * SecurityRestrictionContext also needs to be restored.
2903 *
2904 * (Note: it is not necessary to restore session authorization or role
2905 * settings here because those can only be changed via GUC, and GUC will
2906 * take care of rolling them back if need be.)
2907 */
2909
2910 /* Forget about any active REINDEX. */
2912
2913 /* Reset logical streaming state. */
2915
2916 /* Reset snapshot export state. */
2918
2919 /*
2920 * If this xact has started any unfinished parallel operation, clean up
2921 * its workers and exit parallel mode. Don't warn about leaked resources.
2922 */
2923 AtEOXact_Parallel(false);
2924 s->parallelModeLevel = 0;
2925 s->parallelChildXact = false; /* should be false already */
2926
2927 /*
2928 * do abort processing
2929 */
2930 AfterTriggerEndXact(false); /* 'false' means it's abort */
2932 smgrDoPendingSyncs(false, is_parallel_worker);
2933 AtEOXact_LargeObject(false);
2935 AtEOXact_RelationMap(false, is_parallel_worker);
2937
2938 /*
2939 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2940 * far as assigning an XID to advertise). But if we're inside a parallel
2941 * worker, skip this; the user backend must be the one to write the abort
2942 * record.
2943 */
2944 if (!is_parallel_worker)
2945 latestXid = RecordTransactionAbort(false);
2946 else
2947 {
2948 latestXid = InvalidTransactionId;
2949
2950 /*
2951 * Since the parallel leader won't get our value of XactLastRecEnd in
2952 * this case, we nudge WAL-writer ourselves in this case. See related
2953 * comments in RecordTransactionAbort for why this matters.
2954 */
2956 }
2957
2958 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2959
2960 /*
2961 * Let others know about no transaction in progress by me. Note that this
2962 * must be done _before_ releasing locks we hold and _after_
2963 * RecordTransactionAbort.
2964 */
2965 ProcArrayEndTransaction(MyProc, latestXid);
2966
2967 /*
2968 * Post-abort cleanup. See notes in CommitTransaction() concerning
2969 * ordering. We can skip all of it if the transaction failed before
2970 * creating a resource owner.
2971 */
2972 if (TopTransactionResourceOwner != NULL)
2973 {
2974 if (is_parallel_worker)
2976 else
2978
2981 false, true);
2982 AtEOXact_Aio(false);
2983 AtEOXact_Buffers(false);
2986 AtEOXact_Inval(false);
2990 false, true);
2993 false, true);
2994 smgrDoPendingDeletes(false);
2995
2996 AtEOXact_GUC(false, 1);
2997 AtEOXact_SPI(false);
2998 AtEOXact_Enum();
3000 AtEOXact_Namespace(false, is_parallel_worker);
3001 AtEOXact_SMgr();
3002 AtEOXact_Files(false);
3004 AtEOXact_HashTables(false);
3005 AtEOXact_PgStat(false, is_parallel_worker);
3009 }
3010
3011 /*
3012 * State remains TRANS_ABORT until CleanupTransaction().
3013 */
3015}
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:6228
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:3965
uint32 TransactionId
Definition: c.h:657
void AtEOXact_ComboCid(void)
Definition: combocid.c:182
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1931
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3226
void AtEOXact_Inval(bool isCommit)
Definition: inval.c:1199
void AtEOXact_ApplyLauncher(bool isCommit)
Definition: launcher.c:1112
void AtEOXact_MultiXact(void)
Definition: multixact.c:1799
void AtEOXact_Namespace(bool isCommit, bool parallel)
Definition: namespace.c:4582
void AtEOXact_Enum(void)
Definition: pg_enum.c:739
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:3226
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:428
PGPROC * MyProc
Definition: proc.c:66
int TransactionTimeout
Definition: proc.c:61
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:741
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:673
LocalTransactionId lxid
Definition: proc.h:217
struct PGPROC::@129 vxid
bool parallelChildXact
Definition: xact.c:215
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:19393
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:5339
void AtAbort_Twophase(void)
Definition: twophase.c:306
void AtEOXact_TypeCache(void)
Definition: typcache.c:3191
static void AtAbort_ResourceOwner(void)
Definition: xact.c:1928
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3850
@ XACT_EVENT_ABORT
Definition: xact.h:131
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:132
XLogRecPtr XactLastRecEnd
Definition: xlog.c:255
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2609

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:150
#define IsParallelWorker()
Definition: parallel.h:60
void XactLockTableInsert(TransactionId xid)
Definition: lmgr.c:622
void pfree(void *pointer)
Definition: mcxt.c:1594
void * palloc(Size size)
Definition: mcxt.c:1365
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:221
void SubTransSetParent(TransactionId xid, TransactionId parent)
Definition: subtrans.c:84
#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:226
#define XLOG_XACT_ASSIGNMENT
Definition: xact.h:175
#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 1896 of file xact.c.

1897{
1898 /*
1899 * Switch into TransactionAbortContext, which should have some free space
1900 * even if nothing else does. We'll work in this context until we've
1901 * finished cleaning up.
1902 *
1903 * It is barely possible to get here when we've not been able to create
1904 * TransactionAbortContext yet; if so use TopMemoryContext.
1905 */
1906 if (TransactionAbortContext != NULL)
1908 else
1910}
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 1928 of file xact.c.

1929{
1930 /*
1931 * Make sure we have a valid ResourceOwner, if possible (else it will be
1932 * NULL, which is OK)
1933 */
1935}

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1591 of file xact.c.

1592{
1593 /*
1594 * Make any pending relation map changes visible. We must do this before
1595 * processing local sinval messages, so that the map changes will get
1596 * reflected into the relcache when relcache invals are processed.
1597 */
1599
1600 /*
1601 * Make catalog changes visible to me for the next command.
1602 */
1604}
void CommandEndInvalidationMessages(void)
Definition: inval.c:1409
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 1986 of file xact.c.

1987{
1989
1990 /* Should be at top level */
1991 Assert(s->parent == NULL);
1992
1993 /*
1994 * Return to the memory context that was current before we started the
1995 * transaction. (In principle, this could not be any of the contexts we
1996 * are about to delete. If it somehow is, assertions in mcxt.c will
1997 * complain.)
1998 */
2000
2001 /*
2002 * Clear the special abort context for next time.
2003 */
2004 if (TransactionAbortContext != NULL)
2006
2007 /*
2008 * Release all transaction-local memory, the same as in AtCommit_Memory,
2009 * except we must cope with the possibility that we didn't get as far as
2010 * creating TopTransactionContext.
2011 */
2012 if (TopTransactionContext != NULL)
2014
2015 /*
2016 * Clear these pointers as a pro-forma matter. (Notionally, while
2017 * TopTransactionContext still exists, it's currently not associated with
2018 * this TransactionState struct.)
2019 */
2020 CurTransactionContext = NULL;
2021 s->curTransactionContext = NULL;
2022}
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:400
MemoryContext TopTransactionContext
Definition: mcxt.c:171
MemoryContext CurTransactionContext
Definition: mcxt.c:172
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 1610 of file xact.c.

1611{
1613
1614 /*
1615 * Return to the memory context that was current before we started the
1616 * transaction. (In principle, this could not be any of the contexts we
1617 * are about to delete. If it somehow is, assertions in mcxt.c will
1618 * complain.)
1619 */
1621
1622 /*
1623 * Release all transaction-local memory. TopTransactionContext survives
1624 * but becomes empty; any sub-contexts go away.
1625 */
1628
1629 /*
1630 * Clear these pointers as a pro-forma matter. (Notionally, while
1631 * TopTransactionContext still exists, it's currently not associated with
1632 * this TransactionState struct.)
1633 */
1634 CurTransactionContext = NULL;
1635 s->curTransactionContext = NULL;
1636}

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:930

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:160
#define AllocSetContextCreate
Definition: memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:160

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:418
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 1954 of file xact.c.

1955{
1957
1958 /*
1959 * We keep the child-XID arrays in TopTransactionContext (see
1960 * AtSubCommit_childXids). This means we'd better free the array
1961 * explicitly at abort to avoid leakage.
1962 */
1963 if (s->childXids != NULL)
1964 pfree(s->childXids);
1965 s->childXids = NULL;
1966 s->nChildXids = 0;
1967 s->maxChildXids = 0;
1968
1969 /*
1970 * We could prune the unreportedXids array here. But we don't bother. That
1971 * would potentially reduce number of XLOG_XACT_ASSIGNMENT records but it
1972 * would likely introduce more CPU time into the more common paths, so we
1973 * choose not to do that.
1974 */
1975}
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 1916 of file xact.c.

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1941 of file xact.c.

1942{
1944
1945 /* Make sure we have a valid ResourceOwner */
1947}

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 2034 of file xact.c.

2035{
2037
2038 Assert(s->parent != NULL);
2039
2040 /*
2041 * Return to the memory context that was current before we started the
2042 * subtransaction. (In principle, this could not be any of the contexts
2043 * we are about to delete. If it somehow is, assertions in mcxt.c will
2044 * complain.)
2045 */
2047
2048 /* Update CurTransactionContext (might not be same as priorContext) */
2050
2051 /*
2052 * Clear the special abort context for next time.
2053 */
2054 if (TransactionAbortContext != NULL)
2056
2057 /*
2058 * Delete the subxact local memory contexts. Its CurTransactionContext can
2059 * go too (note this also kills CurTransactionContexts from any children
2060 * of the subxact).
2061 */
2062 if (s->curTransactionContext)
2064 s->curTransactionContext = NULL;
2065}
void MemoryContextDelete(MemoryContext context)
Definition: mcxt.c:469

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

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

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

1648{
1650
1651 Assert(s->parent != NULL);
1652
1653 /* Return to parent transaction level's memory context. */
1656
1657 /*
1658 * Ordinarily we cannot throw away the child's CurTransactionContext,
1659 * since the data it contains will be needed at upper commit. However, if
1660 * there isn't actually anything in it, we can throw it away. This avoids
1661 * a small memory leak in the common case of "trivial" subxacts.
1662 */
1664 {
1666 s->curTransactionContext = NULL;
1667 }
1668}
bool MemoryContextIsEmpty(MemoryContext context)
Definition: mcxt.c:789

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

4339{
4341
4342 /*
4343 * If we are in STARTED state (that is, no transaction block is open),
4344 * switch to IMPLICIT_INPROGRESS state, creating an implicit transaction
4345 * block.
4346 *
4347 * For caller convenience, we consider all other transaction states as
4348 * legal here; otherwise the caller would need its own state check, which
4349 * seems rather pointless.
4350 */
4351 if (s->blockState == TBLOCK_STARTED)
4353}

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

4707{
4709 bool save_ExitOnAnyError = ExitOnAnyError;
4710
4711 /*
4712 * Errors within this function are improbable, but if one does happen we
4713 * force a FATAL exit. Callers generally aren't prepared to handle losing
4714 * control, and moreover our transaction state is probably corrupted if we
4715 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4716 */
4717 ExitOnAnyError = true;
4718
4719 /*
4720 * We do not check for parallel mode here. It's permissible to start and
4721 * end "internal" subtransactions while in parallel mode, so long as no
4722 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4723 * AssignTransactionId() and CommandCounterIncrement().
4724 */
4725
4726 switch (s->blockState)
4727 {
4728 case TBLOCK_STARTED:
4729 case TBLOCK_INPROGRESS:
4732 case TBLOCK_END:
4733 case TBLOCK_PREPARE:
4735 /* Normal subtransaction start */
4737 s = CurrentTransactionState; /* changed by push */
4738
4739 /*
4740 * Savepoint names, like the TransactionState block itself, live
4741 * in TopTransactionContext.
4742 */
4743 if (name)
4745 break;
4746
4747 /* These cases are invalid. */
4748 case TBLOCK_DEFAULT:
4749 case TBLOCK_BEGIN:
4750 case TBLOCK_SUBBEGIN:
4751 case TBLOCK_SUBRELEASE:
4752 case TBLOCK_SUBCOMMIT:
4753 case TBLOCK_ABORT:
4754 case TBLOCK_SUBABORT:
4755 case TBLOCK_ABORT_END:
4759 case TBLOCK_SUBRESTART:
4761 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4763 break;
4764 }
4765
4768
4769 ExitOnAnyError = save_ExitOnAnyError;
4770}
#define FATAL
Definition: elog.h:41
bool ExitOnAnyError
Definition: globals.c:123
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1746
const char * name
static void PushTransaction(void)
Definition: xact.c:5428
void StartTransactionCommand(void)
Definition: xact.c:3071
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5719
void CommitTransactionCommand(void)
Definition: xact.c:3169

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

3937{
3939
3940 switch (s->blockState)
3941 {
3942 /*
3943 * We are not inside a transaction block, so allow one to begin.
3944 */
3945 case TBLOCK_STARTED:
3947 break;
3948
3949 /*
3950 * BEGIN converts an implicit transaction block to a regular one.
3951 * (Note that we allow this even if we've already done some
3952 * commands, which is a bit odd but matches historical practice.)
3953 */
3956 break;
3957
3958 /*
3959 * Already a transaction block in progress.
3960 */
3961 case TBLOCK_INPROGRESS:
3964 case TBLOCK_ABORT:
3965 case TBLOCK_SUBABORT:
3967 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3968 errmsg("there is already a transaction in progress")));
3969 break;
3970
3971 /* These cases are invalid. */
3972 case TBLOCK_DEFAULT:
3973 case TBLOCK_BEGIN:
3974 case TBLOCK_SUBBEGIN:
3975 case TBLOCK_END:
3976 case TBLOCK_SUBRELEASE:
3977 case TBLOCK_SUBCOMMIT:
3978 case TBLOCK_ABORT_END:
3982 case TBLOCK_SUBRESTART:
3984 case TBLOCK_PREPARE:
3985 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3987 break;
3988 }
3989}

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

5720{
5721 switch (blockState)
5722 {
5723 case TBLOCK_DEFAULT:
5724 return "DEFAULT";
5725 case TBLOCK_STARTED:
5726 return "STARTED";
5727 case TBLOCK_BEGIN:
5728 return "BEGIN";
5729 case TBLOCK_INPROGRESS:
5730 return "INPROGRESS";
5732 return "IMPLICIT_INPROGRESS";
5734 return "PARALLEL_INPROGRESS";
5735 case TBLOCK_END:
5736 return "END";
5737 case TBLOCK_ABORT:
5738 return "ABORT";
5739 case TBLOCK_ABORT_END:
5740 return "ABORT_END";
5742 return "ABORT_PENDING";
5743 case TBLOCK_PREPARE:
5744 return "PREPARE";
5745 case TBLOCK_SUBBEGIN:
5746 return "SUBBEGIN";
5748 return "SUBINPROGRESS";
5749 case TBLOCK_SUBRELEASE:
5750 return "SUBRELEASE";
5751 case TBLOCK_SUBCOMMIT:
5752 return "SUBCOMMIT";
5753 case TBLOCK_SUBABORT:
5754 return "SUBABORT";
5756 return "SUBABORT_END";
5758 return "SUBABORT_PENDING";
5759 case TBLOCK_SUBRESTART:
5760 return "SUBRESTART";
5762 return "SUBABORT_RESTART";
5763 }
5764 return "UNRECOGNIZED";
5765}

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

3913{
3914 SubXactCallbackItem *item;
3916
3917 for (item = SubXact_callbacks; item; item = next)
3918 {
3919 /* allow callbacks to unregister themselves when called */
3920 next = item->next;
3921 item->callback(event, mySubid, parentSubid, item->arg);
3922 }
3923}
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 3850 of file xact.c.

3851{
3852 XactCallbackItem *item;
3854
3855 for (item = Xact_callbacks; item; item = next)
3856 {
3857 /* allow callbacks to unregister themselves when called */
3858 next = item->next;
3859 item->callback(event, item->arg);
3860 }
3861}
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 3737 of file xact.c.

3738{
3739 /*
3740 * xact block already started?
3741 */
3742 if (IsTransactionBlock())
3743 return;
3744
3745 /*
3746 * subtransaction?
3747 */
3748 if (IsSubTransaction())
3749 return;
3750
3751 /*
3752 * inside a function call?
3753 */
3754 if (!isTopLevel)
3755 return;
3756
3757 ereport(throwError ? ERROR : WARNING,
3758 (errcode(ERRCODE_NO_ACTIVE_SQL_TRANSACTION),
3759 /* translator: %s represents an SQL statement name */
3760 errmsg("%s can only be used in transaction blocks",
3761 stmtType)));
3762}
bool IsSubTransaction(void)
Definition: xact.c:5056
bool IsTransactionBlock(void)
Definition: xact.c:4983

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

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5395 of file xact.c.

5396{
5398
5399 ShowTransactionState("CleanupSubTransaction");
5400
5401 if (s->state != TRANS_ABORT)
5402 elog(WARNING, "CleanupSubTransaction while in %s state",
5404
5406
5409 if (s->curTransactionOwner)
5411 s->curTransactionOwner = NULL;
5412
5414
5415 s->state = TRANS_DEFAULT;
5416
5418}
void AtSubCleanup_Portals(SubTransactionId mySubid)
Definition: portalmem.c:1092
void ResourceOwnerDelete(ResourceOwner owner)
Definition: resowner.c:868
static void AtSubCleanup_Memory(void)
Definition: xact.c:2034
static void PopTransaction(void)
Definition: xact.c:5490

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

3022{
3024
3025 /*
3026 * State should still be TRANS_ABORT from AbortTransaction().
3027 */
3028 if (s->state != TRANS_ABORT)
3029 elog(FATAL, "CleanupTransaction: unexpected state %s",
3031
3032 /*
3033 * do abort cleanup processing
3034 */
3035 AtCleanup_Portals(); /* now safe to release portal memory */
3036 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3037
3038 CurrentResourceOwner = NULL; /* and resource owner */
3041 s->curTransactionOwner = NULL;
3044
3045 AtCleanup_Memory(); /* and transaction memory */
3046
3049 s->nestingLevel = 0;
3050 s->gucNestLevel = 0;
3051 s->childXids = NULL;
3052 s->nChildXids = 0;
3053 s->maxChildXids = 0;
3054 s->parallelModeLevel = 0;
3055 s->parallelChildXact = false;
3056
3059
3060 /*
3061 * done with abort processing, set current transaction state back to
3062 * default
3063 */
3064 s->state = TRANS_DEFAULT;
3065}
#define InvalidSubTransactionId
Definition: c.h:663
void AtCleanup_Portals(void)
Definition: portalmem.c:858
void AtEOXact_Snapshot(bool isCommit, bool resetXmin)
Definition: snapmgr.c:1014
#define InvalidFullTransactionId
Definition: transam.h:56
static void AtCleanup_Memory(void)
Definition: xact.c:1986
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:674
void SnapshotSetCommandId(CommandId curcid)
Definition: snapmgr.c:488
static bool currentCommandIdUsed
Definition: xact.c:268
static CommandId currentCommandId
Definition: xact.c:267
static void AtCCI_LocalCache(void)
Definition: xact.c:1591

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

5117{
5119
5120 ShowTransactionState("CommitSubTransaction");
5121
5122 if (s->state != TRANS_INPROGRESS)
5123 elog(WARNING, "CommitSubTransaction while in %s state",
5125
5126 /* Pre-commit processing goes here */
5127
5130
5131 /*
5132 * If this subxact has started any unfinished parallel operation, clean up
5133 * its workers and exit parallel mode. Warn about leaked resources.
5134 */
5136 if (s->parallelModeLevel != 0)
5137 {
5138 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5140 s->parallelModeLevel = 0;
5141 }
5142
5143 /* Do the actual "commit", such as it is */
5144 s->state = TRANS_COMMIT;
5145
5146 /* Must CCI to ensure commands of subtransaction are seen as done */
5148
5149 /*
5150 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5151 * perform that step, if required, as part of the atomic update of the
5152 * whole transaction tree at top level commit or abort.
5153 */
5154
5155 /* Post-commit cleanup */
5161 s->parent->nestingLevel,
5166
5169
5172 true, false);
5176 AtEOSubXact_Inval(true);
5178
5179 /*
5180 * The only lock we actually release here is the subtransaction XID lock.
5181 */
5185
5186 /*
5187 * Other locks should get transferred to their parent resource owner.
5188 */
5191 true, false);
5194 true, false);
5195
5196 AtEOXact_GUC(true, s->gucNestLevel);
5207
5208 /*
5209 * We need to restore the upper transaction's read-only state, in case the
5210 * upper is read-write while the child is read-only; GUC will incorrectly
5211 * think it should leave the child state in place.
5212 */
5214
5218 s->curTransactionOwner = NULL;
5219
5221
5222 s->state = TRANS_DEFAULT;
5223
5225}
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:943
void AtSubCommit_Snapshot(int level)
Definition: snapmgr.c:959
void AtSubCommit_smgr(void)
Definition: storage.c:955
static void AtSubCommit_Memory(void)
Definition: xact.c:1647
static void AtSubCommit_childXids(void)
Definition: xact.c:1676
void CommandCounterIncrement(void)
Definition: xact.c:1100
@ SUBXACT_EVENT_PRE_COMMIT_SUB
Definition: xact.h:146
@ SUBXACT_EVENT_COMMIT_SUB
Definition: xact.h:144

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

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

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

3170{
3171 /*
3172 * Repeatedly call CommitTransactionCommandInternal() until all the work
3173 * is done.
3174 */
3176 {
3177 }
3178}
static bool CommitTransactionCommandInternal(void)
Definition: xact.c:3187

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(), HasSubscriptionRelationsCached(), 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(), update_retention_status(), vacuum(), vacuum_rel(), validate_remote_info(), and worker_spi_main().

◆ CommitTransactionCommandInternal()

static bool CommitTransactionCommandInternal ( void  )
static

Definition at line 3187 of file xact.c.

3188{
3191
3192 /* Must save in case we need to restore below */
3194
3195 switch (s->blockState)
3196 {
3197 /*
3198 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3199 * StartTransactionCommand didn't set the STARTED state
3200 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3201 * by EndParallelWorkerTransaction(), not this function.
3202 */
3203 case TBLOCK_DEFAULT:
3205 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3207 break;
3208
3209 /*
3210 * If we aren't in a transaction block, just do our usual
3211 * transaction commit, and return to the idle state.
3212 */
3213 case TBLOCK_STARTED:
3216 break;
3217
3218 /*
3219 * We are completing a "BEGIN TRANSACTION" command, so we change
3220 * to the "transaction block in progress" state and return. (We
3221 * assume the BEGIN did nothing to the database, so we need no
3222 * CommandCounterIncrement.)
3223 */
3224 case TBLOCK_BEGIN:
3226 break;
3227
3228 /*
3229 * This is the case when we have finished executing a command
3230 * someplace within a transaction block. We increment the command
3231 * counter and return.
3232 */
3233 case TBLOCK_INPROGRESS:
3237 break;
3238
3239 /*
3240 * We are completing a "COMMIT" command. Do it and return to the
3241 * idle state.
3242 */
3243 case TBLOCK_END:
3246 if (s->chain)
3247 {
3250 s->chain = false;
3252 }
3253 break;
3254
3255 /*
3256 * Here we are in the middle of a transaction block but one of the
3257 * commands caused an abort so we do nothing but remain in the
3258 * abort state. Eventually we will get a ROLLBACK command.
3259 */
3260 case TBLOCK_ABORT:
3261 case TBLOCK_SUBABORT:
3262 break;
3263
3264 /*
3265 * Here we were in an aborted transaction block and we just got
3266 * the ROLLBACK command from the user, so clean up the
3267 * already-aborted transaction and return to the idle state.
3268 */
3269 case TBLOCK_ABORT_END:
3272 if (s->chain)
3273 {
3276 s->chain = false;
3278 }
3279 break;
3280
3281 /*
3282 * Here we were in a perfectly good transaction block but the user
3283 * told us to ROLLBACK anyway. We have to abort the transaction
3284 * and then clean up.
3285 */
3290 if (s->chain)
3291 {
3294 s->chain = false;
3296 }
3297 break;
3298
3299 /*
3300 * We are completing a "PREPARE TRANSACTION" command. Do it and
3301 * return to the idle state.
3302 */
3303 case TBLOCK_PREPARE:
3306 break;
3307
3308 /*
3309 * The user issued a SAVEPOINT inside a transaction block. Start a
3310 * subtransaction. (DefineSavepoint already did PushTransaction,
3311 * so as to have someplace to put the SUBBEGIN state.)
3312 */
3313 case TBLOCK_SUBBEGIN:
3316 break;
3317
3318 /*
3319 * The user issued a RELEASE command, so we end the current
3320 * subtransaction and return to the parent transaction. The parent
3321 * might be ended too, so repeat till we find an INPROGRESS
3322 * transaction or subtransaction.
3323 */
3324 case TBLOCK_SUBRELEASE:
3325 do
3326 {
3328 s = CurrentTransactionState; /* changed by pop */
3329 } while (s->blockState == TBLOCK_SUBRELEASE);
3330
3333 break;
3334
3335 /*
3336 * The user issued a COMMIT, so we end the current subtransaction
3337 * hierarchy and perform final commit. We do this by rolling up
3338 * any subtransactions into their parent, which leads to O(N^2)
3339 * operations with respect to resource owners - this isn't that
3340 * bad until we approach a thousands of savepoints but is
3341 * necessary for correctness should after triggers create new
3342 * resource owners.
3343 */
3344 case TBLOCK_SUBCOMMIT:
3345 do
3346 {
3348 s = CurrentTransactionState; /* changed by pop */
3349 } while (s->blockState == TBLOCK_SUBCOMMIT);
3350 /* If we had a COMMIT command, finish off the main xact too */
3351 if (s->blockState == TBLOCK_END)
3352 {
3353 Assert(s->parent == NULL);
3356 if (s->chain)
3357 {
3360 s->chain = false;
3362 }
3363 }
3364 else if (s->blockState == TBLOCK_PREPARE)
3365 {
3366 Assert(s->parent == NULL);
3369 }
3370 else
3371 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3373 break;
3374
3375 /*
3376 * The current already-failed subtransaction is ending due to a
3377 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3378 * examine the parent (which could be in any of several states).
3379 * As we need to examine the parent, return false to request the
3380 * caller to do the next iteration.
3381 */
3384 return false;
3385
3386 /*
3387 * As above, but it's not dead yet, so abort first.
3388 */
3392 return false;
3393
3394 /*
3395 * The current subtransaction is the target of a ROLLBACK TO
3396 * command. Abort and pop it, then start a new subtransaction
3397 * with the same name.
3398 */
3399 case TBLOCK_SUBRESTART:
3400 {
3401 char *name;
3402 int savepointLevel;
3403
3404 /* save name and keep Cleanup from freeing it */
3405 name = s->name;
3406 s->name = NULL;
3407 savepointLevel = s->savepointLevel;
3408
3411
3412 DefineSavepoint(NULL);
3413 s = CurrentTransactionState; /* changed by push */
3414 s->name = name;
3415 s->savepointLevel = savepointLevel;
3416
3417 /* This is the same as TBLOCK_SUBBEGIN case */
3421 }
3422 break;
3423
3424 /*
3425 * Same as above, but the subtransaction had already failed, so we
3426 * don't need AbortSubTransaction.
3427 */
3429 {
3430 char *name;
3431 int savepointLevel;
3432
3433 /* save name and keep Cleanup from freeing it */
3434 name = s->name;
3435 s->name = NULL;
3436 savepointLevel = s->savepointLevel;
3437
3439
3440 DefineSavepoint(NULL);
3441 s = CurrentTransactionState; /* changed by push */
3442 s->name = name;
3443 s->savepointLevel = savepointLevel;
3444
3445 /* This is the same as TBLOCK_SUBBEGIN case */
3449 }
3450 break;
3451 }
3452
3453 /* Done, no more iterations required */
3454 return true;
3455}
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3148
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3156
static void StartTransaction(void)
Definition: xact.c:2076
void DefineSavepoint(const char *name)
Definition: xact.c:4385
static void CommitSubTransaction(void)
Definition: xact.c:5116
static void CommitTransaction(void)
Definition: xact.c:2240
static void PrepareTransaction(void)
Definition: xact.c:2527
static void StartSubTransaction(void)
Definition: xact.c:5079

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

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

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

4364{
4366
4367 /*
4368 * If we are in IMPLICIT_INPROGRESS state, switch back to STARTED state,
4369 * allowing CommitTransactionCommand to commit whatever happened during
4370 * the implicit transaction block as though it were a single statement.
4371 *
4372 * For caller convenience, we consider all other transaction states as
4373 * legal here; otherwise the caller would need its own state check, which
4374 * seems rather pointless.
4375 */
4378}

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

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

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

5525{
5527 Size nxids = 0;
5529
5530 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5531 {
5533 nxids = add_size(nxids, 1);
5534 nxids = add_size(nxids, s->nChildXids);
5535 }
5536
5537 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5538}
size_t Size
Definition: c.h:610
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:223
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:659
#define InvalidLocalTransactionId
Definition: lock.h:67
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 3781 of file xact.c.

3782{
3783 /*
3784 * Return true on same conditions that would make
3785 * PreventInTransactionBlock error out
3786 */
3787 if (IsTransactionBlock())
3788 return true;
3789
3790 if (IsSubTransaction())
3791 return true;
3792
3793 if (!isTopLevel)
3794 return true;
3795
3798 return true;
3799
3800 return false;
3801}

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 AcceptInvalidationMessages(), 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(), ConditionalCatalogCacheInitializeCache(), CreateInitDecodingContext(), ensure_last_message(), FetchTableStates(), finish_sync_worker(), IsSubxactTopXidLogPending(), LogicalRepApplyLoop(), LogLogicalMessage(), maybe_reread_subscription(), pa_send_data(), pa_start_subtrans(), pg_do_encoding_conversion(), PrepareClientEncoding(), PrepareTempTablespaces(), process_syncing_tables_for_apply(), process_syncing_tables_for_sync(), RelationCacheInvalidate(), RelationFlushRelation(), RelationInitPhysicalAddr(), replorigin_create(), replorigin_drop_by_name(), SetMultiXactIdLimit(), SetTransactionIdLimit(), SnapBuildClearExportedSnapshot(), SocketBackend(), stream_stop_internal(), synchronize_slots(), update_retention_status(), 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 5490 of file xact.c.

5491{
5493
5494 if (s->state != TRANS_DEFAULT)
5495 elog(WARNING, "PopTransaction while in %s state",
5497
5498 if (s->parent == NULL)
5499 elog(FATAL, "PopTransaction with no parent");
5500
5502
5503 /* Let's just make sure CurTransactionContext is good */
5506
5507 /* Ditto for ResourceOwner links */
5510
5511 /* Free the old child structure */
5512 if (s->name)
5513 pfree(s->name);
5514 pfree(s);
5515}

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

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

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

4005{
4007 bool result;
4008
4009 /* Set up to commit the current transaction */
4010 result = EndTransactionBlock(false);
4011
4012 /* If successful, change outer tblock state to PREPARE */
4013 if (result)
4014 {
4016
4017 while (s->parent != NULL)
4018 s = s->parent;
4019
4020 if (s->blockState == TBLOCK_END)
4021 {
4022 /* Save GID where PrepareTransaction can find it again */
4024
4026 }
4027 else
4028 {
4029 /*
4030 * ignore case where we are not in a transaction;
4031 * EndTransactionBlock already issued a warning.
4032 */
4035 /* Don't send back a PREPARE result tag... */
4036 result = false;
4037 }
4038 }
4039
4040 return result;
4041}
bool EndTransactionBlock(bool chain)
Definition: xact.c:4056

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

3661{
3662 /*
3663 * xact block already started?
3664 */
3665 if (IsTransactionBlock())
3666 ereport(ERROR,
3667 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3668 /* translator: %s represents an SQL statement name */
3669 errmsg("%s cannot run inside a transaction block",
3670 stmtType)));
3671
3672 /*
3673 * subtransaction?
3674 */
3675 if (IsSubTransaction())
3676 ereport(ERROR,
3677 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3678 /* translator: %s represents an SQL statement name */
3679 errmsg("%s cannot run inside a subtransaction",
3680 stmtType)));
3681
3682 /*
3683 * inside a function call?
3684 */
3685 if (!isTopLevel)
3686 ereport(ERROR,
3687 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3688 /* translator: %s represents an SQL statement name */
3689 errmsg("%s cannot be executed from a function", stmtType)));
3690
3691 /* If we got past IsTransactionBlock test, should be in default state */
3694 elog(FATAL, "cannot prevent transaction chain");
3695
3696 /* All okay. Set the flag to make sure the right thing happens later. */
3698}
#define XACT_FLAGS_NEEDIMMEDIATECOMMIT
Definition: xact.h:115

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

5429{
5432
5433 /*
5434 * We keep subtransaction state nodes in TopTransactionContext.
5435 */
5436 s = (TransactionState)
5438 sizeof(TransactionStateData));
5439
5440 /*
5441 * Assign a subtransaction ID, watching out for counter wraparound.
5442 */
5445 {
5447 pfree(s);
5448 ereport(ERROR,
5449 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5450 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5451 }
5452
5453 /*
5454 * We can now stack a minimally valid subtransaction without fear of
5455 * failure.
5456 */
5457 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5459 s->parent = p;
5460 s->nestingLevel = p->nestingLevel + 1;
5463 s->state = TRANS_DEFAULT;
5468 s->parallelModeLevel = 0;
5470 s->topXidLogged = false;
5471
5473
5474 /*
5475 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5476 * with the subtransaction from here on out; in particular they should not
5477 * assume that it necessarily has a transaction context, resource owner,
5478 * or XID.
5479 */
5480}
int NewGUCNestLevel(void)
Definition: guc.c:2240
void * MemoryContextAllocZero(MemoryContext context, Size size)
Definition: mcxt.c:1263
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
Definition: miscinit.c:612
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 1766 of file xact.c.

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

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 *
1435 * Note, it is important to get the commit timestamp after marking the
1436 * transaction in the commit critical section. See
1437 * RecordTransactionCommitPrepared.
1438 */
1442
1444
1445 /*
1446 * Ensures the DELAY_CHKPT_IN_COMMIT flag write is globally visible
1447 * before commit time is written.
1448 */
1450
1451 /*
1452 * Insert the commit XLOG record.
1453 */
1455 nchildren, children, nrels, rels,
1456 ndroppedstats, droppedstats,
1457 nmsgs, invalMessages,
1458 RelcacheInitFileInval,
1460 InvalidTransactionId, NULL /* plain commit */ );
1461
1462 if (replorigin)
1463 /* Move LSNs forward for this replication origin */
1466
1467 /*
1468 * Record commit timestamp. The value comes from plain commit
1469 * timestamp if there's no replication origin; otherwise, the
1470 * timestamp was already set in replorigin_session_origin_timestamp by
1471 * replication.
1472 *
1473 * We don't need to WAL-log anything here, as the commit record
1474 * written above already contains the data.
1475 */
1476
1477 if (!replorigin || replorigin_session_origin_timestamp == 0)
1479
1480 TransactionTreeSetCommitTsData(xid, nchildren, children,
1483 }
1484
1485 /*
1486 * Check if we want to commit asynchronously. We can allow the XLOG flush
1487 * to happen asynchronously if synchronous_commit=off, or if the current
1488 * transaction has not performed any WAL-logged operation or didn't assign
1489 * an xid. The transaction can end up not writing any WAL, even if it has
1490 * an xid, if it only wrote to temporary and/or unlogged tables. It can
1491 * end up having written WAL without an xid if it did HOT pruning. In
1492 * case of a crash, the loss of such a transaction will be irrelevant;
1493 * temp tables will be lost anyway, unlogged tables will be truncated and
1494 * HOT pruning will be done again later. (Given the foregoing, you might
1495 * think that it would be unnecessary to emit the XLOG record at all in
1496 * this case, but we don't currently try to do that. It would certainly
1497 * cause problems at least in Hot Standby mode, where the
1498 * KnownAssignedXids machinery requires tracking every XID assignment. It
1499 * might be OK to skip it only when wal_level < replica, but for now we
1500 * don't.)
1501 *
1502 * However, if we're doing cleanup of any non-temp rels or committing any
1503 * command that wanted to force sync commit, then we must flush XLOG
1504 * immediately. (We must not allow asynchronous commit if there are any
1505 * non-temp tables to be deleted, because we might delete the files before
1506 * the COMMIT record is flushed to disk. We do allow asynchronous commit
1507 * if all to-be-deleted tables are temporary though, since they are lost
1508 * anyway if we crash.)
1509 */
1510 if ((wrote_xlog && markXidCommitted &&
1512 forceSyncCommit || nrels > 0)
1513 {
1515
1516 /*
1517 * Now we may update the CLOG, if we wrote a COMMIT record above
1518 */
1519 if (markXidCommitted)
1520 TransactionIdCommitTree(xid, nchildren, children);
1521 }
1522 else
1523 {
1524 /*
1525 * Asynchronous commit case:
1526 *
1527 * This enables possible committed transaction loss in the case of a
1528 * postmaster crash because WAL buffers are left unwritten. Ideally we
1529 * could issue the WAL write without the fsync, but some
1530 * wal_sync_methods do not allow separate write/fsync.
1531 *
1532 * Report the latest async commit LSN, so that the WAL writer knows to
1533 * flush this commit.
1534 */
1536
1537 /*
1538 * We must not immediately update the CLOG, since we didn't flush the
1539 * XLOG. Instead, we store the LSN up to which the XLOG must be
1540 * flushed before the CLOG may be updated.
1541 */
1542 if (markXidCommitted)
1543 TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
1544 }
1545
1546 /*
1547 * If we entered a commit critical section, leave it now, and let
1548 * checkpoints proceed.
1549 */
1550 if (markXidCommitted)
1551 {
1552 MyProc->delayChkptFlags &= ~DELAY_CHKPT_IN_COMMIT;
1554 }
1555
1556 /* Compute latestXid while we have the child XIDs handy */
1557 latestXid = TransactionIdLatest(xid, nchildren, children);
1558
1559 /*
1560 * Wait for synchronous replication, if required. Similar to the decision
1561 * above about using committing asynchronously we only want to wait if
1562 * this backend assigned an xid and wrote WAL. No need to wait if an xid
1563 * was assigned due to temporary/unlogged tables or due to HOT pruning.
1564 *
1565 * Note that at this stage we have marked clog, but still show as running
1566 * in the procarray and continue to hold locks.
1567 */
1568 if (wrote_xlog && markXidCommitted)
1570
1571 /* remember end of last commit record */
1573
1574 /* Reset XactLastRecEnd until the next transaction writes something */
1575 XactLastRecEnd = 0;
1576cleanup:
1577 /* Clean up local data */
1578 if (rels)
1579 pfree(rels);
1580 if (ndroppedstats)
1581 pfree(droppedstats);
1582
1583 return latestXid;
1584}
#define pg_write_barrier()
Definition: atomics.h:155
static void cleanup(void)
Definition: bootstrap.c:715
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid)
Definition: commit_ts.c:139
void LogLogicalInvalidations(void)
Definition: inval.c:1935
int xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs, bool *RelcacheInitFileInval)
Definition: inval.c:1012
TimestampTz replorigin_session_origin_timestamp
Definition: origin.c:165
#define DELAY_CHKPT_IN_COMMIT
Definition: proc.h:137
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition: standby.c:1470
int delayChkptFlags
Definition: proc.h:257
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:5826
@ SYNCHRONOUS_COMMIT_OFF
Definition: xact.h:71
XLogRecPtr XactLastCommitEnd
Definition: xlog.c:256
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2780

References Assert(), cleanup(), DELAY_CHKPT_IN_COMMIT, PGPROC::delayChkptFlags, DoNotReplicateId, elog, END_CRIT_SECTION, ERROR, forceSyncCommit, GetCurrentTransactionStopTimestamp(), GetTopTransactionIdIfAny(), InvalidRepOriginId, InvalidTransactionId, LogLogicalInvalidations(), LogStandbyInvalidations(), MyProc, MyXactFlags, pfree(), pg_write_barrier, 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(), xactStopTimestamp, XLogFlush(), XLogLogicalInfoActive, XLogSetAsyncXactLSN(), and XLogStandbyInfoActive.

Referenced by CommitTransaction().

◆ RegisterSubXactCallback()

void RegisterSubXactCallback ( SubXactCallback  callback,
void *  arg 
)

Definition at line 3876 of file xact.c.

3877{
3878 SubXactCallbackItem *item;
3879
3880 item = (SubXactCallbackItem *)
3882 item->callback = callback;
3883 item->arg = arg;
3884 item->next = SubXact_callbacks;
3885 SubXact_callbacks = item;
3886}
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 4780 of file xact.c.

4781{
4783
4784 /*
4785 * We do not check for parallel mode here. It's permissible to start and
4786 * end "internal" subtransactions while in parallel mode, so long as no
4787 * new XIDs or command IDs are assigned.
4788 */
4789
4791 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4796 s = CurrentTransactionState; /* changed by pop */
4798}

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

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

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

3729{
3730 CheckTransactionBlock(isTopLevel, true, stmtType);
3731}
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3737

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4808 of file xact.c.

4809{
4811
4812 /*
4813 * We do not check for parallel mode here. It's permissible to start and
4814 * end "internal" subtransactions while in parallel mode, so long as no
4815 * new XIDs or command IDs are assigned.
4816 */
4817
4818 switch (s->blockState)
4819 {
4820 /* Must be in a subtransaction */
4822 case TBLOCK_SUBABORT:
4823 break;
4824
4825 /* These cases are invalid. */
4826 case TBLOCK_DEFAULT:
4827 case TBLOCK_STARTED:
4828 case TBLOCK_BEGIN:
4831 case TBLOCK_SUBBEGIN:
4832 case TBLOCK_INPROGRESS:
4833 case TBLOCK_END:
4834 case TBLOCK_SUBRELEASE:
4835 case TBLOCK_SUBCOMMIT:
4836 case TBLOCK_ABORT:
4837 case TBLOCK_ABORT_END:
4841 case TBLOCK_SUBRESTART:
4843 case TBLOCK_PREPARE:
4844 elog(FATAL, "RollbackAndReleaseCurrentSubTransaction: unexpected state %s",
4846 break;
4847 }
4848
4849 /*
4850 * Abort the current subtransaction, if needed.
4851 */
4854
4855 /* And clean it up, too */
4857
4858 s = CurrentTransactionState; /* changed by pop */
4864}

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

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

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

5553{
5555 Size nxids = 0;
5556 Size i = 0;
5557 TransactionId *workspace;
5559
5560 result = (SerializedTransactionState *) start_address;
5561
5562 result->xactIsoLevel = XactIsoLevel;
5565 result->currentFullTransactionId =
5568
5569 /*
5570 * If we're running in a parallel worker and launching a parallel worker
5571 * of our own, we can just pass along the information that was passed to
5572 * us.
5573 */
5574 if (nParallelCurrentXids > 0)
5575 {
5577 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5579 return;
5580 }
5581
5582 /*
5583 * OK, we need to generate a sorted list of XIDs that our workers should
5584 * view as current. First, figure out how many there are.
5585 */
5586 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5587 {
5589 nxids = add_size(nxids, 1);
5590 nxids = add_size(nxids, s->nChildXids);
5591 }
5593 <= maxsize);
5594
5595 /* Copy them to our scratch space. */
5596 workspace = palloc(nxids * sizeof(TransactionId));
5597 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5598 {
5600 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5601 if (s->nChildXids > 0)
5602 memcpy(&workspace[i], s->childXids,
5603 s->nChildXids * sizeof(TransactionId));
5604 i += s->nChildXids;
5605 }
5606 Assert(i == nxids);
5607
5608 /* Sort them. */
5609 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5610
5611 /* Copy data into output area. */
5612 result->nParallelCurrentXids = nxids;
5613 memcpy(&result->parallelCurrentXids[0], workspace,
5614 nxids * sizeof(TransactionId));
5615}
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 5660 of file xact.c.

5661{
5662 /* skip work if message will definitely not be printed */
5665}
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:5672

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

5673{
5675
5676 if (s->parent)
5677 {
5678 /*
5679 * Since this function recurses, it could be driven to stack overflow.
5680 * This is just a debugging aid, so we can leave out some details
5681 * instead of erroring out with check_stack_depth().
5682 */
5683 if (stack_is_too_deep())
5685 (errmsg_internal("%s(%d): parent omitted to avoid stack overflow",
5686 str, s->nestingLevel)));
5687 else
5689 }
5690
5692 if (s->nChildXids > 0)
5693 {
5694 int i;
5695
5696 appendStringInfo(&buf, ", children: %u", s->childXids[0]);
5697 for (i = 1; i < s->nChildXids; i++)
5698 appendStringInfo(&buf, " %u", s->childXids[i]);
5699 }
5701 (errmsg_internal("%s(%d) name: %s; blockState: %s; state: %s, xid/subid/cid: %u/%u/%u%s%s",
5702 str, s->nestingLevel,
5703 s->name ? s->name : "unnamed",
5707 (unsigned int) s->subTransactionId,
5708 (unsigned int) currentCommandId,
5709 currentCommandIdUsed ? " (used)" : "",
5710 buf.data)));
5711 pfree(buf.data);
5712}
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1161
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(), 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 5079 of file xact.c.

5080{
5082
5083 if (s->state != TRANS_DEFAULT)
5084 elog(WARNING, "StartSubTransaction while in %s state",
5086
5087 s->state = TRANS_START;
5088
5089 /*
5090 * Initialize subsystems for new subtransaction
5091 *
5092 * must initialize resource-management stuff first
5093 */
5097
5099
5100 /*
5101 * Call start-of-subxact callbacks
5102 */
5105
5106 ShowTransactionState("StartSubTransaction");
5107}
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5387
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:143

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

2077{
2080
2081 /*
2082 * Let's just make sure the state stack is empty
2083 */
2086
2088
2089 /* check the current transaction state */
2090 Assert(s->state == TRANS_DEFAULT);
2091
2092 /*
2093 * Set the current transaction state information appropriately during
2094 * start processing. Note that once the transaction status is switched
2095 * this process cannot fail until the user ID and the security context
2096 * flags are fetched below.
2097 */
2098 s->state = TRANS_START;
2099 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2100
2101 /* Determine if statements are logged in this transaction */
2103 (log_xact_sample_rate == 1 ||
2105
2106 /*
2107 * initialize current transaction state fields
2108 *
2109 * note: prevXactReadOnly is not used at the outermost level
2110 */
2111 s->nestingLevel = 1;
2112 s->gucNestLevel = 1;
2113 s->childXids = NULL;
2114 s->nChildXids = 0;
2115 s->maxChildXids = 0;
2116
2117 /*
2118 * Once the current user ID and the security context flags are fetched,
2119 * both will be properly reset even if transaction startup fails.
2120 */
2122
2123 /* SecurityRestrictionContext should never be set outside a transaction */
2124 Assert(s->prevSecContext == 0);
2125
2126 /*
2127 * Make sure we've reset xact state variables
2128 *
2129 * If recovery is still in progress, mark this transaction as read-only.
2130 * We have lower level defences in XLogInsert and elsewhere to stop us
2131 * from modifying data during recovery, but this gives the normal
2132 * indication to the user that the transaction is read-only.
2133 */
2134 if (RecoveryInProgress())
2135 {
2136 s->startedInRecovery = true;
2137 XactReadOnly = true;
2138 }
2139 else
2140 {
2141 s->startedInRecovery = false;
2143 }
2146 forceSyncCommit = false;
2147 MyXactFlags = 0;
2148
2149 /*
2150 * reinitialize within-transaction counters
2151 */
2155 currentCommandIdUsed = false;
2156
2157 /*
2158 * initialize reported xid accounting
2159 */
2160 nUnreportedXids = 0;
2161 s->didLogXid = false;
2162
2163 /*
2164 * must initialize resource-management stuff first
2165 */
2168
2169 /*
2170 * Assign a new LocalTransactionId, and combine it with the proc number to
2171 * form a virtual transaction id.
2172 */
2173 vxid.procNumber = MyProcNumber;
2175
2176 /*
2177 * Lock the virtual transaction id before we announce it in the proc array
2178 */
2180
2181 /*
2182 * Advertise it in the proc array. We assume assignment of
2183 * localTransactionId is atomic, and the proc number should be set
2184 * already.
2185 */
2188
2189 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2190
2191 /*
2192 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2193 * be the same as the first command's statement_timestamp(), so don't do a
2194 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2195 * for transactions started inside procedures (i.e., nonatomic SPI
2196 * contexts), we do need to advance the timestamp. Also, in a parallel
2197 * worker, the timestamp should already have been provided by a call to
2198 * SetParallelStartTimestamps().
2199 */
2200 if (!IsParallelWorker())
2201 {
2204 else
2206 }
2207 else
2210 /* Mark xactStopTimestamp as unset. */
2212
2213 /*
2214 * initialize other subsystems for new transaction
2215 */
2216 AtStart_GUC();
2217 AtStart_Cache();
2219
2220 /*
2221 * done with start processing, set current transaction state to "in
2222 * progress"
2223 */
2225
2226 /* Schedule transaction timeout */
2227 if (TransactionTimeout > 0)
2229
2230 ShowTransactionState("StartTransaction");
2231}
#define TopSubTransactionId
Definition: c.h:664
#define FirstCommandId
Definition: c.h:673
ProcNumber MyProcNumber
Definition: globals.c:90
void AtStart_GUC(void)
Definition: guc.c:2220
double log_xact_sample_rate
Definition: guc_tables.c:548
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4622
double pg_prng_double(pg_prng_state *state)
Definition: pg_prng.c:268
pg_prng_state pg_global_prng_state
Definition: pg_prng.c:34
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:701
bool SPI_inside_nonatomic_context(void)
Definition: spi.c:581
ProcNumber procNumber
Definition: proc.h:212
LocalTransactionId localTransactionId
Definition: lock.h:64
ProcNumber procNumber
Definition: lock.h:63
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:560
void AfterTriggerBeginXact(void)
Definition: trigger.c:5072
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:6386

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

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

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

5016{
5018
5019 switch (s->blockState)
5020 {
5021 case TBLOCK_DEFAULT:
5022 case TBLOCK_STARTED:
5023 return 'I'; /* idle --- not in transaction */
5024 case TBLOCK_BEGIN:
5025 case TBLOCK_SUBBEGIN:
5026 case TBLOCK_INPROGRESS:
5030 case TBLOCK_END:
5031 case TBLOCK_SUBRELEASE:
5032 case TBLOCK_SUBCOMMIT:
5033 case TBLOCK_PREPARE:
5034 return 'T'; /* in transaction */
5035 case TBLOCK_ABORT:
5036 case TBLOCK_SUBABORT:
5037 case TBLOCK_ABORT_END:
5041 case TBLOCK_SUBRESTART:
5043 return 'E'; /* in failed transaction */
5044 }
5045
5046 /* should never get here */
5047 elog(FATAL, "invalid transaction block state: %s",
5049 return 0; /* keep compiler quiet */
5050}

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

5773{
5774 switch (state)
5775 {
5776 case TRANS_DEFAULT:
5777 return "DEFAULT";
5778 case TRANS_START:
5779 return "START";
5780 case TRANS_INPROGRESS:
5781 return "INPROGRESS";
5782 case TRANS_COMMIT:
5783 return "COMMIT";
5784 case TRANS_ABORT:
5785 return "ABORT";
5786 case TRANS_PREPARE:
5787 return "PREPARE";
5788 }
5789 return "UNRECOGNIZED";
5790}
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 3889 of file xact.c.

3890{
3891 SubXactCallbackItem *item;
3892 SubXactCallbackItem *prev;
3893
3894 prev = NULL;
3895 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3896 {
3897 if (item->callback == callback && item->arg == arg)
3898 {
3899 if (prev)
3900 prev->next = item->next;
3901 else
3902 SubXact_callbacks = item->next;
3903 pfree(item);
3904 break;
3905 }
3906 }
3907}

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

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3829 of file xact.c.

3830{
3831 XactCallbackItem *item;
3832 XactCallbackItem *prev;
3833
3834 prev = NULL;
3835 for (item = Xact_callbacks; item; prev = item, item = item->next)
3836 {
3837 if (item->callback == callback && item->arg == arg)
3838 {
3839 if (prev)
3840 prev->next = item->next;
3841 else
3842 Xact_callbacks = item->next;
3843 pfree(item);
3844 break;
3845 }
3846 }
3847}

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

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4216 of file xact.c.

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

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

3723{
3724 CheckTransactionBlock(isTopLevel, false, stmtType);
3725}

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6375 of file xact.c.

6376{
6377 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6378
6379 /* Backup blocks are not used in xact records */
6381
6382 if (info == XLOG_XACT_COMMIT)
6383 {
6384 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6385 xl_xact_parsed_commit parsed;
6386
6387 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6388 xact_redo_commit(&parsed, XLogRecGetXid(record),
6389 record->EndRecPtr, XLogRecGetOrigin(record));
6390 }
6391 else if (info == XLOG_XACT_COMMIT_PREPARED)
6392 {
6393 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6394 xl_xact_parsed_commit parsed;
6395
6396 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6397 xact_redo_commit(&parsed, parsed.twophase_xid,
6398 record->EndRecPtr, XLogRecGetOrigin(record));
6399
6400 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6401 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6402 PrepareRedoRemove(parsed.twophase_xid, false);
6403 LWLockRelease(TwoPhaseStateLock);
6404 }
6405 else if (info == XLOG_XACT_ABORT)
6406 {
6407 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6408 xl_xact_parsed_abort parsed;
6409
6410 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6411 xact_redo_abort(&parsed, XLogRecGetXid(record),
6412 record->EndRecPtr, XLogRecGetOrigin(record));
6413 }
6414 else if (info == XLOG_XACT_ABORT_PREPARED)
6415 {
6416 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6417 xl_xact_parsed_abort parsed;
6418
6419 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6420 xact_redo_abort(&parsed, parsed.twophase_xid,
6421 record->EndRecPtr, XLogRecGetOrigin(record));
6422
6423 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6424 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6425 PrepareRedoRemove(parsed.twophase_xid, false);
6426 LWLockRelease(TwoPhaseStateLock);
6427 }
6428 else if (info == XLOG_XACT_PREPARE)
6429 {
6430 /*
6431 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6432 * gxact entry.
6433 */
6434 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6436 XLogRecGetData(record),
6437 record->ReadRecPtr,
6438 record->EndRecPtr,
6439 XLogRecGetOrigin(record));
6440 LWLockRelease(TwoPhaseStateLock);
6441 }
6442 else if (info == XLOG_XACT_ASSIGNMENT)
6443 {
6445
6448 xlrec->nsubxacts, xlrec->xsub);
6449 }
6450 else if (info == XLOG_XACT_INVALIDATIONS)
6451 {
6452 /*
6453 * XXX we do ignore this for now, what matters are invalidations
6454 * written into the commit record.
6455 */
6456 }
6457 else
6458 elog(PANIC, "xact_redo: unknown op code %u", info);
6459}
uint8_t uint8
Definition: c.h:536
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
@ LW_EXCLUSIVE
Definition: lwlock.h:112
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:223
TransactionId twophase_xid
Definition: xact.h:428
TransactionId twophase_xid
Definition: xact.h:398
void PrepareRedoRemove(TransactionId xid, bool giveWarning)
Definition: twophase.c:2664
void PrepareRedoAdd(FullTransactionId fxid, char *buf, XLogRecPtr start_lsn, XLogRecPtr end_lsn, RepOriginId origin_id)
Definition: twophase.c:2507
static void xact_redo_commit(xl_xact_parsed_commit *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6142
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6296
#define XLOG_XACT_COMMIT_PREPARED
Definition: xact.h:173
#define XLOG_XACT_INVALIDATIONS
Definition: xact.h:176
#define XLOG_XACT_PREPARE
Definition: xact.h:171
#define XLOG_XACT_COMMIT
Definition: xact.h:170
#define XLOG_XACT_OPMASK
Definition: xact.h:180
#define XLOG_XACT_ABORT
Definition: xact.h:172
#define XLOG_XACT_ABORT_PREPARED
Definition: xact.h:174
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, InvalidFullTransactionId, 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 6296 of file xact.c.

6298{
6299 TransactionId max_xid;
6300
6302
6303 /* Make sure nextXid is beyond any XID mentioned in the record. */
6304 max_xid = TransactionIdLatest(xid,
6305 parsed->nsubxacts,
6306 parsed->subxacts);
6308
6310 {
6311 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6312 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6313 }
6314 else
6315 {
6316 /*
6317 * If a transaction completion record arrives that has as-yet
6318 * unobserved subtransactions then this will not have been fully
6319 * handled by the call to RecordKnownAssignedTransactionIds() in the
6320 * main recovery loop in xlog.c. So we need to do bookkeeping again to
6321 * cover that case. This is confusing and it is easy to think this
6322 * call is irrelevant, which has happened three times in development
6323 * already. Leave it in.
6324 */
6326
6327 /* Mark the transaction aborted in pg_xact, no need for async stuff */
6328 TransactionIdAbortTree(xid, parsed->nsubxacts, parsed->subxacts);
6329
6330 /*
6331 * We must update the ProcArray after we have marked clog.
6332 */
6333 ExpireTreeKnownAssignedTransactionIds(xid, parsed->nsubxacts, parsed->subxacts, max_xid);
6334
6335 /*
6336 * There are no invalidation messages to send or undo.
6337 */
6338
6339 /*
6340 * Release locks, if any. There are no invalidations to send.
6341 */
6342 if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS)
6343 StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts);
6344 }
6345
6346 if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN)
6347 {
6348 /* recover apply progress */
6349 replorigin_advance(origin_id, parsed->origin_lsn, lsn,
6350 false /* backward */ , false /* WAL */ );
6351 }
6352
6353 /* Make sure files supposed to be dropped are dropped */
6354 if (parsed->nrels > 0)
6355 {
6356 /*
6357 * See comments about update of minimum recovery point on truncation,
6358 * in xact_redo_commit().
6359 */
6360 XLogFlush(lsn);
6361
6362 DropRelationFiles(parsed->xlocators, parsed->nrels, true);
6363 }
6364
6365 if (parsed->nstats > 0)
6366 {
6367 /* see equivalent call for relations above */
6368 XLogFlush(lsn);
6369
6370 pgstat_execute_transactional_drops(parsed->nstats, parsed->stats, true);
6371 }
6372}
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:911
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:4365
void ExpireTreeKnownAssignedTransactionIds(TransactionId xid, int nsubxids, TransactionId *subxids, TransactionId max_xid)
Definition: procarray.c:4434
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition: standby.c:1092
xl_xact_stats_item * stats
Definition: xact.h:426
RelFileLocator * xlocators
Definition: xact.h:423
TransactionId * subxacts
Definition: xact.h:420
XLogRecPtr origin_lsn
Definition: xact.h:431
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
Definition: varsup.c:304
#define XACT_XINFO_HAS_ORIGIN
Definition: xact.h:194
#define XACT_XINFO_HAS_AE_LOCKS
Definition: xact.h:195
@ 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 6142 of file xact.c.

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

5803{
5805
5806 if (s->nChildXids == 0)
5807 *ptr = NULL;
5808 else
5809 *ptr = s->childXids;
5810
5811 return s->nChildXids;
5812}

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

6004{
6005 xl_xact_abort xlrec;
6006 xl_xact_xinfo xl_xinfo;
6007 xl_xact_subxacts xl_subxacts;
6008 xl_xact_relfilelocators xl_relfilelocators;
6009 xl_xact_stats_items xl_dropped_stats;
6010 xl_xact_twophase xl_twophase;
6011 xl_xact_dbinfo xl_dbinfo;
6012 xl_xact_origin xl_origin;
6013
6014 uint8 info;
6015
6017
6018 xl_xinfo.xinfo = 0;
6019
6020 /* decide between a plain and 2pc abort */
6021 if (!TransactionIdIsValid(twophase_xid))
6022 info = XLOG_XACT_ABORT;
6023 else
6025
6026
6027 /* First figure out and collect all the information needed */
6028
6029 xlrec.xact_time = abort_time;
6030
6032 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
6033
6034 if (nsubxacts > 0)
6035 {
6036 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
6037 xl_subxacts.nsubxacts = nsubxacts;
6038 }
6039
6040 if (nrels > 0)
6041 {
6043 xl_relfilelocators.nrels = nrels;
6044 info |= XLR_SPECIAL_REL_UPDATE;
6045 }
6046
6047 if (ndroppedstats > 0)
6048 {
6050 xl_dropped_stats.nitems = ndroppedstats;
6051 }
6052
6053 if (TransactionIdIsValid(twophase_xid))
6054 {
6055 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
6056 xl_twophase.xid = twophase_xid;
6057 Assert(twophase_gid != NULL);
6058
6060 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6061 }
6062
6063 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6064 {
6065 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6066 xl_dbinfo.dbId = MyDatabaseId;
6067 xl_dbinfo.tsId = MyDatabaseTableSpace;
6068 }
6069
6070 /*
6071 * Dump transaction origin information. We need this during recovery to
6072 * update the replication origin progress.
6073 */
6075 {
6076 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6077
6080 }
6081
6082 if (xl_xinfo.xinfo != 0)
6083 info |= XLOG_XACT_HAS_INFO;
6084
6085 /* Then include all the collected data into the abort record. */
6086
6088
6090
6091 if (xl_xinfo.xinfo != 0)
6092 XLogRegisterData(&xl_xinfo, sizeof(xl_xinfo));
6093
6094 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6095 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
6096
6097 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6098 {
6099 XLogRegisterData(&xl_subxacts,
6101 XLogRegisterData(subxacts,
6102 nsubxacts * sizeof(TransactionId));
6103 }
6104
6106 {
6107 XLogRegisterData(&xl_relfilelocators,
6109 XLogRegisterData(rels,
6110 nrels * sizeof(RelFileLocator));
6111 }
6112
6113 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6114 {
6115 XLogRegisterData(&xl_dropped_stats,
6117 XLogRegisterData(droppedstats,
6118 ndroppedstats * sizeof(xl_xact_stats_item));
6119 }
6120
6121 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6122 {
6123 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
6124 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6125 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6126 }
6127
6128 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6129 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
6130
6131 /* Include the replication origin */
6133
6134 return XLogInsert(RM_XACT_ID, info);
6135}
Oid MyDatabaseTableSpace
Definition: globals.c:96
volatile uint32 CritSectionCount
Definition: globals.c:45
TimestampTz xact_time
Definition: xact.h:339
Oid tsId
Definition: xact.h:259
Oid dbId
Definition: xact.h:258
TimestampTz origin_timestamp
Definition: xact.h:318
XLogRecPtr origin_lsn
Definition: xact.h:317
int nsubxacts
Definition: xact.h:264
TransactionId xid
Definition: xact.h:312
uint32 xinfo
Definition: xact.h:253
#define MinSizeOfXactSubxacts
Definition: xact.h:267
#define XACT_XINFO_HAS_GID
Definition: xact.h:196
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:109
#define XACT_XINFO_HAS_TWOPHASE
Definition: xact.h:193
#define MinSizeOfXactRelfileLocators
Definition: xact.h:274
#define MinSizeOfXactStatsItems
Definition: xact.h:301
#define XACT_XINFO_HAS_RELFILELOCATORS
Definition: xact.h:191
#define MinSizeOfXactAbort
Definition: xact.h:351
#define XACT_XINFO_HAS_DBINFO
Definition: xact.h:189
#define XLOG_XACT_HAS_INFO
Definition: xact.h:183
#define XACT_XINFO_HAS_SUBXACTS
Definition: xact.h:190
#define XACT_XINFO_HAS_DROPPED_STATS
Definition: xact.h:197
#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 5826 of file xact.c.

5834{
5835 xl_xact_commit xlrec;
5836 xl_xact_xinfo xl_xinfo;
5837 xl_xact_dbinfo xl_dbinfo;
5838 xl_xact_subxacts xl_subxacts;
5839 xl_xact_relfilelocators xl_relfilelocators;
5840 xl_xact_stats_items xl_dropped_stats;
5841 xl_xact_invals xl_invals;
5842 xl_xact_twophase xl_twophase;
5843 xl_xact_origin xl_origin;
5844 uint8 info;
5845
5847
5848 xl_xinfo.xinfo = 0;
5849
5850 /* decide between a plain and 2pc commit */
5851 if (!TransactionIdIsValid(twophase_xid))
5852 info = XLOG_XACT_COMMIT;
5853 else
5855
5856 /* First figure out and collect all the information needed */
5857
5858 xlrec.xact_time = commit_time;
5859
5860 if (relcacheInval)
5862 if (forceSyncCommit)
5865 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5866
5867 /*
5868 * Check if the caller would like to ask standbys for immediate feedback
5869 * once this commit is applied.
5870 */
5873
5874 /*
5875 * Relcache invalidations requires information about the current database
5876 * and so does logical decoding.
5877 */
5878 if (nmsgs > 0 || XLogLogicalInfoActive())
5879 {
5880 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5881 xl_dbinfo.dbId = MyDatabaseId;
5882 xl_dbinfo.tsId = MyDatabaseTableSpace;
5883 }
5884
5885 if (nsubxacts > 0)
5886 {
5887 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5888 xl_subxacts.nsubxacts = nsubxacts;
5889 }
5890
5891 if (nrels > 0)
5892 {
5894 xl_relfilelocators.nrels = nrels;
5895 info |= XLR_SPECIAL_REL_UPDATE;
5896 }
5897
5898 if (ndroppedstats > 0)
5899 {
5901 xl_dropped_stats.nitems = ndroppedstats;
5902 }
5903
5904 if (nmsgs > 0)
5905 {
5906 xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5907 xl_invals.nmsgs = nmsgs;
5908 }
5909
5910 if (TransactionIdIsValid(twophase_xid))
5911 {
5912 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5913 xl_twophase.xid = twophase_xid;
5914 Assert(twophase_gid != NULL);
5915
5917 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5918 }
5919
5920 /* dump transaction origin information */
5922 {
5923 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5924
5927 }
5928
5929 if (xl_xinfo.xinfo != 0)
5930 info |= XLOG_XACT_HAS_INFO;
5931
5932 /* Then include all the collected data into the commit record. */
5933
5935
5936 XLogRegisterData(&xlrec, sizeof(xl_xact_commit));
5937
5938 if (xl_xinfo.xinfo != 0)
5939 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5940
5941 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5942 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
5943
5944 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5945 {
5946 XLogRegisterData(&xl_subxacts,
5948 XLogRegisterData(subxacts,
5949 nsubxacts * sizeof(TransactionId));
5950 }
5951
5953 {
5954 XLogRegisterData(&xl_relfilelocators,
5956 XLogRegisterData(rels,
5957 nrels * sizeof(RelFileLocator));
5958 }
5959
5960 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5961 {
5962 XLogRegisterData(&xl_dropped_stats,
5964 XLogRegisterData(droppedstats,
5965 ndroppedstats * sizeof(xl_xact_stats_item));
5966 }
5967
5968 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5969 {
5971 XLogRegisterData(msgs,
5972 nmsgs * sizeof(SharedInvalidationMessage));
5973 }
5974
5975 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5976 {
5977 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
5978 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5979 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5980 }
5981
5982 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5983 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
5984
5985 /* we allow filtering by xacts */
5987
5988 return XLogInsert(RM_XACT_ID, info);
5989}
TimestampTz xact_time
Definition: xact.h:323
int nmsgs
Definition: xact.h:305
#define MinSizeOfXactInvals
Definition: xact.h:308
#define XACT_COMPLETION_UPDATE_RELCACHE_FILE
Definition: xact.h:208
#define XACT_COMPLETION_FORCE_SYNC_COMMIT
Definition: xact.h:209
@ SYNCHRONOUS_COMMIT_REMOTE_APPLY
Definition: xact.h:76
#define XACT_COMPLETION_APPLY_FEEDBACK
Definition: xact.h:207
#define XACT_XINFO_HAS_INVALS
Definition: xact.h:192

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

◆ XactTopFullTransactionId