PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
xact.c File Reference
#include "postgres.h"
#include <time.h>
#include <unistd.h>
#include "access/commit_ts.h"
#include "access/multixact.h"
#include "access/parallel.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "access/twophase.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/xlogrecovery.h"
#include "access/xlogutils.h"
#include "access/xlogwait.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 240 of file xact.c.

Typedef Documentation

◆ SerializedTransactionState

◆ SubXactCallbackItem

◆ TBlockState

typedef enum TBlockState TBlockState

◆ TransactionState

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

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

◆ TransState

enum TransState
Enumerator
TRANS_DEFAULT 
TRANS_START 
TRANS_INPROGRESS 
TRANS_COMMIT 
TRANS_ABORT 
TRANS_PREPARE 

Definition at line 142 of file xact.c.

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

Function Documentation

◆ AbortCurrentTransaction()

void AbortCurrentTransaction ( void  )

Definition at line 3469 of file xact.c.

3470{
3471 /*
3472 * Repeatedly call AbortCurrentTransactionInternal() until all the work is
3473 * done.
3474 */
3476 {
3477 }
3478}
static bool AbortCurrentTransactionInternal(void)
Definition: xact.c:3487

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

3488{
3490
3491 switch (s->blockState)
3492 {
3493 case TBLOCK_DEFAULT:
3494 if (s->state == TRANS_DEFAULT)
3495 {
3496 /* we are idle, so nothing to do */
3497 }
3498 else
3499 {
3500 /*
3501 * We can get here after an error during transaction start
3502 * (state will be TRANS_START). Need to clean up the
3503 * incompletely started transaction. First, adjust the
3504 * low-level state to suppress warning message from
3505 * AbortTransaction.
3506 */
3507 if (s->state == TRANS_START)
3511 }
3512 break;
3513
3514 /*
3515 * If we aren't in a transaction block, we just do the basic abort
3516 * & cleanup transaction. For this purpose, we treat an implicit
3517 * transaction block as if it were a simple statement.
3518 */
3519 case TBLOCK_STARTED:
3524 break;
3525
3526 /*
3527 * If we are in TBLOCK_BEGIN it means something screwed up right
3528 * after reading "BEGIN TRANSACTION". We assume that the user
3529 * will interpret the error as meaning the BEGIN failed to get him
3530 * into a transaction block, so we should abort and return to idle
3531 * state.
3532 */
3533 case TBLOCK_BEGIN:
3537 break;
3538
3539 /*
3540 * We are somewhere in a transaction block and we've gotten a
3541 * failure, so we abort the transaction and set up the persistent
3542 * ABORT state. We will stay in ABORT until we get a ROLLBACK.
3543 */
3544 case TBLOCK_INPROGRESS:
3548 /* CleanupTransaction happens when we exit TBLOCK_ABORT_END */
3549 break;
3550
3551 /*
3552 * Here, we failed while trying to COMMIT. Clean up the
3553 * transaction and return to idle state (we do not want to stay in
3554 * the transaction).
3555 */
3556 case TBLOCK_END:
3560 break;
3561
3562 /*
3563 * Here, we are already in an aborted transaction state and are
3564 * waiting for a ROLLBACK, but for some reason we failed again! So
3565 * we just remain in the abort state.
3566 */
3567 case TBLOCK_ABORT:
3568 case TBLOCK_SUBABORT:
3569 break;
3570
3571 /*
3572 * We are in a failed transaction and we got the ROLLBACK command.
3573 * We have already aborted, we just need to cleanup and go to idle
3574 * state.
3575 */
3576 case TBLOCK_ABORT_END:
3579 break;
3580
3581 /*
3582 * We are in a live transaction and we got a ROLLBACK command.
3583 * Abort, cleanup, go to idle state.
3584 */
3589 break;
3590
3591 /*
3592 * Here, we failed while trying to PREPARE. Clean up the
3593 * transaction and return to idle state (we do not want to stay in
3594 * the transaction).
3595 */
3596 case TBLOCK_PREPARE:
3600 break;
3601
3602 /*
3603 * We got an error inside a subtransaction. Abort just the
3604 * subtransaction, and go to the persistent SUBABORT state until
3605 * we get ROLLBACK.
3606 */
3610 break;
3611
3612 /*
3613 * If we failed while trying to create a subtransaction, clean up
3614 * the broken subtransaction and abort the parent. The same
3615 * applies if we get a failure while ending a subtransaction. As
3616 * we need to abort the parent, return false to request the caller
3617 * to do the next iteration.
3618 */
3619 case TBLOCK_SUBBEGIN:
3620 case TBLOCK_SUBRELEASE:
3621 case TBLOCK_SUBCOMMIT:
3623 case TBLOCK_SUBRESTART:
3626 return false;
3627
3628 /*
3629 * Same as above, except the Abort() was already done.
3630 */
3634 return false;
3635 }
3636
3637 /* Done, no more iterations required */
3638 return true;
3639}
TransState state
Definition: xact.c:200
TBlockState blockState
Definition: xact.c:201
static void CleanupSubTransaction(void)
Definition: xact.c:5401
static void CleanupTransaction(void)
Definition: xact.c:3027
static void AbortSubTransaction(void)
Definition: xact.c:5237
static void AbortTransaction(void)
Definition: xact.c:2822
static TransactionState CurrentTransactionState
Definition: xact.c:261

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

4881{
4883
4884 /* Ensure we're not running in a doomed memory context */
4886
4887 /*
4888 * Get out of any transaction or nested transaction
4889 */
4890 do
4891 {
4892 switch (s->blockState)
4893 {
4894 case TBLOCK_DEFAULT:
4895 if (s->state == TRANS_DEFAULT)
4896 {
4897 /* Not in a transaction, do nothing */
4898 }
4899 else
4900 {
4901 /*
4902 * We can get here after an error during transaction start
4903 * (state will be TRANS_START). Need to clean up the
4904 * incompletely started transaction. First, adjust the
4905 * low-level state to suppress warning message from
4906 * AbortTransaction.
4907 */
4908 if (s->state == TRANS_START)
4912 }
4913 break;
4914 case TBLOCK_STARTED:
4915 case TBLOCK_BEGIN:
4916 case TBLOCK_INPROGRESS:
4919 case TBLOCK_END:
4921 case TBLOCK_PREPARE:
4922 /* In a transaction, so clean up */
4926 break;
4927 case TBLOCK_ABORT:
4928 case TBLOCK_ABORT_END:
4929
4930 /*
4931 * AbortTransaction is already done, still need Cleanup.
4932 * However, if we failed partway through running ROLLBACK,
4933 * there will be an active portal running that command, which
4934 * we need to shut down before doing CleanupTransaction.
4935 */
4939 break;
4940
4941 /*
4942 * In a subtransaction, so clean it up and abort parent too
4943 */
4944 case TBLOCK_SUBBEGIN:
4946 case TBLOCK_SUBRELEASE:
4947 case TBLOCK_SUBCOMMIT:
4949 case TBLOCK_SUBRESTART:
4952 s = CurrentTransactionState; /* changed by pop */
4953 break;
4954
4955 case TBLOCK_SUBABORT:
4958 /* As above, but AbortSubTransaction already done */
4959 if (s->curTransactionOwner)
4960 {
4961 /* As in TBLOCK_ABORT, might have a live portal to zap */
4966 }
4968 s = CurrentTransactionState; /* changed by pop */
4969 break;
4970 }
4971 } while (s->blockState != TBLOCK_DEFAULT);
4972
4973 /* Should be out of all subxacts now */
4974 Assert(s->parent == NULL);
4975
4976 /*
4977 * Revert to TopMemoryContext, to ensure we exit in a well-defined state
4978 * whether there were any transactions to close or not. (Callers that
4979 * don't intend to exit soon should switch to some other context to avoid
4980 * long-term memory leaks.)
4981 */
4983}
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:197
struct TransactionStateData * parent
Definition: xact.c:219
ResourceOwner curTransactionOwner
Definition: xact.c:205
static void AtAbort_Memory(void)
Definition: xact.c:1897

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

◆ AbortSubTransaction()

static void AbortSubTransaction ( void  )
static

Definition at line 5237 of file xact.c.

5238{
5240
5241 /* Prevent cancel/die interrupt while cleaning up */
5243
5244 /* Make sure we have a valid memory context and resource owner */
5247
5248 /*
5249 * Release any LW locks we might be holding as quickly as possible.
5250 * (Regular locks, however, must be held till we finish aborting.)
5251 * Releasing LW locks is critical since we might try to grab them again
5252 * while cleaning up!
5253 *
5254 * FIXME This may be incorrect --- Are there some locks we should keep?
5255 * Buffer locks, for example? I don't think so but I'm not sure.
5256 */
5258
5261
5263
5264 UnlockBuffers();
5265
5266 /* Reset WAL record construction state */
5268
5269 /* Cancel condition variable sleep */
5271
5272 /*
5273 * Also clean up any open wait for lock, since the lock manager will choke
5274 * if we try to wait for another lock before doing this.
5275 */
5277
5278 /*
5279 * If any timeout events are still active, make sure the timeout interrupt
5280 * is scheduled. This covers possible loss of a timeout interrupt due to
5281 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
5282 * We delay this till after LockErrorCleanup so that we don't uselessly
5283 * reschedule lock or deadlock check timeouts.
5284 */
5286
5287 /*
5288 * Re-enable signals, in case we got here by longjmp'ing out of a signal
5289 * handler. We do this fairly early in the sequence so that the timeout
5290 * infrastructure will be functional if needed while aborting.
5291 */
5292 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
5293
5294 /*
5295 * check the current transaction state
5296 */
5297 ShowTransactionState("AbortSubTransaction");
5298
5299 if (s->state != TRANS_INPROGRESS)
5300 elog(WARNING, "AbortSubTransaction while in %s state",
5302
5303 s->state = TRANS_ABORT;
5304
5305 /*
5306 * Reset user ID which might have been changed transiently. (See notes in
5307 * AbortTransaction.)
5308 */
5310
5311 /* Forget about any active REINDEX. */
5313
5314 /* Reset logical streaming state. */
5316
5317 /*
5318 * No need for SnapBuildResetExportedSnapshotState() here, snapshot
5319 * exports are not supported in subtransactions.
5320 */
5321
5322 /*
5323 * If this subxact has started any unfinished parallel operation, clean up
5324 * its workers and exit parallel mode. Don't warn about leaked resources.
5325 */
5327 s->parallelModeLevel = 0;
5328
5329 /*
5330 * We can skip all this stuff if the subxact failed before creating a
5331 * ResourceOwner...
5332 */
5333 if (s->curTransactionOwner)
5334 {
5343
5344 /* Advertise the fact that we aborted in pg_xact. */
5345 (void) RecordTransactionAbort(true);
5346
5347 /* Post-abort cleanup */
5350
5353
5356 false, false);
5357
5358 AtEOXact_Aio(false);
5362 AtEOSubXact_Inval(false);
5365 false, false);
5368 false, false);
5370
5371 AtEOXact_GUC(false, s->gucNestLevel);
5382 }
5383
5384 /*
5385 * Restore the upper transaction's read-only state, too. This should be
5386 * redundant with GUC's cleanup but we may as well do it for consistency
5387 * with the commit case.
5388 */
5390
5392}
void pgaio_error_cleanup(void)
Definition: aio.c:1165
void AtEOXact_Aio(bool is_commit)
Definition: aio.c:1193
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:5577
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:2137
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:136
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:134
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:814
void AtSubAbort_smgr(void)
Definition: storage.c:975
int parallelModeLevel
Definition: xact.c:215
FullTransactionId fullTransactionId
Definition: xact.c:196
bool prevXactReadOnly
Definition: xact.c:212
void AtEOSubXact_on_commit_actions(bool isCommit, SubTransactionId mySubid, SubTransactionId parentSubid)
Definition: tablecmds.c:19449
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:3916
static void AtSubAbort_Memory(void)
Definition: xact.c:1917
static const char * TransStateAsString(TransState state)
Definition: xact.c:5778
bool XactReadOnly
Definition: xact.c:83
static void AtSubAbort_childXids(void)
Definition: xact.c:1955
static void AtSubAbort_ResourceOwner(void)
Definition: xact.c:1942
static void ShowTransactionState(const char *str)
Definition: xact.c:5666
static TransactionId RecordTransactionAbort(bool isSubXact)
Definition: xact.c:1767
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:145
void XLogResetInsertion(void)
Definition: xloginsert.c:225

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

2823{
2825 TransactionId latestXid;
2826 bool is_parallel_worker;
2827
2828 /* Prevent cancel/die interrupt while cleaning up */
2830
2831 /* Disable transaction timeout */
2832 if (TransactionTimeout > 0)
2834
2835 /* Make sure we have a valid memory context and resource owner */
2838
2839 /*
2840 * Release any LW locks we might be holding as quickly as possible.
2841 * (Regular locks, however, must be held till we finish aborting.)
2842 * Releasing LW locks is critical since we might try to grab them again
2843 * while cleaning up!
2844 */
2846
2847 /*
2848 * Cleanup waiting for LSN if any.
2849 */
2851
2852 /* Clear wait information and command progress indicator */
2855
2857
2858 /* Clean up buffer content locks, too */
2859 UnlockBuffers();
2860
2861 /* Reset WAL record construction state */
2863
2864 /* Cancel condition variable sleep */
2866
2867 /*
2868 * Also clean up any open wait for lock, since the lock manager will choke
2869 * if we try to wait for another lock before doing this.
2870 */
2872
2873 /*
2874 * If any timeout events are still active, make sure the timeout interrupt
2875 * is scheduled. This covers possible loss of a timeout interrupt due to
2876 * longjmp'ing out of the SIGINT handler (see notes in handle_sig_alarm).
2877 * We delay this till after LockErrorCleanup so that we don't uselessly
2878 * reschedule lock or deadlock check timeouts.
2879 */
2881
2882 /*
2883 * Re-enable signals, in case we got here by longjmp'ing out of a signal
2884 * handler. We do this fairly early in the sequence so that the timeout
2885 * infrastructure will be functional if needed while aborting.
2886 */
2887 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
2888
2889 /*
2890 * check the current transaction state
2891 */
2892 is_parallel_worker = (s->blockState == TBLOCK_PARALLEL_INPROGRESS);
2893 if (s->state != TRANS_INPROGRESS && s->state != TRANS_PREPARE)
2894 elog(WARNING, "AbortTransaction while in %s state",
2896 Assert(s->parent == NULL);
2897
2898 /*
2899 * set the current transaction state information appropriately during the
2900 * abort processing
2901 */
2902 s->state = TRANS_ABORT;
2903
2904 /*
2905 * Reset user ID which might have been changed transiently. We need this
2906 * to clean up in case control escaped out of a SECURITY DEFINER function
2907 * or other local change of CurrentUserId; therefore, the prior value of
2908 * SecurityRestrictionContext also needs to be restored.
2909 *
2910 * (Note: it is not necessary to restore session authorization or role
2911 * settings here because those can only be changed via GUC, and GUC will
2912 * take care of rolling them back if need be.)
2913 */
2915
2916 /* Forget about any active REINDEX. */
2918
2919 /* Reset logical streaming state. */
2921
2922 /* Reset snapshot export state. */
2924
2925 /*
2926 * If this xact has started any unfinished parallel operation, clean up
2927 * its workers and exit parallel mode. Don't warn about leaked resources.
2928 */
2929 AtEOXact_Parallel(false);
2930 s->parallelModeLevel = 0;
2931 s->parallelChildXact = false; /* should be false already */
2932
2933 /*
2934 * do abort processing
2935 */
2936 AfterTriggerEndXact(false); /* 'false' means it's abort */
2938 smgrDoPendingSyncs(false, is_parallel_worker);
2939 AtEOXact_LargeObject(false);
2941 AtEOXact_RelationMap(false, is_parallel_worker);
2943
2944 /*
2945 * Advertise the fact that we aborted in pg_xact (assuming that we got as
2946 * far as assigning an XID to advertise). But if we're inside a parallel
2947 * worker, skip this; the user backend must be the one to write the abort
2948 * record.
2949 */
2950 if (!is_parallel_worker)
2951 latestXid = RecordTransactionAbort(false);
2952 else
2953 {
2954 latestXid = InvalidTransactionId;
2955
2956 /*
2957 * Since the parallel leader won't get our value of XactLastRecEnd in
2958 * this case, we nudge WAL-writer ourselves in this case. See related
2959 * comments in RecordTransactionAbort for why this matters.
2960 */
2962 }
2963
2964 TRACE_POSTGRESQL_TRANSACTION_ABORT(MyProc->vxid.lxid);
2965
2966 /*
2967 * Let others know about no transaction in progress by me. Note that this
2968 * must be done _before_ releasing locks we hold and _after_
2969 * RecordTransactionAbort.
2970 */
2971 ProcArrayEndTransaction(MyProc, latestXid);
2972
2973 /*
2974 * Post-abort cleanup. See notes in CommitTransaction() concerning
2975 * ordering. We can skip all of it if the transaction failed before
2976 * creating a resource owner.
2977 */
2978 if (TopTransactionResourceOwner != NULL)
2979 {
2980 if (is_parallel_worker)
2982 else
2984
2987 false, true);
2988 AtEOXact_Aio(false);
2989 AtEOXact_Buffers(false);
2992 AtEOXact_Inval(false);
2996 false, true);
2999 false, true);
3000 smgrDoPendingDeletes(false);
3001
3002 AtEOXact_GUC(false, 1);
3003 AtEOXact_SPI(false);
3004 AtEOXact_Enum();
3006 AtEOXact_Namespace(false, is_parallel_worker);
3007 AtEOXact_SMgr();
3008 AtEOXact_Files(false);
3010 AtEOXact_HashTables(false);
3011 AtEOXact_PgStat(false, is_parallel_worker);
3015 }
3016
3017 /*
3018 * State remains TRANS_ABORT until CleanupTransaction().
3019 */
3021}
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:6271
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:3991
uint32 TransactionId
Definition: c.h:661
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:1165
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:67
int TransactionTimeout
Definition: proc.c:62
void smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
Definition: storage.c:741
void smgrDoPendingDeletes(bool isCommit)
Definition: storage.c:673
LocalTransactionId lxid
Definition: proc.h:217
struct PGPROC::@130 vxid
bool parallelChildXact
Definition: xact.c:216
void AtEOXact_on_commit_actions(bool isCommit)
Definition: tablecmds.c:19417
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:1929
static void CallXactCallbacks(XactEvent event)
Definition: xact.c:3856
@ XACT_EVENT_ABORT
Definition: xact.h:131
@ XACT_EVENT_PARALLEL_ABORT
Definition: xact.h:132
XLogRecPtr XactLastRecEnd
Definition: xlog.c:256
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2612
void WaitLSNCleanup(void)
Definition: xlogwait.c:284

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

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

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

1898{
1899 /*
1900 * Switch into TransactionAbortContext, which should have some free space
1901 * even if nothing else does. We'll work in this context until we've
1902 * finished cleaning up.
1903 *
1904 * It is barely possible to get here when we've not been able to create
1905 * TransactionAbortContext yet; if so use TopMemoryContext.
1906 */
1907 if (TransactionAbortContext != NULL)
1909 else
1911}
static MemoryContext TransactionAbortContext
Definition: xact.c:304

References MemoryContextSwitchTo(), TopMemoryContext, and TransactionAbortContext.

Referenced by AbortOutOfAnyTransaction(), and AbortTransaction().

◆ AtAbort_ResourceOwner()

static void AtAbort_ResourceOwner ( void  )
static

Definition at line 1929 of file xact.c.

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

References CurrentResourceOwner, and TopTransactionResourceOwner.

Referenced by AbortTransaction().

◆ AtCCI_LocalCache()

static void AtCCI_LocalCache ( void  )
static

Definition at line 1592 of file xact.c.

1593{
1594 /*
1595 * Make any pending relation map changes visible. We must do this before
1596 * processing local sinval messages, so that the map changes will get
1597 * reflected into the relcache when relcache invals are processed.
1598 */
1600
1601 /*
1602 * Make catalog changes visible to me for the next command.
1603 */
1605}
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 1987 of file xact.c.

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

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

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

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

1169{
1171}
void AcceptInvalidationMessages(void)
Definition: inval.c:930

References AcceptInvalidationMessages().

Referenced by StartTransaction().

◆ AtStart_Memory()

static void AtStart_Memory ( void  )
static

Definition at line 1177 of file xact.c.

1178{
1180
1181 /*
1182 * Remember the memory context that was active prior to transaction start.
1183 */
1185
1186 /*
1187 * If this is the first time through, create a private context for
1188 * AbortTransaction to work in. By reserving some space now, we can
1189 * insulate AbortTransaction from out-of-memory scenarios. Like
1190 * ErrorContext, we set it up with slow growth rate and a nonzero minimum
1191 * size, so that space will be reserved immediately.
1192 */
1193 if (TransactionAbortContext == NULL)
1196 "TransactionAbortContext",
1197 32 * 1024,
1198 32 * 1024,
1199 32 * 1024);
1200
1201 /*
1202 * Likewise, if this is the first time through, create a top-level context
1203 * for transaction-local data. This context will be reset at transaction
1204 * end, and then re-used in later transactions.
1205 */
1206 if (TopTransactionContext == NULL)
1209 "TopTransactionContext",
1211
1212 /*
1213 * In a top-level transaction, CurTransactionContext is the same as
1214 * TopTransactionContext.
1215 */
1218
1219 /* Make the CurTransactionContext active. */
1221}
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 1227 of file xact.c.

1228{
1230
1231 /*
1232 * We shouldn't have a transaction resource owner already.
1233 */
1235
1236 /*
1237 * Create a toplevel resource owner for the transaction.
1238 */
1239 s->curTransactionOwner = ResourceOwnerCreate(NULL, "TopTransaction");
1240
1244}
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 1955 of file xact.c.

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

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_Memory()

static void AtSubAbort_Memory ( void  )
static

Definition at line 1917 of file xact.c.

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

Referenced by AbortSubTransaction().

◆ AtSubAbort_ResourceOwner()

static void AtSubAbort_ResourceOwner ( void  )
static

Definition at line 1942 of file xact.c.

1943{
1945
1946 /* Make sure we have a valid ResourceOwner */
1948}

References CurrentResourceOwner, CurrentTransactionState, and TransactionStateData::curTransactionOwner.

Referenced by AbortSubTransaction().

◆ AtSubCleanup_Memory()

static void AtSubCleanup_Memory ( void  )
static

Definition at line 2035 of file xact.c.

2036{
2038
2039 Assert(s->parent != NULL);
2040
2041 /*
2042 * Return to the memory context that was current before we started the
2043 * subtransaction. (In principle, this could not be any of the contexts
2044 * we are about to delete. If it somehow is, assertions in mcxt.c will
2045 * complain.)
2046 */
2048
2049 /* Update CurTransactionContext (might not be same as priorContext) */
2051
2052 /*
2053 * Clear the special abort context for next time.
2054 */
2055 if (TransactionAbortContext != NULL)
2057
2058 /*
2059 * Delete the subxact local memory contexts. Its CurTransactionContext can
2060 * go too (note this also kills CurTransactionContexts from any children
2061 * of the subxact).
2062 */
2063 if (s->curTransactionContext)
2065 s->curTransactionContext = NULL;
2066}
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 1677 of file xact.c.

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

1649{
1651
1652 Assert(s->parent != NULL);
1653
1654 /* Return to parent transaction level's memory context. */
1657
1658 /*
1659 * Ordinarily we cannot throw away the child's CurTransactionContext,
1660 * since the data it contains will be needed at upper commit. However, if
1661 * there isn't actually anything in it, we can throw it away. This avoids
1662 * a small memory leak in the common case of "trivial" subxacts.
1663 */
1665 {
1667 s->curTransactionContext = NULL;
1668 }
1669}
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 1255 of file xact.c.

1256{
1258
1260
1261 /*
1262 * Remember the context that was active prior to subtransaction start.
1263 */
1265
1266 /*
1267 * Create a CurTransactionContext, which will be used to hold data that
1268 * survives subtransaction commit but disappears on subtransaction abort.
1269 * We make it a child of the immediate parent's CurTransactionContext.
1270 */
1272 "CurTransactionContext",
1275
1276 /* Make the CurTransactionContext active. */
1278}

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

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

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

Referenced by StartSubTransaction().

◆ BeginImplicitTransactionBlock()

void BeginImplicitTransactionBlock ( void  )

Definition at line 4344 of file xact.c.

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

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

4713{
4715 bool save_ExitOnAnyError = ExitOnAnyError;
4716
4717 /*
4718 * Errors within this function are improbable, but if one does happen we
4719 * force a FATAL exit. Callers generally aren't prepared to handle losing
4720 * control, and moreover our transaction state is probably corrupted if we
4721 * fail partway through; so an ordinary ERROR longjmp isn't okay.
4722 */
4723 ExitOnAnyError = true;
4724
4725 /*
4726 * We do not check for parallel mode here. It's permissible to start and
4727 * end "internal" subtransactions while in parallel mode, so long as no
4728 * new XIDs or command IDs are assigned. Enforcement of that occurs in
4729 * AssignTransactionId() and CommandCounterIncrement().
4730 */
4731
4732 switch (s->blockState)
4733 {
4734 case TBLOCK_STARTED:
4735 case TBLOCK_INPROGRESS:
4738 case TBLOCK_END:
4739 case TBLOCK_PREPARE:
4741 /* Normal subtransaction start */
4743 s = CurrentTransactionState; /* changed by push */
4744
4745 /*
4746 * Savepoint names, like the TransactionState block itself, live
4747 * in TopTransactionContext.
4748 */
4749 if (name)
4751 break;
4752
4753 /* These cases are invalid. */
4754 case TBLOCK_DEFAULT:
4755 case TBLOCK_BEGIN:
4756 case TBLOCK_SUBBEGIN:
4757 case TBLOCK_SUBRELEASE:
4758 case TBLOCK_SUBCOMMIT:
4759 case TBLOCK_ABORT:
4760 case TBLOCK_SUBABORT:
4761 case TBLOCK_ABORT_END:
4765 case TBLOCK_SUBRESTART:
4767 elog(FATAL, "BeginInternalSubTransaction: unexpected state %s",
4769 break;
4770 }
4771
4774
4775 ExitOnAnyError = save_ExitOnAnyError;
4776}
#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:5434
void StartTransactionCommand(void)
Definition: xact.c:3077
static const char * BlockStateAsString(TBlockState blockState)
Definition: xact.c:5725
void CommitTransactionCommand(void)
Definition: xact.c:3175

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

3943{
3945
3946 switch (s->blockState)
3947 {
3948 /*
3949 * We are not inside a transaction block, so allow one to begin.
3950 */
3951 case TBLOCK_STARTED:
3953 break;
3954
3955 /*
3956 * BEGIN converts an implicit transaction block to a regular one.
3957 * (Note that we allow this even if we've already done some
3958 * commands, which is a bit odd but matches historical practice.)
3959 */
3962 break;
3963
3964 /*
3965 * Already a transaction block in progress.
3966 */
3967 case TBLOCK_INPROGRESS:
3970 case TBLOCK_ABORT:
3971 case TBLOCK_SUBABORT:
3973 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3974 errmsg("there is already a transaction in progress")));
3975 break;
3976
3977 /* These cases are invalid. */
3978 case TBLOCK_DEFAULT:
3979 case TBLOCK_BEGIN:
3980 case TBLOCK_SUBBEGIN:
3981 case TBLOCK_END:
3982 case TBLOCK_SUBRELEASE:
3983 case TBLOCK_SUBCOMMIT:
3984 case TBLOCK_ABORT_END:
3988 case TBLOCK_SUBRESTART:
3990 case TBLOCK_PREPARE:
3991 elog(FATAL, "BeginTransactionBlock: unexpected state %s",
3993 break;
3994 }
3995}

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

5726{
5727 switch (blockState)
5728 {
5729 case TBLOCK_DEFAULT:
5730 return "DEFAULT";
5731 case TBLOCK_STARTED:
5732 return "STARTED";
5733 case TBLOCK_BEGIN:
5734 return "BEGIN";
5735 case TBLOCK_INPROGRESS:
5736 return "INPROGRESS";
5738 return "IMPLICIT_INPROGRESS";
5740 return "PARALLEL_INPROGRESS";
5741 case TBLOCK_END:
5742 return "END";
5743 case TBLOCK_ABORT:
5744 return "ABORT";
5745 case TBLOCK_ABORT_END:
5746 return "ABORT_END";
5748 return "ABORT_PENDING";
5749 case TBLOCK_PREPARE:
5750 return "PREPARE";
5751 case TBLOCK_SUBBEGIN:
5752 return "SUBBEGIN";
5754 return "SUBINPROGRESS";
5755 case TBLOCK_SUBRELEASE:
5756 return "SUBRELEASE";
5757 case TBLOCK_SUBCOMMIT:
5758 return "SUBCOMMIT";
5759 case TBLOCK_SUBABORT:
5760 return "SUBABORT";
5762 return "SUBABORT_END";
5764 return "SUBABORT_PENDING";
5765 case TBLOCK_SUBRESTART:
5766 return "SUBRESTART";
5768 return "SUBABORT_RESTART";
5769 }
5770 return "UNRECOGNIZED";
5771}

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

3919{
3920 SubXactCallbackItem *item;
3922
3923 for (item = SubXact_callbacks; item; item = next)
3924 {
3925 /* allow callbacks to unregister themselves when called */
3926 next = item->next;
3927 item->callback(event, mySubid, parentSubid, item->arg);
3928 }
3929}
static int32 next
Definition: blutils.c:224
struct SubXactCallbackItem * next
Definition: xact.c:323
SubXactCallback callback
Definition: xact.c:324
static SubXactCallbackItem * SubXact_callbacks
Definition: xact.c:328

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

3857{
3858 XactCallbackItem *item;
3860
3861 for (item = Xact_callbacks; item; item = next)
3862 {
3863 /* allow callbacks to unregister themselves when called */
3864 next = item->next;
3865 item->callback(event, item->arg);
3866 }
3867}
struct XactCallbackItem * next
Definition: xact.c:311
void * arg
Definition: xact.c:313
XactCallback callback
Definition: xact.c:312
static XactCallbackItem * Xact_callbacks
Definition: xact.c:316

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

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

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

Referenced by RequireTransactionBlock(), and WarnNoTransactionBlock().

◆ CleanupSubTransaction()

static void CleanupSubTransaction ( void  )
static

Definition at line 5401 of file xact.c.

5402{
5404
5405 ShowTransactionState("CleanupSubTransaction");
5406
5407 if (s->state != TRANS_ABORT)
5408 elog(WARNING, "CleanupSubTransaction while in %s state",
5410
5412
5415 if (s->curTransactionOwner)
5417 s->curTransactionOwner = NULL;
5418
5420
5421 s->state = TRANS_DEFAULT;
5422
5424}
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:2035
static void PopTransaction(void)
Definition: xact.c:5496

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

3028{
3030
3031 /*
3032 * State should still be TRANS_ABORT from AbortTransaction().
3033 */
3034 if (s->state != TRANS_ABORT)
3035 elog(FATAL, "CleanupTransaction: unexpected state %s",
3037
3038 /*
3039 * do abort cleanup processing
3040 */
3041 AtCleanup_Portals(); /* now safe to release portal memory */
3042 AtEOXact_Snapshot(false, true); /* and release the transaction's snapshots */
3043
3044 CurrentResourceOwner = NULL; /* and resource owner */
3047 s->curTransactionOwner = NULL;
3050
3051 AtCleanup_Memory(); /* and transaction memory */
3052
3055 s->nestingLevel = 0;
3056 s->gucNestLevel = 0;
3057 s->childXids = NULL;
3058 s->nChildXids = 0;
3059 s->maxChildXids = 0;
3060 s->parallelModeLevel = 0;
3061 s->parallelChildXact = false;
3062
3065
3066 /*
3067 * done with abort processing, set current transaction state back to
3068 * default
3069 */
3070 s->state = TRANS_DEFAULT;
3071}
#define InvalidSubTransactionId
Definition: c.h:667
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:1987
static int nParallelCurrentXids
Definition: xact.c:127

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

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

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

5123{
5125
5126 ShowTransactionState("CommitSubTransaction");
5127
5128 if (s->state != TRANS_INPROGRESS)
5129 elog(WARNING, "CommitSubTransaction while in %s state",
5131
5132 /* Pre-commit processing goes here */
5133
5136
5137 /*
5138 * If this subxact has started any unfinished parallel operation, clean up
5139 * its workers and exit parallel mode. Warn about leaked resources.
5140 */
5142 if (s->parallelModeLevel != 0)
5143 {
5144 elog(WARNING, "parallelModeLevel is %d not 0 at end of subtransaction",
5146 s->parallelModeLevel = 0;
5147 }
5148
5149 /* Do the actual "commit", such as it is */
5150 s->state = TRANS_COMMIT;
5151
5152 /* Must CCI to ensure commands of subtransaction are seen as done */
5154
5155 /*
5156 * Prior to 8.4 we marked subcommit in clog at this point. We now only
5157 * perform that step, if required, as part of the atomic update of the
5158 * whole transaction tree at top level commit or abort.
5159 */
5160
5161 /* Post-commit cleanup */
5167 s->parent->nestingLevel,
5172
5175
5178 true, false);
5182 AtEOSubXact_Inval(true);
5184
5185 /*
5186 * The only lock we actually release here is the subtransaction XID lock.
5187 */
5191
5192 /*
5193 * Other locks should get transferred to their parent resource owner.
5194 */
5197 true, false);
5200 true, false);
5201
5202 AtEOXact_GUC(true, s->gucNestLevel);
5213
5214 /*
5215 * We need to restore the upper transaction's read-only state, in case the
5216 * upper is read-write while the child is read-only; GUC will incorrectly
5217 * think it should leave the child state in place.
5218 */
5220
5224 s->curTransactionOwner = NULL;
5225
5227
5228 s->state = TRANS_DEFAULT;
5229
5231}
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:1648
static void AtSubCommit_childXids(void)
Definition: xact.c:1677
void CommandCounterIncrement(void)
Definition: xact.c:1101
@ 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 2241 of file xact.c.

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

3176{
3177 /*
3178 * Repeatedly call CommitTransactionCommandInternal() until all the work
3179 * is done.
3180 */
3182 {
3183 }
3184}
static bool CommitTransactionCommandInternal(void)
Definition: xact.c:3193

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(), copy_sequences(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), finish_xact_command(), FinishSyncWorker(), get_database_list(), get_subscription_list(), HasSubscriptionTablesCached(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncSequences(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), pa_stream_abort(), ParallelApplyWorkerMain(), ParallelWorkerMain(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ProcessSequencesForSync(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), 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 3193 of file xact.c.

3194{
3197
3198 /* Must save in case we need to restore below */
3200
3201 switch (s->blockState)
3202 {
3203 /*
3204 * These shouldn't happen. TBLOCK_DEFAULT means the previous
3205 * StartTransactionCommand didn't set the STARTED state
3206 * appropriately, while TBLOCK_PARALLEL_INPROGRESS should be ended
3207 * by EndParallelWorkerTransaction(), not this function.
3208 */
3209 case TBLOCK_DEFAULT:
3211 elog(FATAL, "CommitTransactionCommand: unexpected state %s",
3213 break;
3214
3215 /*
3216 * If we aren't in a transaction block, just do our usual
3217 * transaction commit, and return to the idle state.
3218 */
3219 case TBLOCK_STARTED:
3222 break;
3223
3224 /*
3225 * We are completing a "BEGIN TRANSACTION" command, so we change
3226 * to the "transaction block in progress" state and return. (We
3227 * assume the BEGIN did nothing to the database, so we need no
3228 * CommandCounterIncrement.)
3229 */
3230 case TBLOCK_BEGIN:
3232 break;
3233
3234 /*
3235 * This is the case when we have finished executing a command
3236 * someplace within a transaction block. We increment the command
3237 * counter and return.
3238 */
3239 case TBLOCK_INPROGRESS:
3243 break;
3244
3245 /*
3246 * We are completing a "COMMIT" command. Do it and return to the
3247 * idle state.
3248 */
3249 case TBLOCK_END:
3252 if (s->chain)
3253 {
3256 s->chain = false;
3258 }
3259 break;
3260
3261 /*
3262 * Here we are in the middle of a transaction block but one of the
3263 * commands caused an abort so we do nothing but remain in the
3264 * abort state. Eventually we will get a ROLLBACK command.
3265 */
3266 case TBLOCK_ABORT:
3267 case TBLOCK_SUBABORT:
3268 break;
3269
3270 /*
3271 * Here we were in an aborted transaction block and we just got
3272 * the ROLLBACK command from the user, so clean up the
3273 * already-aborted transaction and return to the idle state.
3274 */
3275 case TBLOCK_ABORT_END:
3278 if (s->chain)
3279 {
3282 s->chain = false;
3284 }
3285 break;
3286
3287 /*
3288 * Here we were in a perfectly good transaction block but the user
3289 * told us to ROLLBACK anyway. We have to abort the transaction
3290 * and then clean up.
3291 */
3296 if (s->chain)
3297 {
3300 s->chain = false;
3302 }
3303 break;
3304
3305 /*
3306 * We are completing a "PREPARE TRANSACTION" command. Do it and
3307 * return to the idle state.
3308 */
3309 case TBLOCK_PREPARE:
3312 break;
3313
3314 /*
3315 * The user issued a SAVEPOINT inside a transaction block. Start a
3316 * subtransaction. (DefineSavepoint already did PushTransaction,
3317 * so as to have someplace to put the SUBBEGIN state.)
3318 */
3319 case TBLOCK_SUBBEGIN:
3322 break;
3323
3324 /*
3325 * The user issued a RELEASE command, so we end the current
3326 * subtransaction and return to the parent transaction. The parent
3327 * might be ended too, so repeat till we find an INPROGRESS
3328 * transaction or subtransaction.
3329 */
3330 case TBLOCK_SUBRELEASE:
3331 do
3332 {
3334 s = CurrentTransactionState; /* changed by pop */
3335 } while (s->blockState == TBLOCK_SUBRELEASE);
3336
3339 break;
3340
3341 /*
3342 * The user issued a COMMIT, so we end the current subtransaction
3343 * hierarchy and perform final commit. We do this by rolling up
3344 * any subtransactions into their parent, which leads to O(N^2)
3345 * operations with respect to resource owners - this isn't that
3346 * bad until we approach a thousands of savepoints but is
3347 * necessary for correctness should after triggers create new
3348 * resource owners.
3349 */
3350 case TBLOCK_SUBCOMMIT:
3351 do
3352 {
3354 s = CurrentTransactionState; /* changed by pop */
3355 } while (s->blockState == TBLOCK_SUBCOMMIT);
3356 /* If we had a COMMIT command, finish off the main xact too */
3357 if (s->blockState == TBLOCK_END)
3358 {
3359 Assert(s->parent == NULL);
3362 if (s->chain)
3363 {
3366 s->chain = false;
3368 }
3369 }
3370 else if (s->blockState == TBLOCK_PREPARE)
3371 {
3372 Assert(s->parent == NULL);
3375 }
3376 else
3377 elog(ERROR, "CommitTransactionCommand: unexpected state %s",
3379 break;
3380
3381 /*
3382 * The current already-failed subtransaction is ending due to a
3383 * ROLLBACK or ROLLBACK TO command, so pop it and recursively
3384 * examine the parent (which could be in any of several states).
3385 * As we need to examine the parent, return false to request the
3386 * caller to do the next iteration.
3387 */
3390 return false;
3391
3392 /*
3393 * As above, but it's not dead yet, so abort first.
3394 */
3398 return false;
3399
3400 /*
3401 * The current subtransaction is the target of a ROLLBACK TO
3402 * command. Abort and pop it, then start a new subtransaction
3403 * with the same name.
3404 */
3405 case TBLOCK_SUBRESTART:
3406 {
3407 char *name;
3408 int savepointLevel;
3409
3410 /* save name and keep Cleanup from freeing it */
3411 name = s->name;
3412 s->name = NULL;
3413 savepointLevel = s->savepointLevel;
3414
3417
3418 DefineSavepoint(NULL);
3419 s = CurrentTransactionState; /* changed by push */
3420 s->name = name;
3421 s->savepointLevel = savepointLevel;
3422
3423 /* This is the same as TBLOCK_SUBBEGIN case */
3427 }
3428 break;
3429
3430 /*
3431 * Same as above, but the subtransaction had already failed, so we
3432 * don't need AbortSubTransaction.
3433 */
3435 {
3436 char *name;
3437 int savepointLevel;
3438
3439 /* save name and keep Cleanup from freeing it */
3440 name = s->name;
3441 s->name = NULL;
3442 savepointLevel = s->savepointLevel;
3443
3445
3446 DefineSavepoint(NULL);
3447 s = CurrentTransactionState; /* changed by push */
3448 s->name = name;
3449 s->savepointLevel = savepointLevel;
3450
3451 /* This is the same as TBLOCK_SUBBEGIN case */
3455 }
3456 break;
3457 }
3458
3459 /* Done, no more iterations required */
3460 return true;
3461}
void SaveTransactionCharacteristics(SavedTransactionCharacteristics *s)
Definition: xact.c:3154
void RestoreTransactionCharacteristics(const SavedTransactionCharacteristics *s)
Definition: xact.c:3162
static void StartTransaction(void)
Definition: xact.c:2077
void DefineSavepoint(const char *name)
Definition: xact.c:4391
static void CommitSubTransaction(void)
Definition: xact.c:5122
static void CommitTransaction(void)
Definition: xact.c:2241
static void PrepareTransaction(void)
Definition: xact.c:2528
static void StartSubTransaction(void)
Definition: xact.c:5085

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

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

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

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

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

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

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

5531{
5533 Size nxids = 0;
5535
5536 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5537 {
5539 nxids = add_size(nxids, 1);
5540 nxids = add_size(nxids, s->nChildXids);
5541 }
5542
5543 return add_size(size, mul_size(sizeof(TransactionId), nxids));
5544}
size_t Size
Definition: c.h:614
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:240

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

1154{
1155 forceSyncCommit = true;
1156}
static bool forceSyncCommit
Definition: xact.c:294

References forceSyncCommit.

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

◆ GetCurrentCommandId()

CommandId GetCurrentCommandId ( bool  used)

Definition at line 830 of file xact.c.

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

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

References CurrentTransactionState, and TransactionStateData::fullTransactionId.

◆ GetCurrentStatementStartTimestamp()

TimestampTz GetCurrentStatementStartTimestamp ( void  )

Definition at line 880 of file xact.c.

881{
882 return stmtStartTimestamp;
883}
static TimestampTz stmtStartTimestamp
Definition: xact.c:282

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

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

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

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

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

501{
503}

References XactTopFullTransactionId.

Referenced by pg_current_xact_id_if_assigned().

◆ GetTopTransactionId()

◆ GetTopTransactionIdIfAny()

◆ IsAbortedTransactionBlockState()

◆ IsInParallelMode()

◆ IsInTransactionBlock()

bool IsInTransactionBlock ( bool  isTopLevel)

Definition at line 3787 of file xact.c.

3788{
3789 /*
3790 * Return true on same conditions that would make
3791 * PreventInTransactionBlock error out
3792 */
3793 if (IsTransactionBlock())
3794 return true;
3795
3796 if (IsSubTransaction())
3797 return true;
3798
3799 if (!isTopLevel)
3800 return true;
3801
3804 return true;
3805
3806 return false;
3807}

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

Referenced by vacuum().

◆ IsSubTransaction()

◆ IsSubxactTopXidLogPending()

bool IsSubxactTopXidLogPending ( void  )

Definition at line 560 of file xact.c.

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

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

Referenced by MarkSubxactTopXidLogged(), and XLogRecordAssemble().

◆ IsTransactionBlock()

◆ IsTransactionOrTransactionBlock()

◆ IsTransactionState()

bool IsTransactionState ( void  )

Definition at line 388 of file xact.c.

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

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(), FetchRelationStates(), FinishSyncWorker(), IsSubxactTopXidLogPending(), LogicalRepApplyLoop(), LogLogicalMessage(), maybe_reread_subscription(), pa_send_data(), pa_start_subtrans(), pg_do_encoding_conversion(), PrepareClientEncoding(), PrepareTempTablespaces(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), 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 592 of file xact.c.

593{
595
597}
bool IsSubxactTopXidLogPending(void)
Definition: xact.c:560

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

Referenced by XLogInsertRecord().

◆ PopTransaction()

static void PopTransaction ( void  )
static

Definition at line 5496 of file xact.c.

5497{
5499
5500 if (s->state != TRANS_DEFAULT)
5501 elog(WARNING, "PopTransaction while in %s state",
5503
5504 if (s->parent == NULL)
5505 elog(FATAL, "PopTransaction with no parent");
5506
5508
5509 /* Let's just make sure CurTransactionContext is good */
5512
5513 /* Ditto for ResourceOwner links */
5516
5517 /* Free the old child structure */
5518 if (s->name)
5519 pfree(s->name);
5520 pfree(s);
5521}

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

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

4011{
4013 bool result;
4014
4015 /* Set up to commit the current transaction */
4016 result = EndTransactionBlock(false);
4017
4018 /* If successful, change outer tblock state to PREPARE */
4019 if (result)
4020 {
4022
4023 while (s->parent != NULL)
4024 s = s->parent;
4025
4026 if (s->blockState == TBLOCK_END)
4027 {
4028 /* Save GID where PrepareTransaction can find it again */
4030
4032 }
4033 else
4034 {
4035 /*
4036 * ignore case where we are not in a transaction;
4037 * EndTransactionBlock already issued a warning.
4038 */
4041 /* Don't send back a PREPARE result tag... */
4042 result = false;
4043 }
4044 }
4045
4046 return result;
4047}
bool EndTransactionBlock(bool chain)
Definition: xact.c:4062

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

3667{
3668 /*
3669 * xact block already started?
3670 */
3671 if (IsTransactionBlock())
3672 ereport(ERROR,
3673 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3674 /* translator: %s represents an SQL statement name */
3675 errmsg("%s cannot run inside a transaction block",
3676 stmtType)));
3677
3678 /*
3679 * subtransaction?
3680 */
3681 if (IsSubTransaction())
3682 ereport(ERROR,
3683 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3684 /* translator: %s represents an SQL statement name */
3685 errmsg("%s cannot run inside a subtransaction",
3686 stmtType)));
3687
3688 /*
3689 * inside a function call?
3690 */
3691 if (!isTopLevel)
3692 ereport(ERROR,
3693 (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION),
3694 /* translator: %s represents an SQL statement name */
3695 errmsg("%s cannot be executed from a function", stmtType)));
3696
3697 /* If we got past IsTransactionBlock test, should be in default state */
3700 elog(FATAL, "cannot prevent transaction chain");
3701
3702 /* All okay. Set the flag to make sure the right thing happens later. */
3704}
#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 5434 of file xact.c.

5435{
5438
5439 /*
5440 * We keep subtransaction state nodes in TopTransactionContext.
5441 */
5442 s = (TransactionState)
5444 sizeof(TransactionStateData));
5445
5446 /*
5447 * Assign a subtransaction ID, watching out for counter wraparound.
5448 */
5451 {
5453 pfree(s);
5454 ereport(ERROR,
5455 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5456 errmsg("cannot have more than 2^32-1 subtransactions in a transaction")));
5457 }
5458
5459 /*
5460 * We can now stack a minimally valid subtransaction without fear of
5461 * failure.
5462 */
5463 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
5465 s->parent = p;
5466 s->nestingLevel = p->nestingLevel + 1;
5469 s->state = TRANS_DEFAULT;
5474 s->parallelModeLevel = 0;
5476 s->topXidLogged = false;
5477
5479
5480 /*
5481 * AbortSubTransaction and CleanupSubTransaction have to be able to cope
5482 * with the subtransaction from here on out; in particular they should not
5483 * assume that it necessarily has a transaction context, resource owner,
5484 * or XID.
5485 */
5486}
int NewGUCNestLevel(void)
Definition: guc.c:2110
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:213
TransactionStateData * TransactionState
Definition: xact.c:222
static SubTransactionId currentSubTransactionId
Definition: xact.c:267

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

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

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

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

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

3883{
3884 SubXactCallbackItem *item;
3885
3886 item = (SubXactCallbackItem *)
3888 item->callback = callback;
3889 item->arg = arg;
3890 item->next = SubXact_callbacks;
3891 SubXact_callbacks = item;
3892}
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 4786 of file xact.c.

4787{
4789
4790 /*
4791 * We do not check for parallel mode here. It's permissible to start and
4792 * end "internal" subtransactions while in parallel mode, so long as no
4793 * new XIDs or command IDs are assigned.
4794 */
4795
4797 elog(ERROR, "ReleaseCurrentSubTransaction: unexpected state %s",
4802 s = CurrentTransactionState; /* changed by pop */
4804}

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

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

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

3735{
3736 CheckTransactionBlock(isTopLevel, true, stmtType);
3737}
static void CheckTransactionBlock(bool isTopLevel, bool throwError, const char *stmtType)
Definition: xact.c:3743

References CheckTransactionBlock().

Referenced by PerformCursorOpen(), and standard_ProcessUtility().

◆ RestoreTransactionCharacteristics()

◆ RollbackAndReleaseCurrentSubTransaction()

void RollbackAndReleaseCurrentSubTransaction ( void  )

Definition at line 4814 of file xact.c.

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

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

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

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

5559{
5561 Size nxids = 0;
5562 Size i = 0;
5563 TransactionId *workspace;
5565
5566 result = (SerializedTransactionState *) start_address;
5567
5568 result->xactIsoLevel = XactIsoLevel;
5571 result->currentFullTransactionId =
5574
5575 /*
5576 * If we're running in a parallel worker and launching a parallel worker
5577 * of our own, we can just pass along the information that was passed to
5578 * us.
5579 */
5580 if (nParallelCurrentXids > 0)
5581 {
5583 memcpy(&result->parallelCurrentXids[0], ParallelCurrentXids,
5585 return;
5586 }
5587
5588 /*
5589 * OK, we need to generate a sorted list of XIDs that our workers should
5590 * view as current. First, figure out how many there are.
5591 */
5592 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5593 {
5595 nxids = add_size(nxids, 1);
5596 nxids = add_size(nxids, s->nChildXids);
5597 }
5599 <= maxsize);
5600
5601 /* Copy them to our scratch space. */
5602 workspace = palloc(nxids * sizeof(TransactionId));
5603 for (s = CurrentTransactionState; s != NULL; s = s->parent)
5604 {
5606 workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5607 if (s->nChildXids > 0)
5608 memcpy(&workspace[i], s->childXids,
5609 s->nChildXids * sizeof(TransactionId));
5610 i += s->nChildXids;
5611 }
5612 Assert(i == nxids);
5613
5614 /* Sort them. */
5615 qsort(workspace, nxids, sizeof(TransactionId), xidComparator);
5616
5617 /* Copy data into output area. */
5618 result->nParallelCurrentXids = nxids;
5619 memcpy(&result->parallelCurrentXids[0], workspace,
5620 nxids * sizeof(TransactionId));
5621}
int i
Definition: isn.c:77
#define qsort(a, b, c, d)
Definition: port.h:479
FullTransactionId currentFullTransactionId
Definition: xact.c:233
FullTransactionId topFullTransactionId
Definition: xact.c:232
CommandId currentCommandId
Definition: xact.c:234
TransactionId parallelCurrentXids[FLEXIBLE_ARRAY_MEMBER]
Definition: xact.c:236
static TransactionId * ParallelCurrentXids
Definition: xact.c:128
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 860 of file xact.c.

861{
863 xactStartTimestamp = xact_ts;
864 stmtStartTimestamp = stmt_ts;
865}

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

Referenced by ParallelWorkerMain().

◆ ShowTransactionState()

static void ShowTransactionState ( const char *  str)
static

Definition at line 5666 of file xact.c.

5667{
5668 /* skip work if message will definitely not be printed */
5671}
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:5678

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

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

5086{
5088
5089 if (s->state != TRANS_DEFAULT)
5090 elog(WARNING, "StartSubTransaction while in %s state",
5092
5093 s->state = TRANS_START;
5094
5095 /*
5096 * Initialize subsystems for new subtransaction
5097 *
5098 * must initialize resource-management stuff first
5099 */
5103
5105
5106 /*
5107 * Call start-of-subxact callbacks
5108 */
5111
5112 ShowTransactionState("StartSubTransaction");
5113}
void AfterTriggerBeginSubXact(void)
Definition: trigger.c:5387
static void AtSubStart_ResourceOwner(void)
Definition: xact.c:1284
static void AtSubStart_Memory(void)
Definition: xact.c:1255
@ 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 2077 of file xact.c.

2078{
2081
2082 /*
2083 * Let's just make sure the state stack is empty
2084 */
2087
2089
2090 /* check the current transaction state */
2091 Assert(s->state == TRANS_DEFAULT);
2092
2093 /*
2094 * Set the current transaction state information appropriately during
2095 * start processing. Note that once the transaction status is switched
2096 * this process cannot fail until the user ID and the security context
2097 * flags are fetched below.
2098 */
2099 s->state = TRANS_START;
2100 s->fullTransactionId = InvalidFullTransactionId; /* until assigned */
2101
2102 /* Determine if statements are logged in this transaction */
2104 (log_xact_sample_rate == 1 ||
2106
2107 /*
2108 * initialize current transaction state fields
2109 *
2110 * note: prevXactReadOnly is not used at the outermost level
2111 */
2112 s->nestingLevel = 1;
2113 s->gucNestLevel = 1;
2114 s->childXids = NULL;
2115 s->nChildXids = 0;
2116 s->maxChildXids = 0;
2117
2118 /*
2119 * Once the current user ID and the security context flags are fetched,
2120 * both will be properly reset even if transaction startup fails.
2121 */
2123
2124 /* SecurityRestrictionContext should never be set outside a transaction */
2125 Assert(s->prevSecContext == 0);
2126
2127 /*
2128 * Make sure we've reset xact state variables
2129 *
2130 * If recovery is still in progress, mark this transaction as read-only.
2131 * We have lower level defences in XLogInsert and elsewhere to stop us
2132 * from modifying data during recovery, but this gives the normal
2133 * indication to the user that the transaction is read-only.
2134 */
2135 if (RecoveryInProgress())
2136 {
2137 s->startedInRecovery = true;
2138 XactReadOnly = true;
2139 }
2140 else
2141 {
2142 s->startedInRecovery = false;
2144 }
2147 forceSyncCommit = false;
2148 MyXactFlags = 0;
2149
2150 /*
2151 * reinitialize within-transaction counters
2152 */
2156 currentCommandIdUsed = false;
2157
2158 /*
2159 * initialize reported xid accounting
2160 */
2161 nUnreportedXids = 0;
2162 s->didLogXid = false;
2163
2164 /*
2165 * must initialize resource-management stuff first
2166 */
2169
2170 /*
2171 * Assign a new LocalTransactionId, and combine it with the proc number to
2172 * form a virtual transaction id.
2173 */
2174 vxid.procNumber = MyProcNumber;
2176
2177 /*
2178 * Lock the virtual transaction id before we announce it in the proc array
2179 */
2181
2182 /*
2183 * Advertise it in the proc array. We assume assignment of
2184 * localTransactionId is atomic, and the proc number should be set
2185 * already.
2186 */
2189
2190 TRACE_POSTGRESQL_TRANSACTION_START(vxid.localTransactionId);
2191
2192 /*
2193 * set transaction_timestamp() (a/k/a now()). Normally, we want this to
2194 * be the same as the first command's statement_timestamp(), so don't do a
2195 * fresh GetCurrentTimestamp() call (which'd be expensive anyway). But
2196 * for transactions started inside procedures (i.e., nonatomic SPI
2197 * contexts), we do need to advance the timestamp. Also, in a parallel
2198 * worker, the timestamp should already have been provided by a call to
2199 * SetParallelStartTimestamps().
2200 */
2201 if (!IsParallelWorker())
2202 {
2205 else
2207 }
2208 else
2211 /* Mark xactStopTimestamp as unset. */
2213
2214 /*
2215 * initialize other subsystems for new transaction
2216 */
2217 AtStart_GUC();
2218 AtStart_Cache();
2220
2221 /*
2222 * done with start processing, set current transaction state to "in
2223 * progress"
2224 */
2226
2227 /* Schedule transaction timeout */
2228 if (TransactionTimeout > 0)
2230
2231 ShowTransactionState("StartTransaction");
2232}
#define TopSubTransactionId
Definition: c.h:668
#define FirstCommandId
Definition: c.h:677
ProcNumber MyProcNumber
Definition: globals.c:90
void AtStart_GUC(void)
Definition: guc.c:2090
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:1177
bool DefaultXactDeferrable
Definition: xact.c:85
static void AtStart_ResourceOwner(void)
Definition: xact.c:1227
static void AtStart_Cache(void)
Definition: xact.c:1168
int DefaultXactIsoLevel
Definition: xact.c:79
bool xact_is_sampled
Definition: xact.c:297
bool DefaultXactReadOnly
Definition: xact.c:82
bool RecoveryInProgress(void)
Definition: xlog.c:6395

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

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

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(), copy_sequences(), DefineIndex(), DisableSubscriptionAndExit(), do_autovacuum(), EventTriggerOnLogin(), exec_replication_command(), FetchRelationStates(), FinishSyncWorker(), get_database_list(), get_subscription_list(), IdentifySystem(), index_drop(), initialize_worker_spi(), InitializeLogRepWorker(), InitPostgres(), LogicalRepSyncSequences(), LogicalRepSyncTableStart(), maybe_reread_subscription(), movedb(), pa_start_subtrans(), ParallelApplyWorkerMain(), ParallelWorkerMain(), perform_work_item(), ProcessCatchupInterrupt(), ProcessIncomingNotify(), ProcessSyncingTablesForApply(), ProcessSyncingTablesForSync(), 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 806 of file xact.c.

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

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

◆ TransactionBlockStatusCode()

char TransactionBlockStatusCode ( void  )

Definition at line 5021 of file xact.c.

5022{
5024
5025 switch (s->blockState)
5026 {
5027 case TBLOCK_DEFAULT:
5028 case TBLOCK_STARTED:
5029 return 'I'; /* idle --- not in transaction */
5030 case TBLOCK_BEGIN:
5031 case TBLOCK_SUBBEGIN:
5032 case TBLOCK_INPROGRESS:
5036 case TBLOCK_END:
5037 case TBLOCK_SUBRELEASE:
5038 case TBLOCK_SUBCOMMIT:
5039 case TBLOCK_PREPARE:
5040 return 'T'; /* in transaction */
5041 case TBLOCK_ABORT:
5042 case TBLOCK_SUBABORT:
5043 case TBLOCK_ABORT_END:
5047 case TBLOCK_SUBRESTART:
5049 return 'E'; /* in failed transaction */
5050 }
5051
5052 /* should never get here */
5053 elog(FATAL, "invalid transaction block state: %s",
5055 return 0; /* keep compiler quiet */
5056}

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

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

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

1044{
1046}

References CurrentTransactionState, and TransactionStateData::startedInRecovery.

Referenced by RelationGetIndexScan().

◆ TransStateAsString()

static const char * TransStateAsString ( TransState  state)
static

Definition at line 5778 of file xact.c.

5779{
5780 switch (state)
5781 {
5782 case TRANS_DEFAULT:
5783 return "DEFAULT";
5784 case TRANS_START:
5785 return "START";
5786 case TRANS_INPROGRESS:
5787 return "INPROGRESS";
5788 case TRANS_COMMIT:
5789 return "COMMIT";
5790 case TRANS_ABORT:
5791 return "ABORT";
5792 case TRANS_PREPARE:
5793 return "PREPARE";
5794 }
5795 return "UNRECOGNIZED";
5796}
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 3895 of file xact.c.

3896{
3897 SubXactCallbackItem *item;
3898 SubXactCallbackItem *prev;
3899
3900 prev = NULL;
3901 for (item = SubXact_callbacks; item; prev = item, item = item->next)
3902 {
3903 if (item->callback == callback && item->arg == arg)
3904 {
3905 if (prev)
3906 prev->next = item->next;
3907 else
3908 SubXact_callbacks = item->next;
3909 pfree(item);
3910 break;
3911 }
3912 }
3913}

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

◆ UnregisterXactCallback()

void UnregisterXactCallback ( XactCallback  callback,
void *  arg 
)

Definition at line 3835 of file xact.c.

3836{
3837 XactCallbackItem *item;
3838 XactCallbackItem *prev;
3839
3840 prev = NULL;
3841 for (item = Xact_callbacks; item; prev = item, item = item->next)
3842 {
3843 if (item->callback == callback && item->arg == arg)
3844 {
3845 if (prev)
3846 prev->next = item->next;
3847 else
3848 Xact_callbacks = item->next;
3849 pfree(item);
3850 break;
3851 }
3852 }
3853}

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

◆ UserAbortTransactionBlock()

void UserAbortTransactionBlock ( bool  chain)

Definition at line 4222 of file xact.c.

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

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

3729{
3730 CheckTransactionBlock(isTopLevel, false, stmtType);
3731}

References CheckTransactionBlock().

Referenced by ExecSetVariableStmt(), and standard_ProcessUtility().

◆ xact_redo()

void xact_redo ( XLogReaderState record)

Definition at line 6381 of file xact.c.

6382{
6383 uint8 info = XLogRecGetInfo(record) & XLOG_XACT_OPMASK;
6384
6385 /* Backup blocks are not used in xact records */
6387
6388 if (info == XLOG_XACT_COMMIT)
6389 {
6390 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6391 xl_xact_parsed_commit parsed;
6392
6393 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6394 xact_redo_commit(&parsed, XLogRecGetXid(record),
6395 record->EndRecPtr, XLogRecGetOrigin(record));
6396 }
6397 else if (info == XLOG_XACT_COMMIT_PREPARED)
6398 {
6399 xl_xact_commit *xlrec = (xl_xact_commit *) XLogRecGetData(record);
6400 xl_xact_parsed_commit parsed;
6401
6402 ParseCommitRecord(XLogRecGetInfo(record), xlrec, &parsed);
6403 xact_redo_commit(&parsed, parsed.twophase_xid,
6404 record->EndRecPtr, XLogRecGetOrigin(record));
6405
6406 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6407 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6408 PrepareRedoRemove(parsed.twophase_xid, false);
6409 LWLockRelease(TwoPhaseStateLock);
6410 }
6411 else if (info == XLOG_XACT_ABORT)
6412 {
6413 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6414 xl_xact_parsed_abort parsed;
6415
6416 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6417 xact_redo_abort(&parsed, XLogRecGetXid(record),
6418 record->EndRecPtr, XLogRecGetOrigin(record));
6419 }
6420 else if (info == XLOG_XACT_ABORT_PREPARED)
6421 {
6422 xl_xact_abort *xlrec = (xl_xact_abort *) XLogRecGetData(record);
6423 xl_xact_parsed_abort parsed;
6424
6425 ParseAbortRecord(XLogRecGetInfo(record), xlrec, &parsed);
6426 xact_redo_abort(&parsed, parsed.twophase_xid,
6427 record->EndRecPtr, XLogRecGetOrigin(record));
6428
6429 /* Delete TwoPhaseState gxact entry and/or 2PC file. */
6430 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6431 PrepareRedoRemove(parsed.twophase_xid, false);
6432 LWLockRelease(TwoPhaseStateLock);
6433 }
6434 else if (info == XLOG_XACT_PREPARE)
6435 {
6436 /*
6437 * Store xid and start/end pointers of the WAL record in TwoPhaseState
6438 * gxact entry.
6439 */
6440 LWLockAcquire(TwoPhaseStateLock, LW_EXCLUSIVE);
6442 XLogRecGetData(record),
6443 record->ReadRecPtr,
6444 record->EndRecPtr,
6445 XLogRecGetOrigin(record));
6446 LWLockRelease(TwoPhaseStateLock);
6447 }
6448 else if (info == XLOG_XACT_ASSIGNMENT)
6449 {
6451
6454 xlrec->nsubxacts, xlrec->xsub);
6455 }
6456 else if (info == XLOG_XACT_INVALIDATIONS)
6457 {
6458 /*
6459 * XXX we do ignore this for now, what matters are invalidations
6460 * written into the commit record.
6461 */
6462 }
6463 else
6464 elog(PANIC, "xact_redo: unknown op code %u", info);
6465}
uint8_t uint8
Definition: c.h:540
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:206
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:205
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:6148
static void xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid, XLogRecPtr lsn, RepOriginId origin_id)
Definition: xact.c:6302
#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:412
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:409
#define XLogRecGetData(decoder)
Definition: xlogreader.h:414
#define XLogRecGetXid(decoder)
Definition: xlogreader.h:411
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:416
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 6302 of file xact.c.

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

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

5809{
5811
5812 if (s->nChildXids == 0)
5813 *ptr = NULL;
5814 else
5815 *ptr = s->childXids;
5816
5817 return s->nChildXids;
5818}

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

6010{
6011 xl_xact_abort xlrec;
6012 xl_xact_xinfo xl_xinfo;
6013 xl_xact_subxacts xl_subxacts;
6014 xl_xact_relfilelocators xl_relfilelocators;
6015 xl_xact_stats_items xl_dropped_stats;
6016 xl_xact_twophase xl_twophase;
6017 xl_xact_dbinfo xl_dbinfo;
6018 xl_xact_origin xl_origin;
6019
6020 uint8 info;
6021
6023
6024 xl_xinfo.xinfo = 0;
6025
6026 /* decide between a plain and 2pc abort */
6027 if (!TransactionIdIsValid(twophase_xid))
6028 info = XLOG_XACT_ABORT;
6029 else
6031
6032
6033 /* First figure out and collect all the information needed */
6034
6035 xlrec.xact_time = abort_time;
6036
6038 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
6039
6040 if (nsubxacts > 0)
6041 {
6042 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
6043 xl_subxacts.nsubxacts = nsubxacts;
6044 }
6045
6046 if (nrels > 0)
6047 {
6049 xl_relfilelocators.nrels = nrels;
6050 info |= XLR_SPECIAL_REL_UPDATE;
6051 }
6052
6053 if (ndroppedstats > 0)
6054 {
6056 xl_dropped_stats.nitems = ndroppedstats;
6057 }
6058
6059 if (TransactionIdIsValid(twophase_xid))
6060 {
6061 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
6062 xl_twophase.xid = twophase_xid;
6063 Assert(twophase_gid != NULL);
6064
6066 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
6067 }
6068
6069 if (TransactionIdIsValid(twophase_xid) && XLogLogicalInfoActive())
6070 {
6071 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
6072 xl_dbinfo.dbId = MyDatabaseId;
6073 xl_dbinfo.tsId = MyDatabaseTableSpace;
6074 }
6075
6076 /*
6077 * Dump transaction origin information. We need this during recovery to
6078 * update the replication origin progress.
6079 */
6081 {
6082 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
6083
6086 }
6087
6088 if (xl_xinfo.xinfo != 0)
6089 info |= XLOG_XACT_HAS_INFO;
6090
6091 /* Then include all the collected data into the abort record. */
6092
6094
6096
6097 if (xl_xinfo.xinfo != 0)
6098 XLogRegisterData(&xl_xinfo, sizeof(xl_xinfo));
6099
6100 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
6101 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
6102
6103 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
6104 {
6105 XLogRegisterData(&xl_subxacts,
6107 XLogRegisterData(subxacts,
6108 nsubxacts * sizeof(TransactionId));
6109 }
6110
6112 {
6113 XLogRegisterData(&xl_relfilelocators,
6115 XLogRegisterData(rels,
6116 nrels * sizeof(RelFileLocator));
6117 }
6118
6119 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
6120 {
6121 XLogRegisterData(&xl_dropped_stats,
6123 XLogRegisterData(droppedstats,
6124 ndroppedstats * sizeof(xl_xact_stats_item));
6125 }
6126
6127 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
6128 {
6129 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
6130 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
6131 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
6132 }
6133
6134 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
6135 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
6136
6137 /* Include the replication origin */
6139
6140 return XLogInsert(RM_XACT_ID, info);
6141}
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:460
#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 5832 of file xact.c.

5840{
5841 xl_xact_commit xlrec;
5842 xl_xact_xinfo xl_xinfo;
5843 xl_xact_dbinfo xl_dbinfo;
5844 xl_xact_subxacts xl_subxacts;
5845 xl_xact_relfilelocators xl_relfilelocators;
5846 xl_xact_stats_items xl_dropped_stats;
5847 xl_xact_invals xl_invals;
5848 xl_xact_twophase xl_twophase;
5849 xl_xact_origin xl_origin;
5850 uint8 info;
5851
5853
5854 xl_xinfo.xinfo = 0;
5855
5856 /* decide between a plain and 2pc commit */
5857 if (!TransactionIdIsValid(twophase_xid))
5858 info = XLOG_XACT_COMMIT;
5859 else
5861
5862 /* First figure out and collect all the information needed */
5863
5864 xlrec.xact_time = commit_time;
5865
5866 if (relcacheInval)
5868 if (forceSyncCommit)
5871 xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS;
5872
5873 /*
5874 * Check if the caller would like to ask standbys for immediate feedback
5875 * once this commit is applied.
5876 */
5879
5880 /*
5881 * Relcache invalidations requires information about the current database
5882 * and so does logical decoding.
5883 */
5884 if (nmsgs > 0 || XLogLogicalInfoActive())
5885 {
5886 xl_xinfo.xinfo |= XACT_XINFO_HAS_DBINFO;
5887 xl_dbinfo.dbId = MyDatabaseId;
5888 xl_dbinfo.tsId = MyDatabaseTableSpace;
5889 }
5890
5891 if (nsubxacts > 0)
5892 {
5893 xl_xinfo.xinfo |= XACT_XINFO_HAS_SUBXACTS;
5894 xl_subxacts.nsubxacts = nsubxacts;
5895 }
5896
5897 if (nrels > 0)
5898 {
5900 xl_relfilelocators.nrels = nrels;
5901 info |= XLR_SPECIAL_REL_UPDATE;
5902 }
5903
5904 if (ndroppedstats > 0)
5905 {
5907 xl_dropped_stats.nitems = ndroppedstats;
5908 }
5909
5910 if (nmsgs > 0)
5911 {
5912 xl_xinfo.xinfo |= XACT_XINFO_HAS_INVALS;
5913 xl_invals.nmsgs = nmsgs;
5914 }
5915
5916 if (TransactionIdIsValid(twophase_xid))
5917 {
5918 xl_xinfo.xinfo |= XACT_XINFO_HAS_TWOPHASE;
5919 xl_twophase.xid = twophase_xid;
5920 Assert(twophase_gid != NULL);
5921
5923 xl_xinfo.xinfo |= XACT_XINFO_HAS_GID;
5924 }
5925
5926 /* dump transaction origin information */
5928 {
5929 xl_xinfo.xinfo |= XACT_XINFO_HAS_ORIGIN;
5930
5933 }
5934
5935 if (xl_xinfo.xinfo != 0)
5936 info |= XLOG_XACT_HAS_INFO;
5937
5938 /* Then include all the collected data into the commit record. */
5939
5941
5942 XLogRegisterData(&xlrec, sizeof(xl_xact_commit));
5943
5944 if (xl_xinfo.xinfo != 0)
5945 XLogRegisterData(&xl_xinfo.xinfo, sizeof(xl_xinfo.xinfo));
5946
5947 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DBINFO)
5948 XLogRegisterData(&xl_dbinfo, sizeof(xl_dbinfo));
5949
5950 if (xl_xinfo.xinfo & XACT_XINFO_HAS_SUBXACTS)
5951 {
5952 XLogRegisterData(&xl_subxacts,
5954 XLogRegisterData(subxacts,
5955 nsubxacts * sizeof(TransactionId));
5956 }
5957
5959 {
5960 XLogRegisterData(&xl_relfilelocators,
5962 XLogRegisterData(rels,
5963 nrels * sizeof(RelFileLocator));
5964 }
5965
5966 if (xl_xinfo.xinfo & XACT_XINFO_HAS_DROPPED_STATS)
5967 {
5968 XLogRegisterData(&xl_dropped_stats,
5970 XLogRegisterData(droppedstats,
5971 ndroppedstats * sizeof(xl_xact_stats_item));
5972 }
5973
5974 if (xl_xinfo.xinfo & XACT_XINFO_HAS_INVALS)
5975 {
5977 XLogRegisterData(msgs,
5978 nmsgs * sizeof(SharedInvalidationMessage));
5979 }
5980
5981 if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE)
5982 {
5983 XLogRegisterData(&xl_twophase, sizeof(xl_xact_twophase));
5984 if (xl_xinfo.xinfo & XACT_XINFO_HAS_GID)
5985 XLogRegisterData(twophase_gid, strlen(twophase_gid) + 1);
5986 }
5987
5988 if (xl_xinfo.xinfo & XACT_XINFO_HAS_ORIGIN)
5989 XLogRegisterData(&xl_origin, sizeof(xl_xact_origin));
5990
5991 /* we allow filtering by xacts */
5993
5994 return XLogInsert(RM_XACT_ID, info);
5995}
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 267 of file xact.c.

Referenced by PushTransaction(), and StartTransaction().

◆ CurrentTransactionState

TransactionState CurrentTransactionState = &TopTransactionStateData
static

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

Referenced by StartTransaction().

◆ DefaultXactIsoLevel

int DefaultXactIsoLevel = XACT_READ_COMMITTED

Definition at line 79 of file xact.c.

Referenced by StartTransaction().

◆ DefaultXactReadOnly

bool DefaultXactReadOnly = false

Definition at line 82 of file xact.c.

Referenced by StartTransaction().

◆ forceSyncCommit

bool forceSyncCommit = false
static

◆ MyXactFlags

◆ nParallelCurrentXids

◆ nUnreportedXids

int nUnreportedXids
static

Definition at line 258 of file xact.c.

Referenced by AssignTransactionId(), and StartTransaction().

◆ ParallelCurrentXids

TransactionId* ParallelCurrentXids
static

◆ prepareGID

char* prepareGID
static

Definition at line 289 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 88 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 248 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 259 of file xact.c.

Referenced by AssignTransactionId().

◆ Xact_callbacks

XactCallbackItem* Xact_callbacks = NULL
static

Definition at line 316 of file xact.c.

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

◆ xact_is_sampled

bool xact_is_sampled = false

Definition at line 297 of file xact.c.

Referenced by check_log_duration(), and StartTransaction().

◆ XactDeferrable

◆ XactIsoLevel

◆ XactReadOnly

◆ xactStartTimestamp

TimestampTz xactStartTimestamp
static

◆ xactStopTimestamp

TimestampTz xactStopTimestamp
static

◆ XactTopFullTransactionId